Skip to content

Commit

Permalink
chore(coordinator): Enrich DlcProtocolType model
Browse files Browse the repository at this point in the history
We can now differentiate between opening a channel, opening a position
and resizing a position.
  • Loading branch information
luckysori committed Apr 10, 2024
1 parent 4887e94 commit a6a8c8e
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 45 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ALTER TYPE "Protocol_Type_Type"
RENAME VALUE 'open-channel' TO 'open';

ALTER TYPE "Protocol_Type_Type"
RENAME VALUE 'open-position' TO 'renew';
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- Must use `IF NOT EXISTS` because enum values cannot be removed on "down" migrations.
ALTER TYPE "Protocol_Type_Type"
ADD VALUE IF NOT EXISTS 'resize-position';

ALTER TYPE "Protocol_Type_Type"
RENAME VALUE 'open' TO 'open-channel';

ALTER TYPE "Protocol_Type_Type"
RENAME VALUE 'renew' TO 'open-position';
10 changes: 6 additions & 4 deletions coordinator/src/db/custom_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,13 @@ impl FromSql<ProtocolStateType, Pg> for DlcProtocolState {
impl ToSql<ProtocolTypeType, Pg> for DlcProtocolType {
fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
match *self {
DlcProtocolType::Open => out.write_all(b"open")?,
DlcProtocolType::OpenChannel => out.write_all(b"open-channel")?,
DlcProtocolType::Settle => out.write_all(b"settle")?,
DlcProtocolType::Renew => out.write_all(b"renew")?,
DlcProtocolType::OpenPosition => out.write_all(b"open-position")?,
DlcProtocolType::Rollover => out.write_all(b"rollover")?,
DlcProtocolType::Close => out.write_all(b"close")?,
DlcProtocolType::ForceClose => out.write_all(b"force-close")?,
DlcProtocolType::ResizePosition => out.write_all(b"resize-position")?,
}
Ok(IsNull::No)
}
Expand All @@ -195,12 +196,13 @@ impl ToSql<ProtocolTypeType, Pg> for DlcProtocolType {
impl FromSql<ProtocolTypeType, Pg> for DlcProtocolType {
fn from_sql(bytes: PgValue<'_>) -> deserialize::Result<Self> {
match bytes.as_bytes() {
b"open" => Ok(DlcProtocolType::Open),
b"open-channel" => Ok(DlcProtocolType::OpenChannel),
b"settle" => Ok(DlcProtocolType::Settle),
b"renew" => Ok(DlcProtocolType::Renew),
b"open-position" => Ok(DlcProtocolType::OpenPosition),
b"rollover" => Ok(DlcProtocolType::Rollover),
b"close" => Ok(DlcProtocolType::Close),
b"force-close" => Ok(DlcProtocolType::ForceClose),
b"resize-position" => Ok(DlcProtocolType::ResizePosition),
_ => Err("Unrecognized enum variant for ProtocolTypeType".into()),
}
}
Expand Down
2 changes: 1 addition & 1 deletion coordinator/src/db/dlc_channels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub(crate) fn set_dlc_channel_open(
.execute(conn)
}

pub(crate) fn update_channel_on_renew(
pub(crate) fn update_channel(
conn: &mut PgConnection,
channel_id: &DlcChannelId,
coordinator_reserve: Amount,
Expand Down
22 changes: 14 additions & 8 deletions coordinator/src/db/dlc_protocols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,13 @@ impl QueryId for ProtocolStateType {
#[derive(Debug, Clone, Copy, PartialEq, FromSqlRow, AsExpression, Eq, Hash)]
#[diesel(sql_type = ProtocolTypeType)]
pub(crate) enum DlcProtocolType {
Open,
Renew,
OpenChannel,
OpenPosition,
Settle,
Close,
ForceClose,
Rollover,
ResizePosition,
}

impl QueryId for ProtocolTypeType {
Expand Down Expand Up @@ -83,13 +84,13 @@ pub(crate) fn get_dlc_protocol(
.first(conn)?;

let protocol_type = match dlc_protocol.protocol_type {
DlcProtocolType::Open => {
DlcProtocolType::OpenChannel => {
let trade_params = db::trade_params::get(conn, protocol_id)?;
dlc_protocol::DlcProtocolType::Open { trade_params }
dlc_protocol::DlcProtocolType::OpenChannel { trade_params }
}
DlcProtocolType::Renew => {
DlcProtocolType::OpenPosition => {
let trade_params = db::trade_params::get(conn, protocol_id)?;
dlc_protocol::DlcProtocolType::Renew { trade_params }
dlc_protocol::DlcProtocolType::OpenPosition { trade_params }
}
DlcProtocolType::Settle => {
let trade_params = db::trade_params::get(conn, protocol_id)?;
Expand All @@ -104,6 +105,10 @@ pub(crate) fn get_dlc_protocol(
DlcProtocolType::Rollover => dlc_protocol::DlcProtocolType::Rollover {
trader: PublicKey::from_str(&dlc_protocol.trader_pubkey).expect("valid public key"),
},
DlcProtocolType::ResizePosition => {
let trade_params = db::trade_params::get(conn, protocol_id)?;
dlc_protocol::DlcProtocolType::OpenPosition { trade_params }
}
};

let protocol = dlc_protocol::DlcProtocol {
Expand Down Expand Up @@ -209,12 +214,13 @@ impl From<DlcProtocolState> for dlc_protocol::DlcProtocolState {
impl From<dlc_protocol::DlcProtocolType> for DlcProtocolType {
fn from(value: dlc_protocol::DlcProtocolType) -> Self {
match value {
dlc_protocol::DlcProtocolType::Open { .. } => DlcProtocolType::Open,
dlc_protocol::DlcProtocolType::Renew { .. } => DlcProtocolType::Renew,
dlc_protocol::DlcProtocolType::OpenChannel { .. } => DlcProtocolType::OpenChannel,
dlc_protocol::DlcProtocolType::OpenPosition { .. } => DlcProtocolType::OpenPosition,
dlc_protocol::DlcProtocolType::Settle { .. } => DlcProtocolType::Settle,
dlc_protocol::DlcProtocolType::Close { .. } => DlcProtocolType::Close,
dlc_protocol::DlcProtocolType::ForceClose { .. } => DlcProtocolType::ForceClose,
dlc_protocol::DlcProtocolType::Rollover { .. } => DlcProtocolType::Rollover,
dlc_protocol::DlcProtocolType::ResizePosition { .. } => DlcProtocolType::ResizePosition,
}
}
}
134 changes: 109 additions & 25 deletions coordinator/src/dlc_protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,27 +153,49 @@ pub enum DlcProtocolState {

#[derive(Clone, Debug)]
pub enum DlcProtocolType {
Open { trade_params: TradeParams },
Renew { trade_params: TradeParams },
Settle { trade_params: TradeParams },
Close { trader: PublicKey },
ForceClose { trader: PublicKey },
Rollover { trader: PublicKey },
/// Opening a channel also opens a position.
OpenChannel {
trade_params: TradeParams,
},
OpenPosition {
trade_params: TradeParams,
},
ResizePosition {
trade_params: TradeParams,
},
Rollover {
trader: PublicKey,
},
Settle {
trade_params: TradeParams,
},
Close {
trader: PublicKey,
},
ForceClose {
trader: PublicKey,
},
}

impl DlcProtocolType {
pub fn open(trade_params: &commons::TradeParams, protocol_id: ProtocolId) -> Self {
Self::Open {
pub fn open_channel(trade_params: &commons::TradeParams, protocol_id: ProtocolId) -> Self {
Self::OpenChannel {
trade_params: TradeParams::new(trade_params, protocol_id, None),
}
}

pub fn renew(
pub fn open_position(trade_params: &commons::TradeParams, protocol_id: ProtocolId) -> Self {
Self::OpenPosition {
trade_params: TradeParams::new(trade_params, protocol_id, None),
}
}

pub fn resize_position(
trade_params: &commons::TradeParams,
protocol_id: ProtocolId,
trader_pnl: Option<SignedAmount>,
) -> Self {
Self::Renew {
Self::ResizePosition {
trade_params: TradeParams::new(trade_params, protocol_id, trader_pnl),
}
}
Expand All @@ -188,10 +210,13 @@ impl DlcProtocolType {
impl DlcProtocolType {
pub fn get_trader_pubkey(&self) -> &PublicKey {
match self {
DlcProtocolType::Open {
DlcProtocolType::OpenChannel {
trade_params: TradeParams { trader, .. },
} => trader,
DlcProtocolType::Renew {
DlcProtocolType::OpenPosition {
trade_params: TradeParams { trader, .. },
} => trader,
DlcProtocolType::ResizePosition {
trade_params: TradeParams { trader, .. },
} => trader,
DlcProtocolType::Settle {
Expand Down Expand Up @@ -238,8 +263,8 @@ impl DlcProtocolExecutor {
)?;

match protocol_type {
DlcProtocolType::Open { trade_params }
| DlcProtocolType::Renew { trade_params }
DlcProtocolType::OpenChannel { trade_params }
| DlcProtocolType::OpenPosition { trade_params }
| DlcProtocolType::Settle { trade_params } => {
db::trade_params::insert(conn, protocol_id, &trade_params)?;
}
Expand Down Expand Up @@ -272,12 +297,24 @@ impl DlcProtocolExecutor {
let dlc_protocol = db::dlc_protocols::get_dlc_protocol(&mut conn, protocol_id)?;
conn.transaction(|conn| {
match &dlc_protocol.protocol_type {
DlcProtocolType::Open { trade_params }
| DlcProtocolType::Renew { trade_params } => {
DlcProtocolType::OpenChannel { trade_params }
| DlcProtocolType::OpenPosition { trade_params } => {
let contract_id = contract_id
.context("missing contract id")
.map_err(|_| RollbackTransaction)?;
self.finish_open_or_resize_trade_dlc_protocol(
self.finish_open_position_dlc_protocol(
conn,
trade_params,
protocol_id,
&contract_id,
channel_id,
)
}
DlcProtocolType::ResizePosition { trade_params } => {
let contract_id = contract_id
.context("missing contract id")
.map_err(|_| RollbackTransaction)?;
self.finish_resize_position_dlc_protocol(
conn,
trade_params,
protocol_id,
Expand Down Expand Up @@ -318,8 +355,8 @@ impl DlcProtocolExecutor {
})?;

match &dlc_protocol.protocol_type {
DlcProtocolType::Open { trade_params }
| DlcProtocolType::Renew { trade_params }
DlcProtocolType::OpenChannel { trade_params }
| DlcProtocolType::OpenPosition { trade_params }
| DlcProtocolType::Settle { trade_params } => {
if let Err(e) = {
tx_position_feed.send(InternalPositionUpdateMessage::NewTrade {
Expand Down Expand Up @@ -441,14 +478,61 @@ impl DlcProtocolExecutor {
Ok(())
}

/// Complete an open or resize trade DLC protocol as successful and update the 10101 metadata
/// accordingly, in a single database transaction.
/// Complete a DLC protocol that opens a position, by updating several database tables in a
/// single transaction.
///
/// Specifically, we:
///
/// - Set DLC protocol to success.
/// - Update the [`PositionState::Proposed`] or [`PositionState::Resizing`] position state to
/// [`PositionState::Open`].
/// - Update the position state to [`PositionState::Open`].
/// - Create and insert the new trade.
fn finish_open_or_resize_trade_dlc_protocol(
fn finish_open_position_dlc_protocol(
&self,
conn: &mut PgConnection,
trade_params: &TradeParams,
protocol_id: ProtocolId,
contract_id: &ContractId,
channel_id: &DlcChannelId,
) -> QueryResult<()> {
db::dlc_protocols::set_dlc_protocol_state_to_success(
conn,
protocol_id,
contract_id,
channel_id,
)?;

// TODO(holzeis): We are still updating the position based on the position state. This
// will change once we only have a single position per user and representing
// the position only as view on multiple trades.
let position = db::positions::Position::update_position_state(
conn,
trade_params.trader.to_string(),
vec![PositionState::Proposed],
PositionState::Open,
)?;

let order_matching_fee = trade_params.matching_fee;

let new_trade = NewTrade {
position_id: position.id,
contract_symbol: position.contract_symbol,
trader_pubkey: trade_params.trader,
quantity: trade_params.quantity,
trader_leverage: trade_params.leverage,
trader_direction: trade_params.direction,
average_price: trade_params.average_price,
order_matching_fee,
trader_realized_pnl_sat: None,
};

db::trades::insert(conn, new_trade)?;

Ok(())
}

/// Complete a DLC protocol that resizes a position, by updating several database tables in a
/// single transaction.
fn finish_resize_position_dlc_protocol(
&self,
conn: &mut PgConnection,
trade_params: &TradeParams,
Expand All @@ -469,7 +553,7 @@ impl DlcProtocolExecutor {
let position = db::positions::Position::update_position_state(
conn,
trade_params.trader.to_string(),
vec![PositionState::Proposed, PositionState::Resizing],
vec![PositionState::Resizing],
PositionState::Open,
)?;

Expand Down
9 changes: 5 additions & 4 deletions coordinator/src/node/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ impl Node {
let dlc_protocol = db::dlc_protocols::get_dlc_protocol(&mut conn, protocol_id)?;

match dlc_protocol.protocol_type {
DlcProtocolType::Open { .. } => {
DlcProtocolType::OpenChannel { .. } => {
db::dlc_channels::set_dlc_channel_open(
&mut conn,
&protocol_id,
Expand All @@ -147,10 +147,11 @@ impl Node {
trader_funding,
)?;
}
DlcProtocolType::Renew { .. }
DlcProtocolType::OpenPosition { .. }
| DlcProtocolType::Settle { .. }
| DlcProtocolType::Rollover { .. } => {
db::dlc_channels::update_channel_on_renew(
| DlcProtocolType::Rollover { .. }
| DlcProtocolType::ResizePosition { .. } => {
db::dlc_channels::update_channel(
&mut conn,
&channel.get_id(),
coordinator_reserve,
Expand Down
6 changes: 3 additions & 3 deletions coordinator/src/trade/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ impl TradeExecutor {
None,
&temporary_contract_id,
&temporary_channel_id,
DlcProtocolType::open(trade_params, protocol_id),
DlcProtocolType::open_channel(trade_params, protocol_id),
)?;

// After the DLC channel has been proposed the position can be created. This fixes
Expand Down Expand Up @@ -548,7 +548,7 @@ impl TradeExecutor {
previous_id,
&temporary_contract_id,
&channel.get_id(),
DlcProtocolType::renew(trade_params, protocol_id, None),
DlcProtocolType::open_position(trade_params, protocol_id),
)?;

// TODO(holzeis): The position should only get created after the dlc protocol has finished
Expand Down Expand Up @@ -716,7 +716,7 @@ impl TradeExecutor {
previous_id,
&temporary_contract_id,
&channel.get_id(),
DlcProtocolType::renew(trade_params, protocol_id, realized_pnl),
DlcProtocolType::resize_position(trade_params, protocol_id, realized_pnl),
)?;

db::positions::Position::set_position_to_resizing(
Expand Down

0 comments on commit a6a8c8e

Please sign in to comment.