Skip to content

Commit

Permalink
chore(channel): Ignore invalid collab close offers
Browse files Browse the repository at this point in the history
  • Loading branch information
holzeis committed Mar 5, 2024
1 parent ddff388 commit d621579
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions coordinator/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::node::storage::NodeStorage;
use crate::position::models::PositionState;
use crate::storage::CoordinatorTenTenOneStorage;
use crate::trade::TradeExecutor;
use anyhow::bail;
use anyhow::Context;
use anyhow::Result;
use bitcoin::secp256k1::PublicKey;
Expand Down Expand Up @@ -206,6 +207,8 @@ impl Node {
"Received channel message"
);

self.verify_collab_close_offer(&node_id, channel_msg)?;

let inbound_msg = {
let mut conn = self.pool.get()?;
let serialized_inbound_message = SerializedDlcMessage::try_from(msg)?;
Expand Down Expand Up @@ -459,4 +462,55 @@ impl Node {

Ok(())
}

/// TODO(holzeis): We need to intercept the collaborative close offer before
/// processing it in `rust-dlc` as it would otherwise overwrite the `own_payout`
/// amount, which would prevent us from verifying the proposed payout amount.
///
/// If the expected own payout amount does not match the offered own payout amount,
/// we will simply ignore the offer.
fn verify_collab_close_offer(&self, node_id: &PublicKey, msg: &ChannelMessage) -> Result<()> {
let close_offer = match msg {
ChannelMessage::CollaborativeCloseOffer(close_offer) => close_offer,
_ => return Ok(()),
};

let channel = self.inner.get_dlc_channel_by_id(&close_offer.channel_id)?;
match channel {
Channel::Signed(SignedChannel {
state: SignedChannelState::Established { .. },
channel_id,
..
}) => {
let channel_id_hex = hex::encode(channel_id);

tracing::debug!(%node_id, channel_id = %channel_id_hex, "Ignoring dlc channel collaborative close offer");
bail!("channel_id = {channel_id_hex}, node_id = {node_id}, state = Established Received DLC channel \
collaborative close offer in an unexpected signed channel state");
}
Channel::Signed(SignedChannel {
state:
SignedChannelState::Settled {
own_payout: expected_own_payout,
..
},
channel_id,
..
}) => {
let offered_own_payout = close_offer.counter_payout;
if expected_own_payout != offered_own_payout {
let channel_id_hex = hex::encode(channel_id);

// TODO(holzeis): Implement reject collaborative close offer flow https://github.com/get10101/10101/issues/2019
tracing::debug!(%node_id, channel_id = %channel_id_hex, "Ignoring dlc channel collaborative close offer");

bail!("node_id = {node_id}, channel_id = {channel_id_hex}, offered_own_payout = {offered_own_payout}, \
expected_own_payout = {expected_own_payout}, Received DLC channel collaborative close offer with an invalid payout");
}
}
_ => {}
};

Ok(())
}
}

0 comments on commit d621579

Please sign in to comment.