diff --git a/coordinator/src/bin/coordinator.rs b/coordinator/src/bin/coordinator.rs index 83776cdc4..a74470607 100644 --- a/coordinator/src/bin/coordinator.rs +++ b/coordinator/src/bin/coordinator.rs @@ -226,12 +226,14 @@ async fn main() -> Result<()> { tx_price_feed.clone(), auth_users_notifier.clone(), network, + node.inner.oracle_pubkey, ); let _handle = async_match::monitor( pool.clone(), tx_user_feed.clone(), auth_users_notifier.clone(), network, + node.inner.oracle_pubkey, ); let _handle = rollover::monitor( pool.clone(), diff --git a/coordinator/src/node.rs b/coordinator/src/node.rs index 0a91a2c15..0c6c6c00c 100644 --- a/coordinator/src/node.rs +++ b/coordinator/src/node.rs @@ -294,7 +294,7 @@ impl Node { // The contract input to be used for setting up the trade between the trader and the // coordinator let event_id = format!("{contract_symbol}{maturity_time}"); - tracing::debug!(event_id, oracle=%self.inner.oracle_pubkey, "Proposing dlc channel"); + tracing::debug!(event_id, oracle=%trade_params.filled_with.oracle_pk, "Proposing dlc channel"); let contract_input = ContractInput { offer_collateral: margin_coordinator - fee, // the accepting party has do bring in additional margin for the fees @@ -303,7 +303,7 @@ impl Node { contract_infos: vec![ContractInputInfo { contract_descriptor, oracles: OracleInput { - public_keys: vec![self.inner.oracle_pubkey], + public_keys: vec![trade_params.filled_with.oracle_pk], event_id, threshold: 1, }, diff --git a/coordinator/src/orderbook/async_match.rs b/coordinator/src/orderbook/async_match.rs index 42cb0b2b1..54c35c68f 100644 --- a/coordinator/src/orderbook/async_match.rs +++ b/coordinator/src/orderbook/async_match.rs @@ -18,7 +18,6 @@ use orderbook_commons::Matches; use orderbook_commons::Message; use orderbook_commons::OrderReason; use orderbook_commons::OrderState; -use std::str::FromStr; use time::OffsetDateTime; use tokio::sync::broadcast; use tokio::sync::mpsc; @@ -28,6 +27,7 @@ pub fn monitor( tx_user_feed: broadcast::Sender, notifier: mpsc::Sender, network: Network, + oracle_pk: XOnlyPublicKey, ) -> RemoteHandle> { let mut user_feed = tx_user_feed.subscribe(); let (fut, remote_handle) = async move { @@ -37,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, network).await { + if let Err(e) = process_pending_match(&mut conn, notifier, new_user_msg.new_user, network, oracle_pk).await { tracing::error!("Failed to process pending match. Error: {e:#}"); } } @@ -57,12 +57,13 @@ async fn process_pending_match( notifier: mpsc::Sender, trader_id: PublicKey, network: Network, + oracle_pk: XOnlyPublicKey, ) -> 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, network)?; + let filled_with = get_filled_with_from_matches(matches, network, oracle_pk)?; let message = match order.order_reason { OrderReason::Manual => Message::Match(filled_with), @@ -85,7 +86,11 @@ async fn process_pending_match( Ok(()) } -fn get_filled_with_from_matches(matches: Vec, network: Network) -> Result { +fn get_filled_with_from_matches( + matches: Vec, + network: Network, + oracle_pk: XOnlyPublicKey, +) -> Result { ensure!( !matches.is_empty(), "Need at least one matches record to construct a FilledWith" @@ -95,10 +100,6 @@ fn get_filled_with_from_matches(matches: Vec, network: Network) -> Resu .first() .expect("to have at least one match") .order_id; - let oracle_pk = XOnlyPublicKey::from_str( - "16f88cf7d21e6c0f46bcbc983a4e3b19726c6c98858cc31c83551a88fde171c0", - ) - .expect("To be a valid pubkey"); let expiry_timestamp = coordinator_commons::calculate_next_expiry(OffsetDateTime::now_utc(), network); diff --git a/coordinator/src/orderbook/trading.rs b/coordinator/src/orderbook/trading.rs index 81b294c42..f45ffe83e 100644 --- a/coordinator/src/orderbook/trading.rs +++ b/coordinator/src/orderbook/trading.rs @@ -25,7 +25,6 @@ use orderbook_commons::OrderState; use orderbook_commons::OrderType; use rust_decimal::Decimal; use std::cmp::Ordering; -use std::str::FromStr; use thiserror::Error; use time::OffsetDateTime; use tokio::sync::broadcast; @@ -88,6 +87,7 @@ pub fn start( tx_price_feed: broadcast::Sender, notifier: mpsc::Sender, network: Network, + oracle_pk: XOnlyPublicKey, ) -> (RemoteHandle>, mpsc::Sender) { let (sender, mut receiver) = mpsc::channel::(NEW_ORDERS_BUFFER_SIZE); @@ -106,6 +106,7 @@ pub fn start( new_order, new_order_msg.order_reason, network, + oracle_pk, ) .await; if let Err(e) = new_order_msg.sender.send(result).await { @@ -138,6 +139,7 @@ async fn process_new_order( new_order: NewOrder, order_reason: OrderReason, network: Network, + oracle_pk: XOnlyPublicKey, ) -> Result { tracing::info!(trader_id=%new_order.trader_id, "Received a new {:?} order", new_order.order_type); @@ -183,26 +185,27 @@ async fn process_new_order( true, )?; - 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 - // has been a match or not, that's the reason why we also - // have to set the order to failed here. But actually we - // could keep the order until either expired or a - // match has been found and then update the state correspondingly. - - orders::set_order_state(conn, order.id, OrderState::Failed)?; - bail!(TradingError::NoMatchFound(format!( - "Could not match order {}", - order.id - ))); - } - Err(e) => { - orders::set_order_state(conn, order.id, OrderState::Failed)?; - bail!("Failed to match order. Error {e:#}") - } - }; + let matched_orders = + match match_order(&order, opposite_direction_orders, network, oracle_pk) { + Ok(Some(matched_orders)) => matched_orders, + Ok(None) => { + // TODO(holzeis): Currently we still respond to the user immediately if there + // has been a match or not, that's the reason why we also + // have to set the order to failed here. But actually we + // could keep the order until either expired or a + // match has been found and then update the state correspondingly. + + orders::set_order_state(conn, order.id, OrderState::Failed)?; + bail!(TradingError::NoMatchFound(format!( + "Could not match order {}", + order.id + ))); + } + Err(e) => { + orders::set_order_state(conn, order.id, OrderState::Failed)?; + bail!("Failed to match order. Error {e:#}") + } + }; tracing::info!(trader_id=%order.trader_id, order_id=%order.id, "Found a match with {} makers for new order.", matched_orders.taker_match.filled_with.matches.len()); @@ -277,6 +280,7 @@ fn match_order( order: &Order, opposite_direction_orders: Vec, network: Network, + oracle_pk: XOnlyPublicKey, ) -> Result> { if order.order_type == OrderType::Limit { // we don't match limit and limit at the moment @@ -315,12 +319,6 @@ fn match_order( 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( - "16f88cf7d21e6c0f46bcbc983a4e3b19726c6c98858cc31c83551a88fde171c0", - ) - .expect("To be a valid pubkey"); - let matches = matched_orders .iter() .map(|maker_order| { @@ -404,6 +402,7 @@ pub mod tests { use crate::orderbook::trading::sort_orders; use bitcoin::secp256k1::PublicKey; use bitcoin::Network; + use bitcoin::XOnlyPublicKey; use orderbook_commons::Order; use orderbook_commons::OrderReason; use orderbook_commons::OrderState; @@ -583,9 +582,14 @@ pub mod tests { stable: false, }; - let matched_orders = match_order(&order, all_orders, Network::Bitcoin) - .unwrap() - .unwrap(); + let matched_orders = match_order( + &order, + all_orders, + Network::Bitcoin, + get_oracle_public_key(), + ) + .unwrap() + .unwrap(); assert_eq!(matched_orders.makers_matches.len(), 1); let maker_matches = matched_orders @@ -660,7 +664,13 @@ pub mod tests { stable: false, }; - assert!(match_order(&order, all_orders, Network::Bitcoin).is_err()); + assert!(match_order( + &order, + all_orders, + Network::Bitcoin, + get_oracle_public_key() + ) + .is_err()); } #[test] @@ -711,8 +721,19 @@ pub mod tests { stable: false, }; - let matched_orders = match_order(&order, all_orders, Network::Bitcoin).unwrap(); + let matched_orders = match_order( + &order, + all_orders, + Network::Bitcoin, + get_oracle_public_key(), + ) + .unwrap(); assert!(matched_orders.is_none()); } + + fn get_oracle_public_key() -> XOnlyPublicKey { + XOnlyPublicKey::from_str("16f88cf7d21e6c0f46bcbc983a4e3b19726c6c98858cc31c83551a88fde171c0") + .unwrap() + } }