Skip to content

Commit

Permalink
Merge pull request #2125 from get10101/chore/add-rollover-to-protocol…
Browse files Browse the repository at this point in the history
…s-table

chore(dlc_protocol): Track rollovers in dlc protocol table
  • Loading branch information
holzeis authored Mar 4, 2024
2 parents 2c3b1fa + b2b0e3f commit 87c8c0f
Show file tree
Hide file tree
Showing 14 changed files with 525 additions and 262 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

ALTER TABLE dlc_protocols DROP COLUMN IF EXISTS "protocol_type";

DROP TYPE IF EXISTS "Protocol_Type_Type";
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

CREATE TYPE "Protocol_Type_Type" AS ENUM ('open', 'renew', 'settle', 'close', 'force-close', 'rollover');

ALTER TABLE dlc_protocols ADD COLUMN "protocol_type" "Protocol_Type_Type" NOT NULL DEFAULT 'open';
32 changes: 31 additions & 1 deletion coordinator/src/db/custom_types.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::db::channels::ChannelState;
use crate::db::dlc_messages::MessageType;
use crate::db::dlc_protocols::DlcProtocolState;
use crate::db::dlc_protocols::DlcProtocolType;
use crate::db::polls::PollType;
use crate::db::positions::ContractSymbol;
use crate::db::positions::PositionState;
Expand All @@ -11,6 +12,7 @@ use crate::schema::sql_types::MessageTypeType;
use crate::schema::sql_types::PollTypeType;
use crate::schema::sql_types::PositionStateType;
use crate::schema::sql_types::ProtocolStateType;
use crate::schema::sql_types::ProtocolTypeType;
use diesel::deserialize;
use diesel::deserialize::FromSql;
use diesel::pg::Pg;
Expand Down Expand Up @@ -199,7 +201,35 @@ impl FromSql<ProtocolStateType, Pg> for DlcProtocolState {
b"Pending" => Ok(DlcProtocolState::Pending),
b"Success" => Ok(DlcProtocolState::Success),
b"Failed" => Ok(DlcProtocolState::Failed),
_ => Err("Unrecognized enum variant for ContractTransactionType".into()),
_ => Err("Unrecognized enum variant for ProtocolStateType".into()),
}
}
}

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::Settle => out.write_all(b"settle")?,
DlcProtocolType::Renew => out.write_all(b"renew")?,
DlcProtocolType::Rollover => out.write_all(b"rollover")?,
DlcProtocolType::Close => out.write_all(b"close")?,
DlcProtocolType::ForceClose => out.write_all(b"force-close")?,
}
Ok(IsNull::No)
}
}

impl FromSql<ProtocolTypeType, Pg> for DlcProtocolType {
fn from_sql(bytes: PgValue<'_>) -> deserialize::Result<Self> {
match bytes.as_bytes() {
b"open" => Ok(DlcProtocolType::Open),
b"settle" => Ok(DlcProtocolType::Settle),
b"renew" => Ok(DlcProtocolType::Renew),
b"rollover" => Ok(DlcProtocolType::Rollover),
b"close" => Ok(DlcProtocolType::Close),
b"force-close" => Ok(DlcProtocolType::ForceClose),
_ => Err("Unrecognized enum variant for ProtocolTypeType".into()),
}
}
}
97 changes: 78 additions & 19 deletions coordinator/src/db/dlc_protocols.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::db;
use crate::dlc_protocol;
use crate::dlc_protocol::ProtocolId;
use crate::schema::dlc_protocols;
use crate::schema::sql_types::ProtocolStateType;
use crate::schema::sql_types::ProtocolTypeType;
use bitcoin::secp256k1::PublicKey;
use diesel::query_builder::QueryId;
use diesel::AsExpression;
Expand Down Expand Up @@ -37,6 +39,26 @@ impl QueryId for ProtocolStateType {
}
}

#[derive(Debug, Clone, Copy, PartialEq, FromSqlRow, AsExpression, Eq, Hash)]
#[diesel(sql_type = ProtocolTypeType)]
pub(crate) enum DlcProtocolType {
Open,
Renew,
Settle,
Close,
ForceClose,
Rollover,
}

