Browse Source

Merge pull request #205 from comit-network/offer-with-oracle-event-id

Offer with oracle event
upload-correct-windows-binary
Daniel Karzel 3 years ago
committed by GitHub
parent
commit
6e213ea809
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      daemon/migrations/20210903050345_create_cfd_and_order_tables.sql
  2. 146
      daemon/sqlx-data.json
  3. 46
      daemon/src/db.rs
  4. 81
      daemon/src/maker_cfd.rs
  5. 3
      daemon/src/model.rs
  6. 29
      daemon/src/model/cfd.rs
  7. 14
      daemon/src/oracle.rs
  8. 17
      daemon/src/routes_maker.rs
  9. 46
      daemon/src/taker_cfd.rs

3
daemon/migrations/20210903050345_create_cfd_and_order_tables.sql

@ -12,7 +12,8 @@ create table if not exists orders
liquidation_price text not null,
creation_timestamp text not null,
term text not null,
origin text not null
origin text not null,
oracle_event_id text not null
);
create unique index if not exists orders_uuid

146
daemon/sqlx-data.json

@ -1,35 +1,7 @@
{
"db": "SQLite",
"3ec696a1077ae52f21230ac33b9083ae3420698ff4d6bb1bba2d71ad518daf85": {
"query": "\n insert into orders (\n uuid,\n trading_pair,\n position,\n initial_price,\n min_quantity,\n max_quantity,\n leverage,\n liquidation_price,\n creation_timestamp,\n term,\n origin\n ) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 11
},
"nullable": []
}
},
"50abbb297394739ec9d85917f8c32aa8bcfa0bfe140b24e9eeda4ce8d30d4f8d": {
"query": "\n select\n state\n from cfd_states\n where cfd_id = ?\n order by id desc\n limit 1;\n ",
"describe": {
"columns": [
{
"name": "state",
"ordinal": 0,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false
]
}
},
"57c0eb6669321997352d87372431788aa039dd1898ca0b11ba4600f743ff4d93": {
"query": "\n select\n cfds.id as cfd_id,\n orders.uuid as order_id,\n orders.initial_price as price,\n orders.min_quantity as min_quantity,\n orders.max_quantity as max_quantity,\n orders.leverage as leverage,\n orders.trading_pair as trading_pair,\n orders.position as position,\n orders.origin as origin,\n orders.liquidation_price as liquidation_price,\n orders.creation_timestamp as creation_timestamp,\n orders.term as term,\n cfds.quantity_usd as quantity_usd,\n cfd_states.state as state\n from cfds as cfds\n inner join orders as orders on cfds.order_id = orders.id\n inner join cfd_states as cfd_states on cfd_states.cfd_id = cfds.id\n where cfd_states.state in (\n select\n state\n from cfd_states\n where cfd_id = cfds.id\n order by id desc\n limit 1\n )\n ",
"41fb3bea22bde82a79aee6096d579a16494a20cfcfb2e8cfffe0a56073460bbf": {
"query": "\n select\n cfds.id as cfd_id,\n orders.uuid as order_id,\n orders.initial_price as price,\n orders.min_quantity as min_quantity,\n orders.max_quantity as max_quantity,\n orders.leverage as leverage,\n orders.trading_pair as trading_pair,\n orders.position as position,\n orders.origin as origin,\n orders.liquidation_price as liquidation_price,\n orders.creation_timestamp as creation_timestamp,\n orders.term as term,\n orders.oracle_event_id,\n cfds.quantity_usd as quantity_usd,\n cfd_states.state as state\n from cfds as cfds\n inner join orders as orders on cfds.order_id = orders.id\n inner join cfd_states as cfd_states on cfd_states.cfd_id = cfds.id\n where cfd_states.state in (\n select\n state\n from cfd_states\n where cfd_id = cfds.id\n order by id desc\n limit 1\n )\n ",
"describe": {
"columns": [
{
@ -93,14 +65,19 @@
"type_info": "Text"
},
{
"name": "quantity_usd",
"name": "oracle_event_id",
"ordinal": 12,
"type_info": "Text"
},
{
"name": "state",
"name": "quantity_usd",
"ordinal": 13,
"type_info": "Text"
},
{
"name": "state",
"ordinal": 14,
"type_info": "Text"
}
],
"parameters": {
@ -120,12 +97,69 @@
false,
false,
false,
false,
false
]
}
},
"50abbb297394739ec9d85917f8c32aa8bcfa0bfe140b24e9eeda4ce8d30d4f8d": {
"query": "\n select\n state\n from cfd_states\n where cfd_id = ?\n order by id desc\n limit 1;\n ",
"describe": {
"columns": [
{
"name": "state",
"ordinal": 0,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false
]
}
},
"62c8df2dde7a305757a070149a7066faf15da1ef2d6c6fc4c0bd83e385e4750e": {
"query": "\n select\n cfds.id as cfd_id,\n orders.uuid as order_id,\n orders.initial_price as price,\n orders.min_quantity as min_quantity,\n orders.max_quantity as max_quantity,\n orders.leverage as leverage,\n orders.trading_pair as trading_pair,\n orders.position as position,\n orders.origin as origin,\n orders.liquidation_price as liquidation_price,\n orders.creation_timestamp as creation_timestamp,\n orders.term as term,\n cfds.quantity_usd as quantity_usd,\n cfd_states.state as state\n from cfds as cfds\n inner join orders as orders on cfds.order_id = orders.id\n inner join cfd_states as cfd_states on cfd_states.cfd_id = cfds.id\n where cfd_states.state in (\n select\n state\n from cfd_states\n where cfd_id = cfds.id\n order by id desc\n limit 1\n )\n and orders.uuid = ?\n ",
"8e7571250da58b12f5884f17656e5966957c7798ea029c701a4fc43fd613f015": {
"query": "\n select\n id\n from cfds\n where order_uuid = ?;\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Int64"
}
],
"parameters": {
"Right": 1
},
"nullable": [
true
]
}
},
"a464a1feb12abadff8bfd5b2b3b7362f3846869c0702944b21737eff8f420be5": {
"query": "\n insert into cfd_states (\n cfd_id,\n state\n ) values (?, ?);\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
}
},
"a59cf0824b5e4191c94c229086ce464d1b8084f65a6fafb165d27ce6df5b815b": {
"query": "\n insert into orders (\n uuid,\n trading_pair,\n position,\n initial_price,\n min_quantity,\n max_quantity,\n leverage,\n liquidation_price,\n creation_timestamp,\n term,\n origin,\n oracle_event_id\n ) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 12
},
"nullable": []
}
},
"c404a4eebb7118fd4e716fe4155e011a52e12a3594b698ca4f0662674cd067f8": {
"query": "\n select\n cfds.id as cfd_id,\n orders.uuid as order_id,\n orders.initial_price as price,\n orders.min_quantity as min_quantity,\n orders.max_quantity as max_quantity,\n orders.leverage as leverage,\n orders.trading_pair as trading_pair,\n orders.position as position,\n orders.origin as origin,\n orders.liquidation_price as liquidation_price,\n orders.creation_timestamp as creation_timestamp,\n orders.term as term,\n orders.oracle_event_id,\n cfds.quantity_usd as quantity_usd,\n cfd_states.state as state\n from cfds as cfds\n inner join orders as orders on cfds.order_id = orders.id\n inner join cfd_states as cfd_states on cfd_states.cfd_id = cfds.id\n where cfd_states.state in (\n select\n state\n from cfd_states\n where cfd_id = cfds.id\n order by id desc\n limit 1\n )\n and orders.uuid = ?\n ",
"describe": {
"columns": [
{
@ -189,14 +223,19 @@
"type_info": "Text"
},
{
"name": "quantity_usd",
"name": "oracle_event_id",
"ordinal": 12,
"type_info": "Text"
},
{
"name": "state",
"name": "quantity_usd",
"ordinal": 13,
"type_info": "Text"
},
{
"name": "state",
"ordinal": 14,
"type_info": "Text"
}
],
"parameters": {
@ -216,38 +255,11 @@
false,
false,
false,
false,
false
]
}
},
"8e7571250da58b12f5884f17656e5966957c7798ea029c701a4fc43fd613f015": {
"query": "\n select\n id\n from cfds\n where order_uuid = ?;\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Int64"
}
],
"parameters": {
"Right": 1
},
"nullable": [
true
]
}
},
"a464a1feb12abadff8bfd5b2b3b7362f3846869c0702944b21737eff8f420be5": {
"query": "\n insert into cfd_states (\n cfd_id,\n state\n ) values (?, ?);\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
}
},
"f3dce76f316212c91cb3402b0cef00f1c9adbef8519c54e9bdbd373aab946209": {
"query": "\n select * from orders where uuid = ?;\n ",
"describe": {
@ -311,6 +323,11 @@
"name": "origin",
"ordinal": 11,
"type_info": "Text"
},
{
"name": "oracle_event_id",
"ordinal": 12,
"type_info": "Text"
}
],
"parameters": {
@ -328,6 +345,7 @@
false,
false,
false,
false,
false
]
}

