Skip to content

Commit

Permalink
Merge pull request #1327 from get10101/chore/shorten-expiry-and-rollo…
Browse files Browse the repository at this point in the history
…ver-cycles-for-regtest

chore: Shorten expiry and rollover cycles for regtest
  • Loading branch information
holzeis authored Sep 19, 2023
2 parents b543f43 + d5661fa commit 0c9de41
Show file tree
Hide file tree
Showing 11 changed files with 198 additions and 83 deletions.
17 changes: 13 additions & 4 deletions coordinator/src/bin/coordinator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,20 @@ async fn main() -> Result<()> {

let (_handle, notifier) = notification::start(tx_user_feed.clone());

let (_handle, trading_sender) =
trading::start(pool.clone(), tx_price_feed.clone(), notifier.clone());
let (_handle, trading_sender) = trading::start(
pool.clone(),
tx_price_feed.clone(),
notifier.clone(),
network,
);

let _handle = async_match::monitor(pool.clone(), tx_user_feed.clone(), notifier.clone());
let _handle = rollover::monitor(pool.clone(), tx_user_feed.clone(), notifier);
let _handle = async_match::monitor(
pool.clone(),
tx_user_feed.clone(),
notifier.clone(),
network,
);
let _handle = rollover::monitor(pool.clone(), tx_user_feed.clone(), notifier, network);

tokio::spawn({
let node = node.clone();
Expand Down
54 changes: 34 additions & 20 deletions coordinator/src/node/rollover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use anyhow::Context;
use anyhow::Result;
use bitcoin::hashes::hex::ToHex;
use bitcoin::secp256k1::PublicKey;
use bitcoin::Network;
use bitcoin::XOnlyPublicKey;
use diesel::r2d2::ConnectionManager;
use diesel::r2d2::Pool;
Expand Down Expand Up @@ -37,12 +38,14 @@ struct Rollover {
contract_symbol: ContractSymbol,
oracle_pk: XOnlyPublicKey,
contract_tx_fee_rate: u64,
network: Network,
}

pub fn monitor(
pool: Pool<ConnectionManager<PgConnection>>,
tx_user_feed: broadcast::Sender<NewUserMessage>,
notifier: mpsc::Sender<Notification>,
network: Network,
) -> RemoteHandle<Result<()>> {
let mut user_feed = tx_user_feed.subscribe();
let (fut, remote_handle) = async move {
Expand All @@ -51,9 +54,13 @@ pub fn monitor(
let mut conn = pool.get()?;
let notifier = notifier.clone();
async move {
if let Err(e) =
check_if_eligible_for_rollover(&mut conn, notifier, new_user_msg.new_user)
.await
if let Err(e) = check_if_eligible_for_rollover(
&mut conn,
notifier,
new_user_msg.new_user,
network,
)
.await
{
tracing::error!("Failed to check if eligible for rollover. Error: {e:#}");
}
Expand All @@ -73,15 +80,17 @@ async fn check_if_eligible_for_rollover(
conn: &mut PgConnection,
notifier: mpsc::Sender<Notification>,
trader_id: PublicKey,
network: Network,
) -> Result<()> {
tracing::debug!(%trader_id, "Checking if the users positions is eligible for rollover");
if let Some(position) =
positions::Position::get_open_position_by_trader(conn, trader_id.to_string())?
{
if coordinator_commons::is_in_rollover_weekend(OffsetDateTime::now_utc())
if coordinator_commons::is_eligible_for_rollover(OffsetDateTime::now_utc(), network)
&& !position.is_expired()
{
let next_expiry = coordinator_commons::calculate_next_expiry(OffsetDateTime::now_utc());
let next_expiry =
coordinator_commons::calculate_next_expiry(OffsetDateTime::now_utc(), network);
if position.expiry_timestamp == next_expiry {
tracing::trace!(%trader_id, position_id=position.id, "Position has already been rolled over");
return Ok(());
Expand All @@ -103,7 +112,7 @@ async fn check_if_eligible_for_rollover(
}

impl Rollover {
pub fn new(contract: Contract) -> Result<Self> {
pub fn new(contract: Contract, network: Network) -> Result<Self> {
let contract = match contract {
Contract::Confirmed(contract) => contract,
_ => bail!(
Expand Down Expand Up @@ -145,6 +154,7 @@ impl Rollover {
&oracle_announcement.oracle_event.event_id[..6],
)?,
contract_tx_fee_rate,
network,
})
}

Expand All @@ -155,15 +165,19 @@ impl Rollover {

/// Calculates the maturity time based on the current expiry timestamp.
pub fn maturity_time(&self) -> OffsetDateTime {
coordinator_commons::calculate_next_expiry(self.expiry_timestamp)
coordinator_commons::calculate_next_expiry(self.expiry_timestamp, self.network)
}
}

impl Node {
/// Initiates the rollover protocol with the app.
pub async fn propose_rollover(&self, dlc_channel_id: ChannelId) -> Result<()> {
pub async fn propose_rollover(
&self,
dlc_channel_id: ChannelId,
network: Network,
) -> Result<()> {
let contract = self.inner.get_contract_by_dlc_channel_id(dlc_channel_id)?;
let rollover = Rollover::new(contract)?;
let rollover = Rollover::new(contract, network)?;

tracing::debug!(?rollover, "Rollover dlc channel");

Expand Down Expand Up @@ -245,7 +259,7 @@ pub mod tests {
fn test_new_rollover_from_signed_contract() {
let expiry_timestamp = OffsetDateTime::now_utc().unix_timestamp() + 10_000;
let contract = dummy_signed_contract(200, 100, expiry_timestamp as u32);
let rollover = Rollover::new(Contract::Confirmed(contract)).unwrap();
let rollover = Rollover::new(Contract::Confirmed(contract), Network::Bitcoin).unwrap();
assert_eq!(rollover.contract_symbol, ContractSymbol::BtcUsd);
assert_eq!(rollover.margin_trader, 100);
assert_eq!(rollover.margin_coordinator, 200);
Expand All @@ -254,11 +268,10 @@ pub mod tests {
#[test]
fn test_new_rollover_from_other_contract() {
let expiry_timestamp = OffsetDateTime::now_utc().unix_timestamp() + 10_000;
assert!(Rollover::new(Contract::Offered(dummy_offered_contract(
200,
100,
expiry_timestamp as u32
)))
assert!(Rollover::new(
Contract::Offered(dummy_offered_contract(200, 100, expiry_timestamp as u32)),
Network::Bitcoin
)
.is_err())
}

Expand All @@ -275,6 +288,7 @@ pub mod tests {
contract_symbol: ContractSymbol::BtcUsd,
oracle_pk: XOnlyPublicKey::from(dummy_pubkey()),
contract_tx_fee_rate: 1,
network: Network::Bitcoin,
};
let event_id = rollover.event_id();

Expand All @@ -296,6 +310,7 @@ pub mod tests {
contract_symbol: ContractSymbol::BtcUsd,
oracle_pk: XOnlyPublicKey::from(dummy_pubkey()),
contract_tx_fee_rate: 1,
network: Network::Bitcoin,
};

let contract_input: ContractInput = rollover.into();
Expand All @@ -307,11 +322,10 @@ pub mod tests {
#[test]
fn test_rollover_expired_position() {
let expiry_timestamp = OffsetDateTime::now_utc().unix_timestamp() - 10_000;
assert!(Rollover::new(Contract::Confirmed(dummy_signed_contract(
200,
100,
expiry_timestamp as u32
)))
assert!(Rollover::new(
Contract::Confirmed(dummy_signed_contract(200, 100, expiry_timestamp as u32)),
Network::Bitcoin
)
.is_err())
}

Expand Down
12 changes: 8 additions & 4 deletions coordinator/src/orderbook/async_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::orderbook::db::orders;
use anyhow::ensure;
use anyhow::Result;
use bitcoin::secp256k1::PublicKey;
use bitcoin::Network;
use bitcoin::XOnlyPublicKey;
use diesel::r2d2::ConnectionManager;
use diesel::r2d2::Pool;
Expand All @@ -26,6 +27,7 @@ pub fn monitor(
pool: Pool<ConnectionManager<PgConnection>>,
tx_user_feed: broadcast::Sender<NewUserMessage>,
notifier: mpsc::Sender<Notification>,
network: Network,
) -> RemoteHandle<Result<()>> {
let mut user_feed = tx_user_feed.subscribe();
let (fut, remote_handle) = async move {
Expand All @@ -35,7 +37,7 @@ pub fn monitor(
let notifier = notifier.clone();
async move {
tracing::debug!(trader_id=%new_user_msg.new_user, "Checking if the user needs to be notified about pending matches");
if let Err(e) = process_pending_match(&mut conn, notifier, new_user_msg.new_user).await {
if let Err(e) = process_pending_match(&mut conn, notifier, new_user_msg.new_user, network).await {
tracing::error!("Failed to process pending match. Error: {e:#}");
}
}
Expand All @@ -54,12 +56,13 @@ async fn process_pending_match(
conn: &mut PgConnection,
notifier: mpsc::Sender<Notification>,
trader_id: PublicKey,
network: Network,
) -> Result<()> {
if let Some(order) = orders::get_by_trader_id_and_state(conn, trader_id, OrderState::Matched)? {
tracing::debug!(%trader_id, order_id=%order.id, "Notifying trader about pending match");

let matches = matches::get_matches_by_order_id(conn, order.id)?;
let filled_with = get_filled_with_from_matches(matches)?;
let filled_with = get_filled_with_from_matches(matches, network)?;

let message = match order.order_reason {
OrderReason::Manual => Message::Match(filled_with),
Expand All @@ -75,7 +78,7 @@ async fn process_pending_match(
Ok(())
}

fn get_filled_with_from_matches(matches: Vec<Matches>) -> Result<FilledWith> {
fn get_filled_with_from_matches(matches: Vec<Matches>, network: Network) -> Result<FilledWith> {
ensure!(
!matches.is_empty(),
"Need at least one matches record to construct a FilledWith"
Expand All @@ -90,7 +93,8 @@ fn get_filled_with_from_matches(matches: Vec<Matches>) -> Result<FilledWith> {
)
.expect("To be a valid pubkey");

let expiry_timestamp = coordinator_commons::calculate_next_expiry(OffsetDateTime::now_utc());
let expiry_timestamp =
coordinator_commons::calculate_next_expiry(OffsetDateTime::now_utc(), network);

Ok(FilledWith {
order_id,
Expand Down
19 changes: 14 additions & 5 deletions coordinator/src/orderbook/trading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use anyhow::bail;
use anyhow::Result;
use autometrics::autometrics;
use bitcoin::secp256k1::PublicKey;
use bitcoin::Network;
use bitcoin::XOnlyPublicKey;
use coordinator_commons::TradeParams;
use diesel::r2d2::ConnectionManager;
Expand Down Expand Up @@ -85,6 +86,7 @@ pub fn start(
pool: Pool<ConnectionManager<PgConnection>>,
tx_price_feed: broadcast::Sender<Message>,
notifier: mpsc::Sender<Notification>,
network: Network,
) -> (RemoteHandle<Result<()>>, mpsc::Sender<NewOrderMessage>) {
let (sender, mut receiver) = mpsc::channel::<NewOrderMessage>(NEW_ORDERS_BUFFER_SIZE);

Expand All @@ -102,6 +104,7 @@ pub fn start(
tx_price_feed,
new_order,
new_order_msg.order_reason,
network,
)
.await;
if let Err(e) = new_order_msg.sender.send(result).await {
Expand Down Expand Up @@ -133,6 +136,7 @@ async fn process_new_order(
tx_price_feed: broadcast::Sender<Message>,
new_order: NewOrder,
order_reason: OrderReason,
network: Network,
) -> Result<Order> {
tracing::info!(trader_id=%new_order.trader_id, "Received a new {:?} order", new_order.order_type);

Expand Down Expand Up @@ -173,7 +177,7 @@ async fn process_new_order(
true,
)?;

let matched_orders = match match_order(&order, opposite_direction_orders) {
let matched_orders = match match_order(&order, opposite_direction_orders, network) {
Ok(Some(matched_orders)) => matched_orders,
Ok(None) => {
// TODO(holzeis): Currently we still respond to the user immediately if there
Expand Down Expand Up @@ -259,6 +263,7 @@ async fn process_new_order(
fn match_order(
order: &Order,
opposite_direction_orders: Vec<Order>,
network: Network,
) -> Result<Option<MatchParams>> {
if order.order_type == OrderType::Limit {
// we don't match limit and limit at the moment
Expand Down Expand Up @@ -294,7 +299,8 @@ fn match_order(
return Ok(None);
}

let expiry_timestamp = coordinator_commons::calculate_next_expiry(OffsetDateTime::now_utc());
let expiry_timestamp =
coordinator_commons::calculate_next_expiry(OffsetDateTime::now_utc(), network);

// For now we hardcode the oracle pubkey here
let oracle_pk = XOnlyPublicKey::from_str(
Expand Down Expand Up @@ -384,6 +390,7 @@ pub mod tests {
use crate::orderbook::trading::match_order;
use crate::orderbook::trading::sort_orders;
use bitcoin::secp256k1::PublicKey;
use bitcoin::Network;
use orderbook_commons::Order;
use orderbook_commons::OrderReason;
use orderbook_commons::OrderState;
Expand Down Expand Up @@ -561,7 +568,9 @@ pub mod tests {
order_reason: OrderReason::Manual,
};

let matched_orders = match_order(&order, all_orders).unwrap().unwrap();
let matched_orders = match_order(&order, all_orders, Network::Bitcoin)
.unwrap()
.unwrap();

assert_eq!(matched_orders.makers_matches.len(), 1);
let maker_matches = matched_orders
Expand Down Expand Up @@ -635,7 +644,7 @@ pub mod tests {
order_reason: OrderReason::Manual,
};

assert!(match_order(&order, all_orders).is_err());
assert!(match_order(&order, all_orders, Network::Bitcoin).is_err());
}

#[test]
Expand Down Expand Up @@ -685,7 +694,7 @@ pub mod tests {
order_reason: OrderReason::Manual,
};

let matched_orders = match_order(&order, all_orders).unwrap();
let matched_orders = match_order(&order, all_orders, Network::Bitcoin).unwrap();

assert!(matched_orders.is_none());
}
Expand Down
2 changes: 1 addition & 1 deletion coordinator/src/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ pub async fn rollover(

state
.node
.propose_rollover(dlc_channel_id)
.propose_rollover(dlc_channel_id, state.node.inner.network)
.await
.map_err(|e| {
AppError::InternalServerError(format!(
Expand Down
Loading

0 comments on commit 0c9de41

Please sign in to comment.