Skip to content

Commit

Permalink
Claim DLC channel settle transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
luckysori committed Mar 12, 2024
1 parent cb012ad commit 8e4c49b
Show file tree
Hide file tree
Showing 6 changed files with 359 additions and 56 deletions.
3 changes: 2 additions & 1 deletion dlc-manager/src/channel/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ impl_dlc_writeable_enum!(
(8, RenewConfirmed, {(contract_id, writeable), (offer_per_update_point, writeable), (accept_per_update_point, writeable), (buffer_transaction, writeable), (buffer_script_pubkey, writeable), (offer_buffer_adaptor_signature, {cb_writeable, write_ecdsa_adaptor_signature, read_ecdsa_adaptor_signature}), (timeout, writeable), (own_payout, writeable), (total_collateral, writeable)}),
(10, RenewFinalized, {(contract_id, writeable), (prev_offer_per_update_point, writeable), (buffer_transaction, writeable), (buffer_script_pubkey, writeable), (offer_buffer_adaptor_signature, {cb_writeable, write_ecdsa_adaptor_signature, read_ecdsa_adaptor_signature}), (accept_buffer_adaptor_signature, {cb_writeable, write_ecdsa_adaptor_signature, read_ecdsa_adaptor_signature}), (timeout, writeable), (own_payout, writeable), (total_collateral, writeable)}),
(9, Closing, {(buffer_transaction, writeable), (contract_id, writeable), (is_initiator, writeable)}),
(11, CollaborativeCloseOffered, { (counter_payout, writeable), (offer_signature, writeable), (close_tx, writeable), (timeout, writeable), (is_offer, writeable) })
(11, CollaborativeCloseOffered, { (counter_payout, writeable), (offer_signature, writeable), (close_tx, writeable), (timeout, writeable), (is_offer, writeable) }),
(12, SettledClosing, {(settle_transaction, writeable), (contract_id, writeable), (is_initiator, writeable)})
;;
);

Expand Down
12 changes: 12 additions & 0 deletions dlc-manager/src/channel/signed_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,18 @@ typed_enum!(
/// Whether the local party initiated the closing of the channel.
is_initiator: bool,
},
/// A [`SignedChannel`] is in `SettledClosing` state when the local party
/// has broadcast a settle transaction and is waiting to finalize the
/// closing of a the channel by claiming one of its outputs.
SettledClosing {
/// The settle transaction that was broadcast.
settle_transaction: Transaction,
/// The [`crate::ContractId`] of the contract that was used to close
/// the channel.
contract_id: ContractId,
/// Whether the local party initiated the closing of the channel.
is_initiator: bool,
},
/// A [`SignedChannel`] is in `CollaborativeCloseOffered` state when the local party
/// has sent a [`dlc_messages::channel::CollaborativeCloseOffer`] message.
CollaborativeCloseOffered {
Expand Down
146 changes: 114 additions & 32 deletions dlc-manager/src/channel_updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use crate::{chain_monitor::{ChainMonitor, ChannelInfo, TxType}, channel::{
}, contract_updater::{
accept_contract_internal, verify_accepted_and_sign_contract_internal,
verify_signed_contract_internal,
}, error::Error, subchannel::{ClosingSubChannel, SubChannel}, Blockchain, ContractId, DlcChannelId, Signer, Time, Wallet, ReferenceId};
use bitcoin::{OutPoint, Script, Sequence, Transaction};
}, error::Error, subchannel::{ClosingSubChannel, SubChannel}, Blockchain, ContractId, DlcChannelId, Signer, Time, Wallet, ReferenceId, manager::CET_NSEQUENCE};
use bitcoin::{OutPoint, Script, Sequence, Transaction, Address};
use dlc::{
channel::{get_tx_adaptor_signature, verify_tx_adaptor_signature, DlcChannelTransactions}, util::dlc_channel_extra_fee, PartyParams
};
Expand Down Expand Up @@ -2712,26 +2712,14 @@ where
Ok((cet, channel))
}

