Browse Source

Taker monitors

Wire the monitor into the taker.
fix-bad-api-calls
Daniel Karzel 3 years ago
parent
commit
608a962b8e
No known key found for this signature in database GPG Key ID: 30C3FC2E438ADB6E
  1. 11
      daemon/src/taker.rs
  2. 71
      daemon/src/taker_cfd.rs

11
daemon/src/taker.rs

@ -8,6 +8,7 @@ use model::cfd::{Cfd, Order};
use rocket::fairing::AdHoc;
use rocket_db_pools::Database;
use seed::Seed;
use std::collections::HashMap;
use std::net::SocketAddr;
use std::path::PathBuf;
use std::thread::sleep;
@ -78,6 +79,7 @@ async fn main() -> Result<()> {
let data_dir = opts
.data_dir
.clone()
.unwrap_or_else(|| std::env::current_dir().expect("unable to get cwd"));
if !data_dir.exists() {
@ -163,6 +165,8 @@ async fn main() -> Result<()> {
.create(None)
.spawn_global();
let (monitor_actor_address, monitor_actor_context) = xtra::Context::new(None);
let cfd_actor_inbox = taker_cfd::Actor::new(
db,
wallet.clone(),
@ -170,6 +174,7 @@ async fn main() -> Result<()> {
cfd_feed_sender,
order_feed_sender,
send_to_maker,
monitor_actor_address,
)
.await
.unwrap()
@ -179,6 +184,12 @@ async fn main() -> Result<()> {
let inc_maker_messages_actor =
taker_inc_message_actor::new(read, cfd_actor_inbox.clone());
tokio::spawn(monitor_actor_context.run(monitor::Actor::new(
&opts.electrum,
HashMap::new(),
cfd_actor_inbox.clone(),
)));
tokio::spawn(wallet_sync::new(wallet, wallet_feed_sender));
tokio::spawn(inc_maker_messages_actor);

71
daemon/src/taker_cfd.rs

@ -4,11 +4,12 @@ use crate::db::{
};
use crate::actors::log_error;
use crate::model::cfd::{Cfd, CfdState, CfdStateCommon, Dlc, Order, OrderId};
use crate::model::cfd::{Cfd, CfdState, CfdStateChangeEvent, CfdStateCommon, Dlc, Order, OrderId};
use crate::model::Usd;
use crate::monitor::{CfdMonitoringEvent, MonitorParams};
use crate::wallet::Wallet;
use crate::wire::SetupMsg;
use crate::{send_to_socket, setup_contract_actor, wire};
use crate::{monitor, send_to_socket, setup_contract_actor, wire};
use anyhow::Result;
use async_trait::async_trait;
use bdk::bitcoin::secp256k1::schnorrsig;
@ -43,6 +44,7 @@ pub struct Actor {
// TODO: Move the contract setup into a dedicated actor and send messages to that actor that
// manages the state instead of this ugly buffer
contract_setup_message_buffer: Vec<SetupMsg>,
monitor_actor: Address<monitor::Actor<Actor>>,
}
impl Actor {
@ -53,6 +55,7 @@ impl Actor {
cfd_feed_actor_inbox: watch::Sender<Vec<Cfd>>,
order_feed_actor_inbox: watch::Sender<Option<Order>>,
send_to_maker: Address<send_to_socket::Actor>,
monitor_actor: Address<monitor::Actor<Actor>>,
) -> Result<Self> {
let mut conn = db.acquire().await?;
cfd_feed_actor_inbox.send(load_all_cfds(&mut conn).await?)?;
@ -66,6 +69,7 @@ impl Actor {
send_to_maker,
current_contract_setup: None,
contract_setup_message_buffer: vec![],
monitor_actor,
})
}
@ -231,12 +235,62 @@ impl Actor {
self.cfd_feed_actor_inbox
.send(load_all_cfds(&mut conn).await?)?;
let txid = self.wallet.try_broadcast_transaction(dlc.lock.0).await?;
let txid = self
.wallet
.try_broadcast_transaction(dlc.lock.0.clone())
.await?;
tracing::info!("Lock transaction published with txid {}", txid);
// TODO: tx monitoring, once confirmed with x blocks transition the Cfd to
// Open
// TODO: It's a bit suspicious to load this just to get the
// refund timelock
let cfd = load_cfd_by_order_id(order_id, &mut conn).await?;
let script_pubkey = dlc.address.script_pubkey();
self.monitor_actor
.do_send_async(monitor::StartMonitoring {
id: order_id,
params: MonitorParams {
lock: (dlc.lock.0.txid(), dlc.lock.1),
commit: (dlc.commit.0.txid(), dlc.commit.2),
cets: dlc
.cets
.into_iter()
.map(|(tx, _, range)| (tx.txid(), script_pubkey.clone(), range))
.collect(),
refund: (
dlc.refund.0.txid(),
script_pubkey,
cfd.refund_timelock_in_blocks(),
),
},
})
.await?;
Ok(())
}
async fn handle_monitoring_event(&mut self, event: CfdMonitoringEvent) -> Result<()> {
let order_id = event.order_id();
let mut conn = self.db.acquire().await?;
let cfd = load_cfd_by_order_id(order_id, &mut conn).await?;
let new_state = cfd.transition_to(CfdStateChangeEvent::Monitor(event))?;
insert_new_cfd_state_by_order_id(order_id, new_state.clone(), &mut conn).await?;
// TODO: Not sure that should be done here...
// Consider sending a message to ourselves to trigger broadcasting refund?
if let CfdState::MustRefund { .. } = new_state {
let signed_refund_tx = cfd.refund_tx()?;
let txid = self
.wallet
.try_broadcast_transaction(signed_refund_tx)
.await?;
tracing::info!("Refund transaction published on chain: {}", txid);
}
Ok(())
}
@ -284,6 +338,13 @@ impl Handler<CfdSetupCompleted> for Actor {
}
}
#[async_trait]
impl Handler<CfdMonitoringEvent> for Actor {
async fn handle(&mut self, msg: CfdMonitoringEvent, _ctx: &mut Context<Self>) {
log_error!(self.handle_monitoring_event(msg))
}
}
impl Message for TakeOffer {
type Result = ();
}

Loading…
Cancel
Save