impl QueryId for ProtocolTypeType {
type QueryId = ProtocolTypeType;
const HAS_STATIC_QUERY_ID: bool = false;

fn query_id() -> Option<TypeId> {
None
}
}

#[derive(Queryable, Debug)]
#[diesel(table_name = protocols)]
#[allow(dead_code)] // We have to allow dead code here because diesel needs the fields to be able to derive queryable.
Expand All @@ -49,17 +71,52 @@ pub(crate) struct DlcProtocol {
pub protocol_state: DlcProtocolState,
pub trader_pubkey: String,
pub timestamp: OffsetDateTime,
pub protocol_type: DlcProtocolType,
}

pub(crate) fn get_dlc_protocol(
conn: &mut PgConnection,
protocol_id: ProtocolId,
) -> QueryResult<dlc_protocol::DlcProtocol> {
let contract_transaction: DlcProtocol = dlc_protocols::table
let dlc_protocol: DlcProtocol = dlc_protocols::table
.filter(dlc_protocols::protocol_id.eq(protocol_id.to_uuid()))
.first(conn)?;

Ok(dlc_protocol::DlcProtocol::from(contract_transaction))
let protocol_type = match dlc_protocol.protocol_type {
DlcProtocolType::Open => {
let trade_params = db::trade_params::get(conn, protocol_id)?;
dlc_protocol::DlcProtocolType::Open { trade_params }
}
DlcProtocolType::Renew => {
let trade_params = db::trade_params::get(conn, protocol_id)?;
dlc_protocol::DlcProtocolType::Renew { trade_params }
}
DlcProtocolType::Settle => {
let trade_params = db::trade_params::get(conn, protocol_id)?;
dlc_protocol::DlcProtocolType::Settle { trade_params }
}
DlcProtocolType::Close => dlc_protocol::DlcProtocolType::Close {
trader: PublicKey::from_str(&dlc_protocol.trader_pubkey).expect("valid public key"),
},
DlcProtocolType::ForceClose => dlc_protocol::DlcProtocolType::ForceClose {
trader: PublicKey::from_str(&dlc_protocol.trader_pubkey).expect("valid public key"),
},
DlcProtocolType::Rollover => dlc_protocol::DlcProtocolType::Rollover {
trader: PublicKey::from_str(&dlc_protocol.trader_pubkey).expect("valid public key"),
},
};

let protocol = dlc_protocol::DlcProtocol {
id: dlc_protocol.protocol_id.into(),
timestamp: dlc_protocol.timestamp,
channel_id: DlcChannelId::from_hex(&dlc_protocol.channel_id).expect("valid dlc channel id"),
contract_id: ContractId::from_hex(&dlc_protocol.contract_id).expect("valid contract id"),
trader: PublicKey::from_str(&dlc_protocol.trader_pubkey).expect("valid public key"),
protocol_state: dlc_protocol.protocol_state.into(),
protocol_type,
};

Ok(protocol)
}