/// Sign the settlement transaction and update the state of the channel.
pub fn close_settled_channel<S: Deref>(
pub(crate) fn initiate_unilateral_close_settled_channel<S: Deref>(
secp: &Secp256k1<All>,
signed_channel: &mut SignedChannel,
signer: &S,
is_initiator: bool,
) -> Result<(Transaction, Channel), Error>
where
S::Target: Signer,
{
close_settled_channel_internal(secp, signed_channel, signer, None, is_initiator)
}

pub(crate) fn close_settled_channel_internal<S: Deref>(
secp: &Secp256k1<All>,
signed_channel: &SignedChannel,
signer: &S,
sub_channel: Option<(SubChannel, &ClosingSubChannel)>,
is_initiator: bool,
) -> Result<(Transaction, Channel), Error>
reference_id: Option<ReferenceId>
) -> Result<(), Error>
where
S::Target: Signer,
{
Expand Down Expand Up @@ -2832,24 +2820,118 @@ where
)?;
}

let contract_id = signed_channel.get_contract_id().ok_or_else(|| {
Error::InvalidState(
"Expected to be in a state with an associated contract id but was not.".to_string(),
)
})?;

signed_channel.state = SignedChannelState::SettledClosing {
settle_transaction: settle_tx,
contract_id,
is_initiator,
};

signed_channel.reference_id = reference_id;

Ok(())
}

/// Spend the settle transaction output owned by us.
pub fn finalize_unilateral_close_settled_channel<S: Deref>(
secp: &Secp256k1<All>,
signed_channel: &SignedChannel,
confirmed_contract: &SignedContract,
destination_address: &Address,
fee_rate_per_vb: u64,
signer: &S,
is_initiator: bool,
) -> Result<(Transaction, Channel), Error>
where
S::Target: Signer,
{
let settle_transaction =
get_signed_channel_state!(signed_channel, SettledClosing, settle_transaction)?;

let is_offer = confirmed_contract
.accepted_contract
.offered_contract
.is_offer_party;



let (offer_points, accept_points, offer_per_update_point, accept_per_update_point) = if is_offer
{
(
&signed_channel.own_points,
&signed_channel.counter_points,
&signed_channel.own_per_update_point,
&signed_channel.counter_per_update_point,
)
} else {
(
&signed_channel.counter_points,
&signed_channel.own_points,
&signed_channel.counter_per_update_point,
&signed_channel.own_per_update_point,
)
};

let offer_revoke_params = offer_points.get_revokable_params(
secp,
&accept_points.revocation_basepoint,
offer_per_update_point,
);

let accept_revoke_params = accept_points.get_revokable_params(
secp,
&offer_points.revocation_basepoint,
accept_per_update_point,
);

let (own_per_update_point, own_basepoint) = if is_offer {
(
&offer_per_update_point,
&offer_points.own_basepoint,
)
} else {
(
&accept_per_update_point,
&accept_points.own_basepoint,
)
};

let base_secret = signer.get_secret_key_for_pubkey(own_basepoint)?;
let own_sk = derive_private_key(secp, own_per_update_point, &base_secret);

let claim_tx = dlc::channel::create_and_sign_claim_settle_transaction(
secp,
&offer_revoke_params,
&accept_revoke_params,
&own_sk,
settle_transaction,
destination_address,
CET_NSEQUENCE,
0,
fee_rate_per_vb,
is_offer,
)?;

let closed_channel = ClosedChannel {
counter_party: signed_channel.counter_party,
temporary_channel_id: signed_channel.temporary_channel_id,
channel_id: signed_channel.channel_id,
reference_id: signed_channel.reference_id,
closing_txid: claim_tx.txid()
};

let channel = if is_initiator {
Channel::Closed(ClosedChannel {
counter_party: signed_channel.counter_party,
temporary_channel_id: signed_channel.temporary_channel_id,
channel_id: signed_channel.channel_id,
reference_id: signed_channel.reference_id,
closing_txid: settle_tx.txid()
})
Channel::Closed(closed_channel)
} else {
Channel::CounterClosed(ClosedChannel {
counter_party: signed_channel.counter_party,
temporary_channel_id: signed_channel.temporary_channel_id,
channel_id: signed_channel.channel_id,
reference_id: signed_channel.reference_id,
closing_txid: settle_tx.txid()
})
Channel::CounterClosed(closed_channel)
};
Ok((settle_tx, channel))

Ok((claim_tx, channel))
}

/// Returns the current time as unix time (in seconds)
Expand Down
Loading

0 comments on commit 8e4c49b

Please sign in to comment.