46
daemon/src/db.rs

@ -1,5 +1,5 @@
use crate::model::cfd::{Cfd, CfdState, Order, OrderId, Origin};
use crate::model::{Leverage, Position};
use crate::model::{Leverage, OracleEventId, Position};
use anyhow::{Context, Result};
use rocket_db_pools::sqlx;
use sqlx::pool::PoolConnection;
@ -24,6 +24,7 @@ pub async fn insert_order(order: &Order, conn: &mut PoolConnection<Sqlite>) -> a
let creation_timestamp = serde_json::to_string(&order.creation_timestamp).unwrap();
let term = serde_json::to_string(&order.term).unwrap();
let origin = serde_json::to_string(&order.origin).unwrap();
let oracle_event_id = order.oracle_event_id.0.clone();
sqlx::query!(
r#"
@ -38,8 +39,9 @@ pub async fn insert_order(order: &Order, conn: &mut PoolConnection<Sqlite>) -> a
liquidation_price,
creation_timestamp,
term,
origin
) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
origin,
oracle_event_id
) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
"#,
uuid,
trading_pair,
@ -51,7 +53,8 @@ pub async fn insert_order(order: &Order, conn: &mut PoolConnection<Sqlite>) -> a
liquidation_price,
creation_timestamp,
term,
origin
origin,
oracle_event_id
)
.execute(conn)
.await?;
@ -85,6 +88,7 @@ pub async fn load_order_by_id(
let creation_timestamp = serde_json::from_str(row.creation_timestamp.as_str()).unwrap();
let term = serde_json::from_str(row.term.as_str()).unwrap();
let origin = serde_json::from_str(row.origin.as_str()).unwrap();
let oracle_event_id = OracleEventId(row.oracle_event_id);
Ok(Order {
id: uuid,
@ -98,6 +102,7 @@ pub async fn load_order_by_id(
creation_timestamp,
term,
origin,
oracle_event_id,
})
}
@ -264,6 +269,7 @@ pub async fn load_cfd_by_order_id(
orders.liquidation_price as liquidation_price,
orders.creation_timestamp as creation_timestamp,
orders.term as term,
orders.oracle_event_id,
cfds.quantity_usd as quantity_usd,
cfd_states.state as state
from cfds as cfds
@ -295,6 +301,7 @@ pub async fn load_cfd_by_order_id(
let creation_timestamp = serde_json::from_str(row.creation_timestamp.as_str()).unwrap();
let term = serde_json::from_str(row.term.as_str()).unwrap();
let origin: Origin = serde_json::from_str(row.origin.as_str()).unwrap();
let oracle_event_id = OracleEventId(row.oracle_event_id.clone());
let quantity = serde_json::from_str(row.quantity_usd.as_str()).unwrap();
let latest_state = serde_json::from_str(row.state.as_str()).unwrap();
@ -311,6 +318,7 @@ pub async fn load_cfd_by_order_id(
creation_timestamp,
term,
origin,
oracle_event_id,
};
Ok(Cfd {
@ -339,6 +347,7 @@ pub async fn load_all_cfds(conn: &mut PoolConnection<Sqlite>) -> anyhow::Result<
orders.liquidation_price as liquidation_price,
orders.creation_timestamp as creation_timestamp,
orders.term as term,
orders.oracle_event_id,
cfds.quantity_usd as quantity_usd,
cfd_states.state as state
from cfds as cfds
@ -371,6 +380,7 @@ pub async fn load_all_cfds(conn: &mut PoolConnection<Sqlite>) -> anyhow::Result<
let creation_timestamp = serde_json::from_str(row.creation_timestamp.as_str()).unwrap();
let term = serde_json::from_str(row.term.as_str()).unwrap();
let origin: Origin = serde_json::from_str(row.origin.as_str()).unwrap();
let oracle_event_id = OracleEventId(row.oracle_event_id.clone());
let quantity = serde_json::from_str(row.quantity_usd.as_str()).unwrap();
let latest_state = serde_json::from_str(row.state.as_str()).unwrap();
@ -387,6 +397,7 @@ pub async fn load_all_cfds(conn: &mut PoolConnection<Sqlite>) -> anyhow::Result<
creation_timestamp,
term,
origin,
oracle_event_id,
};
Cfd {
@ -420,7 +431,7 @@ mod tests {
let pool = setup_test_db().await;
let mut conn = pool.acquire().await.unwrap();
let order = Order::from_default_with_price(Usd(dec!(10000)), Origin::Theirs).unwrap();
let order = Order::default();
insert_order(&order, &mut conn).await.unwrap();
let order_loaded = load_order_by_id(order.id, &mut conn).await.unwrap();
@ -433,7 +444,7 @@ mod tests {
let pool = setup_test_db().await;
let mut conn = pool.acquire().await.unwrap();
let order = Order::from_default_with_price(Usd(dec!(10000)), Origin::Theirs).unwrap();
let order = Order::default();
let cfd = Cfd::new(
order.clone(),
Usd(dec!(1000)),
@ -457,7 +468,7 @@ mod tests {
let pool = setup_test_db().await;
let mut conn = pool.acquire().await.unwrap();
let order = Order::from_default_with_price(Usd(dec!(10000)), Origin::Theirs).unwrap();
let order = Order::default();
let cfd = Cfd::new(
order.clone(),
Usd(dec!(1000)),
@ -482,8 +493,7 @@ mod tests {
let pool = setup_test_db().await;
let mut conn = pool.acquire().await.unwrap();
let order = Order::from_default_with_price(Usd(dec!(10000)), Origin::Theirs).unwrap();
let order = Order::default();
let cfd = Cfd::new(
order.clone(),
Usd(dec!(1000)),
@ -502,8 +512,7 @@ mod tests {
let cfd_from_db = load_cfd_by_order_id(order_id, &mut conn).await.unwrap();
assert_eq!(cfd, cfd_from_db);
let order = Order::from_default_with_price(Usd(dec!(10000)), Origin::Theirs).unwrap();
let order = Order::default();
let cfd = Cfd::new(
order.clone(),
Usd(dec!(1000)),
@ -528,7 +537,7 @@ mod tests {
let pool = setup_test_db().await;
let mut conn = pool.acquire().await.unwrap();
let order = Order::from_default_with_price(Usd(dec!(10000)), Origin::Theirs).unwrap();
let order = Order::default();
let mut cfd = Cfd::new(
order.clone(),
Usd(dec!(1000)),
@ -572,4 +581,17 @@ mod tests {
pool
}
impl Default for Order {
fn default() -> Self {
Order::new(
Usd(dec!(1000)),
Usd(dec!(100)),
Usd(dec!(1000)),
Origin::Theirs,
OracleEventId("Dummy".to_string()),
)
.unwrap()
}
}
}

81
daemon/src/maker_cfd.rs

@ -5,10 +5,10 @@ use crate::db::{
};
use crate::maker_inc_connections::TakerCommand;
use crate::model::cfd::{
Cfd, CfdState, CfdStateChangeEvent, CfdStateCommon, Dlc, Order, OrderId, Role,
Cfd, CfdState, CfdStateChangeEvent, CfdStateCommon, Dlc, Order, OrderId, Origin, Role,
SettlementProposal, SettlementProposals,
};
use crate::model::{TakerId, Usd};
use crate::model::{OracleEventId, TakerId, Usd};
use crate::monitor::MonitorParams;
use crate::wallet::Wallet;
use crate::{maker_inc_connections, monitor, oracle, setup_contract, wire};
@ -17,7 +17,7 @@ use async_trait::async_trait;
use bdk::bitcoin::secp256k1::schnorrsig;
use futures::channel::mpsc;
use futures::{future, SinkExt};
use std::collections::HashMap;
use std::collections::{BTreeMap, HashMap};
use std::time::SystemTime;
use tokio::sync::watch;
use xtra::prelude::*;
@ -43,7 +43,11 @@ pub struct RejectSettlement {
pub order_id: OrderId,
}
pub struct NewOrder(pub Order);
pub struct NewOrder {
pub price: Usd,
pub min_quantity: Usd,
pub max_quantity: Usd,
}
pub struct NewTakerOnline {
pub id: TakerId,
@ -70,8 +74,8 @@ pub struct Actor {
current_order_id: Option<OrderId>,
monitor_actor: Address<monitor::Actor<Actor>>,
setup_state: SetupState,
latest_announcement: Option<oracle::Announcement>,
_oracle_actor: Address<oracle::Actor<Actor, monitor::Actor<Actor>>>,
latest_announcements: Option<BTreeMap<OracleEventId, oracle::Announcement>>,
oracle_actor: Address<oracle::Actor<Actor, monitor::Actor<Actor>>>,
current_settlement_proposals: HashMap<OrderId, SettlementProposal>,
}
@ -107,8 +111,8 @@ impl Actor {
current_order_id: None,
monitor_actor,
setup_state: SetupState::None,
latest_announcement: None,
_oracle_actor: oracle_actor,
latest_announcements: None,
oracle_actor,
current_settlement_proposals: HashMap::new(),
}
}
@ -121,7 +125,30 @@ impl Actor {
))?)
}
async fn handle_new_order(&mut self, order: Order) -> Result<()> {
async fn handle_new_order(
&mut self,
price: Usd,
min_quantity: Usd,
max_quantity: Usd,
) -> Result<()> {
let oracle_event_id = self
.latest_announcements
.clone()
.context("Cannot create order because no announcement from oracle")?
.iter()
.next_back()
.context("Empty list of announcements")?
.0
.clone();
let order = Order::new(
price,
min_quantity,
max_quantity,
Origin::Ours,
oracle_event_id,
)?;
// 1. Save to DB
let mut conn = self.db.acquire().await?;
insert_order(&order, &mut conn).await?;
@ -340,18 +367,21 @@ impl Actor {
self.cfd_feed_actor_inbox
.send(load_all_cfds(&mut conn).await?)?;
// let latest_announcement = self
// .latest_announcement
// .to_owned()
// .context("Unaware of oracle's latest announcement.")?;
// self.oracle_actor
// .do_send_async(oracle::MonitorEvent {
// event_id: latest_announcement.id,
// })
// .await?;
let offer_announcements = self
.latest_announcements
.clone()
.context("No oracle announcements available")?;
let offer_announcement = offer_announcements
.get(&cfd.order.oracle_event_id)
.context("Order's announcement not found in current oracle announcements")?;
self.oracle_actor
.do_send_async(oracle::MonitorEvent {
event_id: offer_announcement.id.clone(),
})
.await?;
let nonce_pks = Vec::new();
let nonce_pks = offer_announcement.nonce_pks.clone();
let contract_future = setup_contract::new(
self.takers.clone().into_sink().with(move |msg| {
@ -509,8 +539,13 @@ impl Actor {
&mut self,
announcements: oracle::Announcements,
) -> Result<()> {
tracing::debug!("Updating latest oracle announcements");
self.latest_announcement = Some(announcements.0.last().unwrap().clone());
self.latest_announcements.replace(
announcements
.0
.iter()
.map(|announcement| (announcement.id.clone(), announcement.clone()))
.collect(),
);
Ok(())
}
@ -565,7 +600,7 @@ impl Handler<Commit> for Actor {
#[async_trait]
impl Handler<NewOrder> for Actor {
async fn handle(&mut self, msg: NewOrder, _ctx: &mut Context<Self>) {
log_error!(self.handle_new_order(msg.0));
log_error!(self.handle_new_order(msg.price, msg.min_quantity, msg.max_quantity));
}
}

3
daemon/src/model.rs

@ -105,3 +105,6 @@ pub struct WalletInfo {
pub address: Address,
pub last_updated_at: SystemTime,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct OracleEventId(pub String);

29
daemon/src/model/cfd.rs

@ -1,4 +1,4 @@
use crate::model::{Leverage, Percent, Position, TakerId, TradingPair, Usd};
use crate::model::{Leverage, OracleEventId, Percent, Position, TakerId, TradingPair, Usd};
use crate::monitor;
use anyhow::{bail, Context, Result};
use bdk::bitcoin::secp256k1::{SecretKey, Signature};
@ -91,11 +91,22 @@ pub struct Order {
pub term: Duration,
pub origin: Origin,
/// The id of the event to be used for price attestation
///
/// The maker includes this into the Order based on the Oracle announcement to be used.
pub oracle_event_id: OracleEventId,
}
#[allow(dead_code)] // Only one binary and the tests use this.
impl Order {
pub fn from_default_with_price(price: Usd, origin: Origin) -> Result<Self> {
pub fn new(
price: Usd,
min_quantity: Usd,
max_quantity: Usd,
origin: Origin,
oracle_event_id: OracleEventId,
) -> Result<Self> {
let leverage = Leverage(5);
let maintenance_margin_rate = dec!(0.005);
let liquidation_price =
@ -104,8 +115,8 @@ impl Order {
Ok(Order {
id: OrderId::default(),
price,
min_quantity: Usd(dec!(1000)),
max_quantity: Usd(dec!(10000)),
min_quantity,
max_quantity,
leverage,
trading_pair: TradingPair::BtcUsd,
liquidation_price,
@ -113,17 +124,9 @@ impl Order {
creation_timestamp: SystemTime::now(),
term: Duration::from_secs(60 * 60 * 8), // 8 hours
origin,
oracle_event_id,
})
}
pub fn with_min_quantity(mut self, min_quantity: Usd) -> Order {
self.min_quantity = min_quantity;
self
}
pub fn with_max_quantity(mut self, max_quantity: Usd) -> Order {
self.max_quantity = max_quantity;
self
}
}
fn calculate_liquidation_price(

14
daemon/src/oracle.rs

@ -1,4 +1,5 @@
use crate::actors::log_error;
use crate::model::OracleEventId;
use anyhow::{Context, Result};
use async_trait::async_trait;
use cfd_protocol::secp256k1_zkp::{schnorrsig, SecretKey};
@ -153,7 +154,7 @@ where
}
pub struct MonitorEvent {
pub event_id: String,
pub event_id: OracleEventId,
}
impl xtra::Message for MonitorEvent {
@ -167,7 +168,7 @@ where
M: xtra::Handler<Attestation>,
{
async fn handle(&mut self, msg: MonitorEvent, _ctx: &mut xtra::Context<Self>) {
self.monitor_event(msg.event_id)
self.monitor_event(msg.event_id.0)
}
}
@ -202,11 +203,12 @@ pub struct Announcement {
///
/// Doubles up as the path of the URL for this event i.e.
/// https://h00.ooo/{id}.
pub id: String,
pub id: OracleEventId,
pub expected_outcome_time: OffsetDateTime,
pub nonce_pks: Vec<schnorrsig::PublicKey>,
}
#[derive(Debug, Clone)]
pub struct Announcements(pub [Announcement; 24]);
// TODO: Implement real deserialization once price attestation is
@ -228,6 +230,7 @@ impl xtra::Message for Attestation {
}
mod olivia_api {
use crate::model::OracleEventId;
use anyhow::Context;
use cfd_protocol::secp256k1_zkp::{schnorrsig, SecretKey};
use std::convert::TryFrom;
@ -249,7 +252,7 @@ mod olivia_api {
serde_json::from_str::<AnnouncementData>(&response.announcement.oracle_event.data)?;
Ok(Self {
id: data.id,
id: OracleEventId(data.id),
expected_outcome_time: data.expected_outcome_time,
nonce_pks: data.schemes.olivia_v1.nonces,
})
@ -338,6 +341,7 @@ mod olivia_api {
mod tests {
use std::vec;
use crate::model::OracleEventId;
use crate::oracle;
use time::macros::datetime;
@ -347,7 +351,7 @@ mod olivia_api {
let deserialized = serde_json::from_str::<oracle::Announcement>(json).unwrap();
let expected = oracle::Announcement {
id: "/x/BitMEX/BXBT/2021-10-04T22:00:00.price[n:20]".to_string(),
id: OracleEventId("/x/BitMEX/BXBT/2021-10-04T22:00:00.price[n:20]".to_string()),
expected_outcome_time: datetime!(2021-10-04 22:00:00).assume_utc(),
nonce_pks: vec![
"8d72028eeaf4b85aec0f750f05a4a320cac193f5d8494bfe05cd4b29f3df4239"

17
daemon/src/routes_maker.rs

@ -1,5 +1,5 @@
use crate::auth::Authenticated;
use crate::model::cfd::{Cfd, Order, OrderId, Origin, Role, SettlementProposals};
use crate::model::cfd::{Cfd, Order, OrderId, Role, SettlementProposals};
use crate::model::{Usd, WalletInfo};
use crate::routes::EmbeddedFileExt;
use crate::to_sse_event::{CfdAction, CfdsWithAuxData, ToSseEvent};
@ -87,16 +87,15 @@ pub async fn post_sell_order(
order: Json<CfdNewOrderRequest>,
cfd_actor_address: &State<Address<maker_cfd::Actor>>,
_auth: Authenticated,
) -> Result<status::Accepted<()>, status::BadRequest<String>> {
let order = Order::from_default_with_price(order.price, Origin::Ours)
.map_err(|e| status::BadRequest(Some(e.to_string())))?
.with_min_quantity(order.min_quantity)
.with_max_quantity(order.max_quantity);
) -> Result<status::Accepted<()>, Status> {
cfd_actor_address
.do_send_async(maker_cfd::NewOrder(order))
.do_send_async(maker_cfd::NewOrder {
price: order.price,
min_quantity: order.min_quantity,
max_quantity: order.max_quantity,
})
.await
.expect("actor to always be available");
.map_err(|_| Status::new(500))?;
Ok(status::Accepted(None))
}

46
daemon/src/taker_cfd.rs

@ -7,7 +7,7 @@ use crate::model::cfd::{
Cfd, CfdState, CfdStateChangeEvent, CfdStateCommon, Dlc, Order, OrderId, Origin, Role,
SettlementProposal, SettlementProposals,
};
use crate::model::Usd;
use crate::model::{OracleEventId, Usd};
use crate::monitor::{self, MonitorParams};
use crate::wallet::Wallet;
use crate::wire::SetupMsg;
@ -17,7 +17,7 @@ use async_trait::async_trait;
use bdk::bitcoin::secp256k1::schnorrsig;
use futures::channel::mpsc;
use futures::{future, SinkExt};
use std::collections::HashMap;
use std::collections::{BTreeMap, HashMap};
use std::time::SystemTime;
use tokio::sync::watch;
use xtra::prelude::*;
@ -63,8 +63,8 @@ pub struct Actor {
send_to_maker: Address<send_to_socket::Actor<wire::TakerToMaker>>,
monitor_actor: Address<monitor::Actor<Actor>>,
setup_state: SetupState,
latest_announcement: Option<oracle::Announcement>,
_oracle_actor: Address<oracle::Actor<Actor, monitor::Actor<Actor>>>,
latest_announcements: Option<BTreeMap<OracleEventId, oracle::Announcement>>,
oracle_actor: Address<oracle::Actor<Actor, monitor::Actor<Actor>>>,
current_settlement_proposals: HashMap<OrderId, SettlementProposal>,
}
@ -91,8 +91,8 @@ impl Actor {
send_to_maker,
monitor_actor,
setup_state: SetupState::None,
latest_announcement: None,
_oracle_actor: oracle_actor,
oracle_actor,
latest_announcements: None,
current_settlement_proposals: HashMap::new(),
}
}
@ -213,18 +213,21 @@ impl Actor {
.send(load_all_cfds(&mut conn).await?)?;
let cfd = load_cfd_by_order_id(order_id, &mut conn).await?;
// let latest_announcement = self
// .latest_announcement
// .to_owned()
// .context("Unaware of oracle's latest announcement.")?;
// self.oracle_actor
// .do_send_async(oracle::MonitorEvent {
// event_id: latest_announcement.id,
// })
// .await?;
let offer_announcements = self
.latest_announcements
.clone()
.context("No oracle announcements available")?;
let offer_announcement = offer_announcements
.get(&cfd.order.oracle_event_id)
.context("Order's announcement not found in current oracle announcements")?;
self.oracle_actor
.do_send_async(oracle::MonitorEvent {
event_id: offer_announcement.id.clone(),
})
.await?;
let nonce_pks = Vec::new();
let nonce_pks = offer_announcement.nonce_pks.clone();
let contract_future = setup_contract::new(
self.send_to_maker
@ -392,8 +395,13 @@ impl Actor {
&mut self,
announcements: oracle::Announcements,
) -> Result<()> {
tracing::debug!("Updating latest oracle announcements");
self.latest_announcement = Some(announcements.0.last().unwrap().clone());
self.latest_announcements.replace(
announcements
.0
.iter()
.map(|announcement| (announcement.id.clone(), announcement.clone()))
.collect(),
);
Ok(())
}

Loading…
Cancel
Save