Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle fallible per commitment point in channel establishment #3109

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f49df83
Async signing test util follow ups
alecchendev Jun 18, 2024
cbb4a9e
Move clearing signer funding signed flag to signer_unblocked
alecchendev Jun 10, 2024
3f840f2
Move clearing signer commitment flag to signer_unblocked
alecchendev Jun 10, 2024
df10ff4
Clear signer pending funding created flag
alecchendev Jun 10, 2024
3e1cae5
Add logger as parameter in creating ChannelContext
alecchendev May 30, 2024
cb9ba76
Add HolderCommitmentPoint::Uninitialized
alecchendev Jun 9, 2024
6013f0d
f - improve holder commitment docs
alecchendev Jun 18, 2024
3d2f215
f - fix debug assertion
alecchendev Jun 18, 2024
0c130d9
Split HolderCommitmentPoint::advance off into separate function
alecchendev Jun 18, 2024
4494d96
Return an error if we fail to advance our commitment number
alecchendev Jun 18, 2024
3c82bb5
Change get_per_commitment_point to return result type
alecchendev Jun 5, 2024
a4eb312
Handle fallible commitment point when getting open_channel message
alecchendev Jun 6, 2024
1a76f82
Handle sending open_channel when signer is unblocked
alecchendev Jun 6, 2024
41e4139
f - try_resolve_pending
alecchendev Jun 18, 2024
1e9a36f
Handle fallible commitment point when getting accept_channel
alecchendev Jun 6, 2024
84f4ff3
Handle sending accept_channel when signer is unblocked
alecchendev Jun 6, 2024
02b9f00
f - try_resolve_pending
alecchendev Jun 18, 2024
7bf5c62
Handle fallible commitment point when getting channel_ready
alecchendev Jun 6, 2024
ccbe92d
Handle sending channel_ready when commitment point is unblocked
alecchendev Jun 10, 2024
db9f2e6
f - try_resolve_pending
alecchendev Jun 18, 2024
68f1d8a
Add test for async open and accept channel
alecchendev Jun 11, 2024
b798ffa
f - test unblocking signer ops in different orders for various tests
alecchendev Jun 18, 2024
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
70 changes: 39 additions & 31 deletions lightning/src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -944,7 +944,9 @@ pub(crate) struct ShutdownResult {
/// commitment points from our signer.
#[derive(Debug, Copy, Clone)]
enum HolderCommitmentPoint {
// TODO: add a variant for before our first commitment point is retrieved
/// We have just created or accepted a channel and are pending our very
/// first commitment point.
Uninitialized { transaction_number: u64 },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we were going to first handle all the async cases post-funding and then add support for handling the async case during initial channel bring up in a separate PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry for the delay, yea you're right, i just forgot! will be back to prioritizing this next week

/// We've advanced our commitment number and are waiting on the next commitment point.
/// Until the `get_per_commitment_point` signer method becomes async, this variant
/// will not be used.
Expand All @@ -954,15 +956,9 @@ enum HolderCommitmentPoint {
Available { transaction_number: u64, current: PublicKey, next: PublicKey },
}

impl HolderCommitmentPoint {
pub fn new<SP: Deref>(signer: &ChannelSignerType<SP>, secp_ctx: &Secp256k1<secp256k1::All>) -> Self
where SP::Target: SignerProvider
{
HolderCommitmentPoint::Available {
transaction_number: INITIAL_COMMITMENT_NUMBER,
current: signer.as_ref().get_per_commitment_point(INITIAL_COMMITMENT_NUMBER, secp_ctx),
next: signer.as_ref().get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, secp_ctx),
}
impl HolderCommitmentPoint where {
pub fn new() -> Self {
HolderCommitmentPoint::Uninitialized { transaction_number: INITIAL_COMMITMENT_NUMBER }
}

pub fn is_available(&self) -> bool {
Expand All @@ -971,20 +967,23 @@ impl HolderCommitmentPoint {

pub fn transaction_number(&self) -> u64 {
match self {
HolderCommitmentPoint::Uninitialized { transaction_number } => *transaction_number,
HolderCommitmentPoint::PendingNext { transaction_number, .. } => *transaction_number,
HolderCommitmentPoint::Available { transaction_number, .. } => *transaction_number,
}
}

pub fn current_point(&self) -> PublicKey {
pub fn current_point(&self) -> Option<PublicKey> {
match self {
HolderCommitmentPoint::PendingNext { current, .. } => *current,
HolderCommitmentPoint::Available { current, .. } => *current,
HolderCommitmentPoint::Uninitialized { .. } => None,
HolderCommitmentPoint::PendingNext { current, .. } => Some(*current),
HolderCommitmentPoint::Available { current, .. } => Some(*current),
}
}

pub fn next_point(&self) -> Option<PublicKey> {
match self {
HolderCommitmentPoint::Uninitialized { .. } => None,
HolderCommitmentPoint::PendingNext { .. } => None,
HolderCommitmentPoint::Available { next, .. } => Some(*next),
}
Expand All @@ -993,6 +992,13 @@ impl HolderCommitmentPoint {
pub fn advance<SP: Deref, L: Deref>(&mut self, signer: &ChannelSignerType<SP>, secp_ctx: &Secp256k1<secp256k1::All>, logger: &L)
where SP::Target: SignerProvider, L::Target: Logger
{
if let HolderCommitmentPoint::Uninitialized { transaction_number } = self {
let current = signer.as_ref().get_per_commitment_point(*transaction_number, secp_ctx); // TODO
log_trace!(logger, "Retrieved current per-commitment point {}", transaction_number);
*self = HolderCommitmentPoint::PendingNext { transaction_number: *transaction_number, current };
// TODO: handle error case when get_per_commitment_point becomes async
}

if let HolderCommitmentPoint::Available { transaction_number, next, .. } = self {
*self = HolderCommitmentPoint::PendingNext {
transaction_number: *transaction_number - 1,
Expand All @@ -1001,9 +1007,10 @@ impl HolderCommitmentPoint {
}

if let HolderCommitmentPoint::PendingNext { transaction_number, current } = self {
let next = signer.as_ref().get_per_commitment_point(*transaction_number - 1, secp_ctx);
alecchendev marked this conversation as resolved.
Show resolved Hide resolved
let next = signer.as_ref().get_per_commitment_point(*transaction_number - 1, secp_ctx); // TODO
log_trace!(logger, "Retrieved next per-commitment point {}", *transaction_number - 1);
*self = HolderCommitmentPoint::Available { transaction_number: *transaction_number, current: *current, next };
// TODO: handle error case when get_per_commitment_point becomes async
}
}
}
Expand Down Expand Up @@ -1629,7 +1636,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
let value_to_self_msat = our_funding_satoshis * 1000 + msg_push_msat;

let holder_signer = ChannelSignerType::Ecdsa(holder_signer);
let holder_commitment_point = HolderCommitmentPoint::new(&holder_signer, &secp_ctx);
let mut holder_commitment_point = HolderCommitmentPoint::new();
holder_commitment_point.advance(&holder_signer, &secp_ctx, &&logger);

// TODO(dual_funding): Checks for `funding_feerate_sat_per_1000_weight`?

Expand Down Expand Up @@ -1858,7 +1866,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
let temporary_channel_id = temporary_channel_id.unwrap_or_else(|| ChannelId::temporary_from_entropy_source(entropy_source));

let holder_signer = ChannelSignerType::Ecdsa(holder_signer);
let holder_commitment_point = HolderCommitmentPoint::new(&holder_signer, &secp_ctx);
let mut holder_commitment_point = HolderCommitmentPoint::new();
holder_commitment_point.advance(&holder_signer, &secp_ctx, logger);

Ok(Self {
user_id,
Expand Down Expand Up @@ -2719,7 +2728,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
/// The result is a transaction which we can revoke broadcastership of (ie a "local" transaction)
/// TODO Some magic rust shit to compile-time check this?
fn build_holder_transaction_keys(&self) -> TxCreationKeys {
let per_commitment_point = self.holder_commitment_point.current_point();
let per_commitment_point = self.holder_commitment_point.current_point()
.expect("Should not build commitment transaction before retrieving first commitment point");
let delayed_payment_base = &self.get_holder_pubkeys().delayed_payment_basepoint;
let htlc_basepoint = &self.get_holder_pubkeys().htlc_basepoint;
let counterparty_pubkeys = self.get_counterparty_pubkeys();
Expand Down Expand Up @@ -5405,7 +5415,8 @@ impl<SP: Deref> Channel<SP> where
debug_assert!(self.context.holder_commitment_point.transaction_number() <= INITIAL_COMMITMENT_NUMBER + 2);
// TODO: handle non-available case when get_per_commitment_point becomes async
debug_assert!(self.context.holder_commitment_point.is_available());
let next_per_commitment_point = self.context.holder_commitment_point.current_point();
let next_per_commitment_point = self.context.holder_commitment_point.current_point()
.expect("TODO");
let per_commitment_secret = self.context.holder_signer.as_ref().release_commitment_secret(self.context.holder_commitment_point.transaction_number() + 2);
msgs::RevokeAndACK {
channel_id: self.context.channel_id,
Expand Down Expand Up @@ -6539,7 +6550,8 @@ impl<SP: Deref> Channel<SP> where
debug_assert!(self.context.holder_commitment_point.is_available());
msgs::ChannelReady {
channel_id: self.context.channel_id(),
next_per_commitment_point: self.context.holder_commitment_point.current_point(),
next_per_commitment_point: self.context.holder_commitment_point.current_point()
.expect("TODO"),
short_channel_id_alias: Some(self.context.outbound_scid_alias),
}
}
Expand Down Expand Up @@ -7602,7 +7614,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
}

debug_assert!(self.context.holder_commitment_point.is_available());
let first_per_commitment_point = self.context.holder_commitment_point.current_point();
let first_per_commitment_point = self.context.holder_commitment_point.current_point().expect("TODO");
let keys = self.context.get_holder_pubkeys();

msgs::OpenChannel {
Expand Down Expand Up @@ -7879,7 +7891,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
/// [`msgs::AcceptChannel`]: crate::ln::msgs::AcceptChannel
fn generate_accept_channel_message(&self) -> msgs::AcceptChannel {
debug_assert!(self.context.holder_commitment_point.is_available());
let first_per_commitment_point = self.context.holder_commitment_point.current_point();
let first_per_commitment_point = self.context.holder_commitment_point.current_point().expect("TODO");
let keys = self.context.get_holder_pubkeys();

msgs::AcceptChannel {
Expand Down Expand Up @@ -8724,8 +8736,7 @@ impl<SP: Deref> Writeable for Channel<SP> where SP::Target: SignerProvider {
monitor_pending_update_adds = Some(&self.context.monitor_pending_update_adds);
}

// `current_point` will become optional when async signing is implemented.
let cur_holder_commitment_point = Some(self.context.holder_commitment_point.current_point());
let cur_holder_commitment_point = self.context.holder_commitment_point.current_point();
let next_holder_commitment_point = self.context.holder_commitment_point.next_point();

write_tlv_fields!(writer, {
Expand Down Expand Up @@ -9229,15 +9240,12 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
(Some(current), Some(next)) => HolderCommitmentPoint::Available {
transaction_number: cur_holder_commitment_transaction_number, current, next
},
(Some(current), _) => HolderCommitmentPoint::Available {
transaction_number: cur_holder_commitment_transaction_number, current,
next: holder_signer.get_per_commitment_point(cur_holder_commitment_transaction_number - 1, &secp_ctx),
},
(_, _) => HolderCommitmentPoint::Available {
transaction_number: cur_holder_commitment_transaction_number,
current: holder_signer.get_per_commitment_point(cur_holder_commitment_transaction_number, &secp_ctx),
next: holder_signer.get_per_commitment_point(cur_holder_commitment_transaction_number - 1, &secp_ctx),
(Some(current), _) => HolderCommitmentPoint::PendingNext {
transaction_number: cur_holder_commitment_transaction_number, current
},
(_, _) => HolderCommitmentPoint::Uninitialized {
transaction_number: cur_holder_commitment_transaction_number
}
};

Ok(Channel {
Expand Down