pub(crate) fn set_dlc_protocol_state_to_failed(
Expand All @@ -81,8 +138,8 @@ pub(crate) fn set_dlc_protocol_state_to_failed(
pub(crate) fn set_dlc_protocol_state_to_success(
conn: &mut PgConnection,
protocol_id: ProtocolId,
contract_id: ContractId,
channel_id: DlcChannelId,
contract_id: &ContractId,
channel_id: &DlcChannelId,
) -> QueryResult<()> {
let affected_rows = diesel::update(dlc_protocols::table)
.filter(dlc_protocols::protocol_id.eq(protocol_id.to_uuid()))
Expand All @@ -104,8 +161,9 @@ pub(crate) fn create(
conn: &mut PgConnection,
protocol_id: ProtocolId,
previous_protocol_id: Option<ProtocolId>,
contract_id: ContractId,
channel_id: DlcChannelId,
contract_id: &ContractId,
channel_id: &DlcChannelId,
protocol_type: dlc_protocol::DlcProtocolType,
trader: &PublicKey,
) -> QueryResult<()> {
let affected_rows = diesel::insert_into(dlc_protocols::table)
Expand All @@ -117,6 +175,7 @@ pub(crate) fn create(
dlc_protocols::protocol_state.eq(DlcProtocolState::Pending),
dlc_protocols::trader_pubkey.eq(trader.to_string()),
dlc_protocols::timestamp.eq(OffsetDateTime::now_utc()),
dlc_protocols::protocol_type.eq(DlcProtocolType::from(protocol_type)),
))
.execute(conn)?;

Expand All @@ -127,19 +186,6 @@ pub(crate) fn create(
Ok(())
}

impl From<DlcProtocol> for dlc_protocol::DlcProtocol {
fn from(value: DlcProtocol) -> Self {
dlc_protocol::DlcProtocol {
id: value.protocol_id.into(),
timestamp: value.timestamp,
channel_id: DlcChannelId::from_hex(&value.channel_id).expect("valid dlc channel id"),
contract_id: ContractId::from_hex(&value.contract_id).expect("valid contract id"),
trader: PublicKey::from_str(&value.trader_pubkey).expect("valid public key"),
protocol_state: value.protocol_state.into(),
}
}
}

impl From<dlc_protocol::DlcProtocolState> for DlcProtocolState {
fn from(value: dlc_protocol::DlcProtocolState) -> Self {
match value {
Expand All @@ -159,3 +205,16 @@ 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::Settle { .. } => DlcProtocolType::Settle,
dlc_protocol::DlcProtocolType::Close { .. } => DlcProtocolType::Close,
dlc_protocol::DlcProtocolType::ForceClose { .. } => DlcProtocolType::ForceClose,
dlc_protocol::DlcProtocolType::Rollover { .. } => DlcProtocolType::Rollover,
}
}
}
10 changes: 3 additions & 7 deletions coordinator/src/db/positions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@ impl Position {
conn: &mut PgConnection,
trader_pubkey: String,
temporary_contract_id: ContractId,
) -> Result<()> {
let affected_rows = diesel::update(positions::table)
) -> QueryResult<usize> {
diesel::update(positions::table)
.filter(positions::trader_pubkey.eq(trader_pubkey))
.filter(
positions::position_state
Expand All @@ -313,11 +313,7 @@ impl Position {
positions::temporary_contract_id.eq(hex::encode(temporary_contract_id)),
positions::update_timestamp.eq(OffsetDateTime::now_utc()),
))
.execute(conn)?;

ensure!(affected_rows > 0, "Could not set position to open");

Ok(())
.execute(conn)
}

pub fn update_unrealized_pnl(conn: &mut PgConnection, id: i32, pnl: i64) -> Result<()> {
Expand Down
12 changes: 3 additions & 9 deletions coordinator/src/db/trade_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use diesel::QueryDsl;
use diesel::QueryResult;
use diesel::Queryable;
use diesel::RunQueryDsl;
use rust_decimal::prelude::ToPrimitive;
use std::str::FromStr;
use uuid::Uuid;

Expand All @@ -29,21 +28,16 @@ pub(crate) struct TradeParams {
pub(crate) fn insert(
conn: &mut PgConnection,
protocol_id: ProtocolId,
params: &commons::TradeParams,
params: &dlc_protocol::TradeParams,
) -> QueryResult<()> {
let average_price = params
.average_execution_price()
.to_f32()
.expect("to fit into f32");

let affected_rows = diesel::insert_into(trade_params::table)
.values(&(
trade_params::protocol_id.eq(protocol_id.to_uuid()),
trade_params::quantity.eq(params.quantity),
trade_params::leverage.eq(params.leverage),
trade_params::trader_pubkey.eq(params.pubkey.to_string()),
trade_params::trader_pubkey.eq(params.trader.to_string()),
trade_params::direction.eq(Direction::from(params.direction)),
trade_params::average_price.eq(average_price),
trade_params::average_price.eq(params.average_price),
))
.execute(conn)?;

Expand Down
Loading

0 comments on commit 87c8c0f

Please sign in to comment.