From 23090931e32120dcb7397d850587cfde70b61a99 Mon Sep 17 00:00:00 2001 From: Lucas Soriano del Pino Date: Wed, 13 Mar 2024 01:47:18 +0100 Subject: [PATCH] fixup! Claim DLC channel settle transactions --- dlc-manager/src/chain_monitor.rs | 43 ++++++ dlc-manager/src/channel/mod.rs | 30 ++++ dlc-manager/src/channel/ser.rs | 14 +- dlc-manager/src/channel/signed_channel.rs | 11 +- dlc-manager/src/channel_updater.rs | 83 +++-------- dlc-manager/src/lib.rs | 4 +- dlc-manager/src/manager.rs | 170 +++++++++++++++------- dlc-sled-storage-provider/src/lib.rs | 17 ++- dlc/src/channel/mod.rs | 12 +- mocks/src/memory_storage_provider.rs | 15 ++ 10 files changed, 263 insertions(+), 136 deletions(-) diff --git a/dlc-manager/src/chain_monitor.rs b/dlc-manager/src/chain_monitor.rs index ccdcd2f9..448169f7 100644 --- a/dlc-manager/src/chain_monitor.rs +++ b/dlc-manager/src/chain_monitor.rs @@ -45,8 +45,12 @@ pub(crate) enum TxType { BufferTx, CollaborativeClose, SplitTx, + // TODO: Add `is_offer` here. SettleTx, Cet, + SettleTx2 { + is_offer: bool, + }, } impl_dlc_writeable_enum!(TxType,; @@ -55,6 +59,9 @@ impl_dlc_writeable_enum!(TxType,; (own_adaptor_signature, {cb_writeable, write_ecdsa_adaptor_signature, read_ecdsa_adaptor_signature}), (is_offer, writeable), (revoked_tx_type, writeable) + }), + (6, SettleTx2, { + (is_offer, writeable) });; (1, BufferTx), (2, CollaborativeClose), (3, SplitTx), (4, SettleTx), (5, Cet) ); @@ -180,6 +187,42 @@ impl ChainMonitor { } } + pub(crate) fn did_we_offer_last_channel_settlement( + &self, + channel_id: &[u8; 32], + ) -> Option { + let mut watched_txs = self.watched_tx.iter(); + + watched_txs.find_map(|(_, state)| match state { + WatchState::Registered { + channel_info: + ChannelInfo { + channel_id: cid, + tx_type: + TxType::Revoked { + revoked_tx_type: RevokedTxType::Buffer, + is_offer, + .. + }, + }, + } + | WatchState::Confirmed { + channel_info: + ChannelInfo { + channel_id: cid, + tx_type: + TxType::Revoked { + revoked_tx_type: RevokedTxType::Buffer, + is_offer, + .. + }, + }, + .. + } if channel_id == cid => Some(*is_offer), + _ => None, + }) + } + /// All the currently watched transactions which have been confirmed. pub(crate) fn confirmed_txs(&self) -> Vec<(Transaction, ChannelInfo)> { (self.watched_tx.values()) diff --git a/dlc-manager/src/channel/mod.rs b/dlc-manager/src/channel/mod.rs index 7dcd30f5..947b02ed 100644 --- a/dlc-manager/src/channel/mod.rs +++ b/dlc-manager/src/channel/mod.rs @@ -31,6 +31,10 @@ pub enum Channel { /// has broadcast a buffer transaction and is waiting to finalize the /// closing of the channel by broadcasting a CET. Closing(ClosingChannel), + /// A [`Channel`] is in `SettledClosing` state when the local party + /// has broadcast a settle transaction and is waiting to finalize the + /// closing of the channel by claiming their output. + SettledClosing(SettledClosingChannel), /// A [`Channel`] is in `Closed` state when it was force closed by /// the local party. Closed(ClosedChannel), @@ -64,6 +68,7 @@ impl std::fmt::Debug for Channel { Channel::FailedAccept(_) => "failed accept", Channel::FailedSign(_) => "failed sign", Channel::Closing(_) => "closing", + Channel::SettledClosing(_) => "settled closing", Channel::Closed(_) => "closed", Channel::CounterClosed(_) => "counter closed", Channel::ClosedPunished(_) => "closed punished", @@ -84,6 +89,7 @@ impl Channel { Channel::FailedAccept(f) => f.counter_party, Channel::FailedSign(f) => f.counter_party, Channel::Closing(c) => c.counter_party, + Channel::SettledClosing(c) => c.counter_party, Channel::Closed(c) | Channel::CounterClosed(c) | Channel::CollaborativelyClosed(c) => { c.counter_party } @@ -101,6 +107,7 @@ impl Channel { Channel::FailedAccept(f) => f.reference_id, Channel::FailedSign(f) => f.reference_id, Channel::Closing(c) => c.reference_id, + Channel::SettledClosing(c) => c.reference_id, Channel::Closed(c) | Channel::CounterClosed(c) | Channel::CollaborativelyClosed(c) => { c.reference_id } @@ -167,6 +174,28 @@ pub struct ClosingChannel { pub reference_id: Option, } +#[derive(Clone)] +/// A channel is closing when its buffer transaction was broadcast or detected on chain. +pub struct SettledClosingChannel { + /// The [`secp256k1_zkp::PublicKey`] of the counter party. + pub counter_party: PublicKey, + /// The temporary [`DlcChannelId`] of the channel. + pub temporary_channel_id: DlcChannelId, + /// The [`DlcChannelId`] for the channel. + pub channel_id: DlcChannelId, + /// The previous state the channel was before being closed, if that state was the `Signed` one, + /// otherwise is `None`. + pub rollback_state: Option, + /// The settle transaction that was broadcast. + pub settle_transaction: Transaction, + /// The claim transaction that was broadcast. + pub claim_transaction: Transaction, + /// Whether the local party initiated the closing of the channel. + pub is_closer: bool, + /// The reference id set by the api user. + pub reference_id: Option, +} + #[derive(Clone)] /// A channel is closed when its buffer transaction has been spent. pub struct ClosedChannel { @@ -223,6 +252,7 @@ impl Channel { Channel::FailedAccept(f) => f.temporary_channel_id, Channel::FailedSign(f) => f.channel_id, Channel::Closing(c) => c.channel_id, + Channel::SettledClosing(c) => c.channel_id, Channel::Closed(c) | Channel::CounterClosed(c) | Channel::CollaborativelyClosed(c) => { c.channel_id } diff --git a/dlc-manager/src/channel/ser.rs b/dlc-manager/src/channel/ser.rs index 3745241d..c0746537 100644 --- a/dlc-manager/src/channel/ser.rs +++ b/dlc-manager/src/channel/ser.rs @@ -3,7 +3,7 @@ use super::accepted_channel::AcceptedChannel; use super::offered_channel::OfferedChannel; use super::party_points::PartyBasePoints; use super::signed_channel::{SignedChannel, SignedChannelState}; -use super::{ClosedChannel, ClosedPunishedChannel, ClosingChannel, FailedAccept, FailedSign}; +use super::{ClosedChannel, ClosedPunishedChannel, ClosingChannel, FailedAccept, FailedSign, SettledClosingChannel}; use dlc_messages::ser_impls::{ read_ecdsa_adaptor_signature, read_string, write_ecdsa_adaptor_signature, write_string, @@ -65,7 +65,7 @@ impl_dlc_writeable_enum!( (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) }), - (12, SettledClosing, {(settle_transaction, writeable), (contract_id, writeable), (is_initiator, writeable)}) + (12, SettledClosing, {(settle_transaction, writeable), (is_offer, writeable), (is_initiator, writeable)}) ;; ); @@ -82,5 +82,15 @@ impl_dlc_writeable!(ClosingChannel, { (is_closer, writeable), (reference_id, option) }); +impl_dlc_writeable!(SettledClosingChannel, { + (channel_id, writeable), + (counter_party, writeable), + (temporary_channel_id, writeable), + (rollback_state, option), + (settle_transaction, writeable), + (claim_transaction, writeable), + (is_closer, writeable), + (reference_id, option) +}); impl_dlc_writeable!(ClosedChannel, {(channel_id, writeable), (counter_party, writeable), (temporary_channel_id, writeable), (reference_id, option), (closing_txid, writeable)}); impl_dlc_writeable!(ClosedPunishedChannel, {(channel_id, writeable), (counter_party, writeable), (temporary_channel_id, writeable), (punish_txid, writeable), (reference_id, option)}); diff --git a/dlc-manager/src/channel/signed_channel.rs b/dlc-manager/src/channel/signed_channel.rs index e8b03c49..58add47a 100644 --- a/dlc-manager/src/channel/signed_channel.rs +++ b/dlc-manager/src/channel/signed_channel.rs @@ -297,15 +297,14 @@ 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. + /// A [`SignedChannel`] is in `SettledClosing` state when a settle transaction has been + /// broadcast, and we are waiting to finalize the closing of 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, + /// Indicates whether the local party originally offered to settle the channel or not. + is_offer: bool, /// Whether the local party initiated the closing of the channel. is_initiator: bool, }, diff --git a/dlc-manager/src/channel_updater.rs b/dlc-manager/src/channel_updater.rs index b492d24f..87835db6 100644 --- a/dlc-manager/src/channel_updater.rs +++ b/dlc-manager/src/channel_updater.rs @@ -7,7 +7,7 @@ use crate::{chain_monitor::{ChainMonitor, ChannelInfo, TxType}, channel::{ offered_channel::OfferedChannel, party_points::PartyBasePoints, signed_channel::{SignedChannel, SignedChannelState}, - Channel, ClosedChannel, + Channel, ClosedChannel, SettledClosingChannel, }, contract::{ accepted_contract::AcceptedContract, contract_info::ContractInfo, contract_input::ContractInput, offered_contract::OfferedContract, @@ -2717,6 +2717,7 @@ pub(crate) fn initiate_unilateral_close_settled_channel( signed_channel: &mut SignedChannel, signer: &S, sub_channel: Option<(SubChannel, &ClosingSubChannel)>, + is_settle_offer: bool, is_initiator: bool, reference_id: Option ) -> Result<(), Error> @@ -2820,15 +2821,11 @@ 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_offer: is_settle_offer, is_initiator, }; @@ -2841,10 +2838,10 @@ where pub fn finalize_unilateral_close_settled_channel( secp: &Secp256k1, signed_channel: &SignedChannel, - confirmed_contract: &SignedContract, destination_address: &Address, fee_rate_per_vb: u64, signer: &S, + is_offer: bool, is_initiator: bool, ) -> Result<(Transaction, Channel), Error> where @@ -2853,61 +2850,28 @@ where 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( + let own_revoke_params = signed_channel.own_points.get_revokable_params( secp, - &accept_points.revocation_basepoint, - offer_per_update_point, + &signed_channel.counter_points.revocation_basepoint, + &signed_channel.own_per_update_point, ); - let accept_revoke_params = accept_points.get_revokable_params( + let counter_revoke_params = signed_channel.counter_points.get_revokable_params( secp, - &offer_points.revocation_basepoint, - accept_per_update_point, + &signed_channel.own_points.revocation_basepoint, + &signed_channel.counter_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 own_basepoint = signed_channel.own_points.own_basepoint; + let own_per_update_point = signed_channel.own_per_update_point; - 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 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_revoke_params, + &counter_revoke_params, &own_sk, settle_transaction, destination_address, @@ -2917,19 +2881,18 @@ where is_offer, )?; - let closed_channel = ClosedChannel { + let closing_channel = SettledClosingChannel { counter_party: signed_channel.counter_party, temporary_channel_id: signed_channel.temporary_channel_id, channel_id: signed_channel.channel_id, + rollback_state: Some(signed_channel.clone()), + settle_transaction: settle_transaction.clone(), + claim_transaction: claim_tx.clone(), + is_closer: is_initiator, reference_id: signed_channel.reference_id, - closing_txid: claim_tx.txid() }; - let channel = if is_initiator { - Channel::Closed(closed_channel) - } else { - Channel::CounterClosed(closed_channel) - }; + let channel = Channel::SettledClosing(closing_channel); Ok((claim_tx, channel)) } diff --git a/dlc-manager/src/lib.rs b/dlc-manager/src/lib.rs index f6b98fd2..8ecc00eb 100644 --- a/dlc-manager/src/lib.rs +++ b/dlc-manager/src/lib.rs @@ -45,7 +45,7 @@ use bitcoin::{Address, Block, OutPoint, Script, Transaction, TxOut, Txid}; use chain_monitor::ChainMonitor; use channel::offered_channel::OfferedChannel; use channel::signed_channel::{SignedChannel, SignedChannelStateType}; -use channel::Channel; +use channel::{Channel, SettledClosingChannel}; use contract::PreClosedContract; use contract::{offered_contract::OfferedContract, signed_contract::SignedContract, Contract}; use dlc_messages::oracle_msgs::{OracleAnnouncement, OracleAttestation}; @@ -182,6 +182,8 @@ pub trait Storage { ) -> Result, Error>; /// Returns the set of channels in offer state. fn get_offered_channels(&self) -> Result, Error>; + /// Returns the set of channels in settled closing state. + fn get_settled_closing_channels(&self) -> Result, Error>; /// Writes the [`ChainMonitor`] data to the store. fn persist_chain_monitor(&self, monitor: &ChainMonitor) -> Result<(), Error>; /// Returns the latest [`ChainMonitor`] in the store if any. diff --git a/dlc-manager/src/manager.rs b/dlc-manager/src/manager.rs index cf6d414b..0ff32d18 100644 --- a/dlc-manager/src/manager.rs +++ b/dlc-manager/src/manager.rs @@ -4,7 +4,7 @@ use super::{Blockchain, Oracle, Storage, Time, Wallet}; use crate::chain_monitor::{ChainMonitor, ChannelInfo, RevokedTxType, TxType}; use crate::channel::offered_channel::OfferedChannel; use crate::channel::signed_channel::{SignedChannel, SignedChannelState, SignedChannelStateType}; -use crate::channel::{Channel, ClosedChannel, ClosedPunishedChannel}; +use crate::channel::{Channel, ClosedChannel, ClosedPunishedChannel, SettledClosingChannel}; use crate::channel_updater::{get_unix_time_now, verify_signed_channel}; use crate::channel_updater::{self, get_signed_channel_state}; use crate::contract::{ @@ -1235,11 +1235,11 @@ where &self, signed_channel: SignedChannel, ) -> Result<(), Error> { - let (settle_tx, contract_id, &is_initiator) = get_signed_channel_state!( + let (settle_tx, &is_offer, &is_initiator) = get_signed_channel_state!( signed_channel, SettledClosing, settle_transaction, - contract_id, + is_offer, is_initiator )?; @@ -1249,13 +1249,10 @@ where >= CET_NSEQUENCE { log::info!( - "Settle transaction for contract {} has enough confirmations to spend from it", - serialize_hex(&contract_id) + "Settle transaction for channel {} has enough confirmations to spend from it", + serialize_hex(&signed_channel.channel_id) ); - let confirmed_contract = - get_contract_in_state!(self, contract_id, Confirmed, None as Option)?; - let fee_rate_per_vb: u64 = { let fee_rate = self .fee_estimator @@ -1268,30 +1265,72 @@ where fee_rate.into() }; - let (signed_claim_tx, closed_channel) = + let (claim_tx, closed_channel) = channel_updater::finalize_unilateral_close_settled_channel( &self.secp, &signed_channel, - &confirmed_contract, &self.wallet.get_new_address()?, fee_rate_per_vb, &self.wallet, + is_offer, is_initiator, )?; - let closed_contract = self.get_unilaterally_settled_contract( - &confirmed_contract.accepted_contract.get_contract_id(), - signed_claim_tx.output[0].value, - true, - )?; + let confirmations = self + .blockchain + .get_transaction_confirmations(&claim_tx.txid())?; + + if confirmations < 1 { + self.blockchain.send_transaction(&claim_tx)?; + } else if confirmations >= NB_CONFIRMATIONS { + self.chain_monitor + .lock() + .unwrap() + .cleanup_channel(signed_channel.channel_id); + self.store + .upsert_channel(closed_channel, None)?; + } + } + + Ok(()) + } + + fn try_confirm_claim_tx(&self, channel: &SettledClosingChannel) -> Result<(), Error> { + let claim_tx = &channel.claim_transaction; + + let confirmations = self + .blockchain + .get_transaction_confirmations(&claim_tx.txid())?; + + if confirmations < 1 { + self.blockchain.send_transaction(&claim_tx)?; + } else if confirmations >= NB_CONFIRMATIONS { self.chain_monitor .lock() .unwrap() - .cleanup_channel(signed_channel.channel_id); + .cleanup_channel(channel.channel_id); + + let closed_channel = if channel.is_closer { + Channel::Closed(ClosedChannel { + counter_party: channel.counter_party, + temporary_channel_id: channel.temporary_channel_id, + channel_id: channel.channel_id, + reference_id: channel.reference_id, + closing_txid: channel.settle_transaction.txid() + }) + } else { + Channel::CounterClosed(ClosedChannel { + counter_party: channel.counter_party, + temporary_channel_id: channel.temporary_channel_id, + channel_id: channel.channel_id, + reference_id: channel.reference_id, + closing_txid: channel.settle_transaction.txid() + }) + }; self.store - .upsert_channel(closed_channel, Some(Contract::Closed(closed_contract)))?; + .upsert_channel(closed_channel, None)?; } Ok(()) @@ -2123,13 +2162,23 @@ where } } - let settled_closing_channels = self + let signed_settled_closing_channels = self .store .get_signed_channels(Some(SignedChannelStateType::SettledClosing))?; - for channel in settled_closing_channels { + for channel in signed_settled_closing_channels { if let Err(e) = self.try_finalize_settled_closing_channel(channel) { - error!("Error trying to close established channel: {}", e); + error!("Error trying to close settled channel: {}", e); + } + } + + let settled_closing_channels = self + .store + .get_settled_closing_channels()?; + + for channel in settled_closing_channels { + if let Err(e) = self.try_confirm_claim_tx(&channel) { + error!("Error trying to confirm claim TX of settled channel: {}", e); } } @@ -2394,14 +2443,44 @@ where // tx to close the channel it is unlikely that the tx will // not be part of a future block. - let contract_id = signed_channel - .get_contract_id() - .expect("to have a contract id"); + let is_settle_offer = { + let chain_monitor = self.chain_monitor.lock().unwrap(); + chain_monitor.did_we_offer_last_channel_settlement(&signed_channel.channel_id) + }; + + let is_settle_offer = match is_settle_offer { + Some(is_settle_offer) => is_settle_offer, + None => { + log::error!("Cannot force close settled channel without knowledge of who offered settlement"); + continue; + }, + }; let mut state = SignedChannelState::SettledClosing { settle_transaction: tx.clone(), + is_offer: is_settle_offer, + is_initiator: false, + }; + std::mem::swap(&mut signed_channel.state, &mut state); + + signed_channel.roll_back_state = Some(state); + + self.store + .upsert_channel(Channel::Signed(signed_channel), None)?; + + false + } + TxType::SettleTx2 { is_offer } => { + // TODO(tibo): should only considered closed after some confirmations. + // Ideally should save previous state, and maybe restore in + // case of reorg, though if the counter party has sent the + // tx to close the channel it is unlikely that the tx will + // not be part of a future block. + + let mut state = SignedChannelState::SettledClosing { + settle_transaction: tx.clone(), + is_offer, is_initiator: false, - contract_id, }; std::mem::swap(&mut signed_channel.state, &mut state); @@ -2633,11 +2712,22 @@ where is_initiator: bool, reference_id: Option ) -> Result<(), Error> { + let is_settle_offer = { + let chain_monitor = self.chain_monitor.lock().unwrap(); + chain_monitor.did_we_offer_last_channel_settlement(&signed_channel.channel_id) + }.ok_or_else( + || Error::InvalidState( + "Cannot force close settled channel without knowledge of who offered settlement" + .to_string() + ) + )?; + crate::channel_updater::initiate_unilateral_close_settled_channel( &self.secp, &mut signed_channel, &self.wallet, sub_channel, + is_settle_offer, is_initiator, reference_id, )?; @@ -2726,38 +2816,6 @@ where pnl, }) } - - fn get_unilaterally_settled_contract( - &self, - contract_id: &ContractId, - payout: u64, - is_own_payout: bool, - ) -> Result { - let contract = get_contract_in_state!(self, contract_id, Confirmed, None::)?; - let own_collateral = if contract.accepted_contract.offered_contract.is_offer_party { - contract - .accepted_contract - .offered_contract - .offer_params - .collateral - } else { - contract.accepted_contract.accept_params.collateral - }; - let own_payout = if is_own_payout { - payout - } else { - contract.accepted_contract.offered_contract.total_collateral - payout - }; - let pnl = own_payout as i64 - own_collateral as i64; - Ok(ClosedContract { - attestations: None, - signed_cet: None, - contract_id: *contract_id, - temporary_contract_id: contract.accepted_contract.offered_contract.id, - counter_party_id: contract.accepted_contract.offered_contract.counter_party, - pnl, - }) - } } #[cfg(test)] diff --git a/dlc-sled-storage-provider/src/lib.rs b/dlc-sled-storage-provider/src/lib.rs index f0eda35e..a33e45f3 100644 --- a/dlc-sled-storage-provider/src/lib.rs +++ b/dlc-sled-storage-provider/src/lib.rs @@ -21,7 +21,7 @@ use dlc_manager::channel::accepted_channel::AcceptedChannel; use dlc_manager::channel::offered_channel::OfferedChannel; use dlc_manager::channel::signed_channel::{SignedChannel, SignedChannelStateType}; use dlc_manager::channel::{ - Channel, ClosedChannel, ClosedPunishedChannel, ClosingChannel, FailedAccept, FailedSign, + Channel, ClosedChannel, ClosedPunishedChannel, ClosingChannel, FailedAccept, FailedSign, SettledClosingChannel, }; use dlc_manager::contract::accepted_contract::AcceptedContract; use dlc_manager::contract::offered_contract::OfferedContract; @@ -132,7 +132,8 @@ convertible_enum!( CollaborativelyClosed, FailedAccept, FailedSign, - Cancelled,; + Cancelled, + SettledClosing,; }, Channel ); @@ -425,6 +426,14 @@ impl Storage for SledStorageProvider { ) } + fn get_settled_closing_channels(&self) -> Result, Error> { + self.get_data_with_prefix( + &self.channel_tree()?, + &[ChannelPrefix::SettledClosing.into()], + None, + ) + } + fn persist_chain_monitor(&self, monitor: &ChainMonitor) -> Result<(), Error> { self.open_tree(&[CHAIN_MONITOR_TREE])? .insert([CHAIN_MONITOR_KEY], monitor.serialize()?) @@ -730,6 +739,7 @@ fn serialize_channel(channel: &Channel) -> Result, ::std::io::Error> { Channel::FailedAccept(f) => f.serialize(), Channel::FailedSign(f) => f.serialize(), Channel::Closing(c) => c.serialize(), + Channel::SettledClosing(c) => c.serialize(), Channel::Closed(c) | Channel::CounterClosed(c) | Channel::CollaborativelyClosed(c) => { c.serialize() } @@ -772,6 +782,9 @@ fn deserialize_channel(buff: &sled::IVec) -> Result { ChannelPrefix::Closing => { Channel::Closing(ClosingChannel::deserialize(&mut cursor).map_err(to_storage_error)?) } + ChannelPrefix::SettledClosing => { + Channel::SettledClosing(SettledClosingChannel::deserialize(&mut cursor).map_err(to_storage_error)?) + } ChannelPrefix::Closed => { Channel::Closed(ClosedChannel::deserialize(&mut cursor).map_err(to_storage_error)?) } diff --git a/dlc/src/channel/mod.rs b/dlc/src/channel/mod.rs index 5fb0230e..e1e94f85 100644 --- a/dlc/src/channel/mod.rs +++ b/dlc/src/channel/mod.rs @@ -405,8 +405,8 @@ pub fn sign_cet( /// Create and sign a transaction claiming a settle transaction output. pub fn create_and_sign_claim_settle_transaction( secp: &Secp256k1, - offer_params: &RevokeParams, - accept_params: &RevokeParams, + own_params: &RevokeParams, + counter_params: &RevokeParams, own_sk: &SecretKey, settle_tx: &Transaction, dest_address: &Address, @@ -415,16 +415,10 @@ pub fn create_and_sign_claim_settle_transaction( fee_rate_per_vb: u64, is_offer: bool, ) -> Result { - let (own_params, counter_params) = if is_offer { - (offer_params, accept_params) - } else { - (accept_params, offer_params) - }; - let descriptor = settle_descriptor(counter_params, &own_params.own_pk, csv_timelock); // TODO: Do we need to flip this? - let vout = u32::from(is_offer); + let vout = u32::from(!is_offer); let tx_in = TxIn { previous_output: OutPoint { diff --git a/mocks/src/memory_storage_provider.rs b/mocks/src/memory_storage_provider.rs index b186c51d..2e55d9f9 100644 --- a/mocks/src/memory_storage_provider.rs +++ b/mocks/src/memory_storage_provider.rs @@ -4,6 +4,7 @@ use dlc_manager::channel::{ offered_channel::OfferedChannel, signed_channel::{SignedChannel, SignedChannelStateType}, Channel, + SettledClosingChannel, }; use dlc_manager::contract::{ offered_contract::OfferedContract, signed_contract::SignedContract, Contract, PreClosedContract, @@ -269,6 +270,20 @@ impl Storage for MemoryStorage { Ok(res) } + fn get_settled_closing_channels(&self) -> Result, DaemonError> { + let map = self.channels.read().expect("Could not get read lock"); + + let mut res: Vec = Vec::new(); + + for (_, val) in map.iter() { + if let Channel::SettledClosing(c) = val { + res.push(c.clone()) + } + } + + Ok(res) + } + fn persist_chain_monitor(&self, _: &ChainMonitor) -> Result<(), DaemonError> { // No need to persist for mocks Ok(())