diff --git a/Cargo.lock b/Cargo.lock index b805913..d67725b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -528,6 +528,8 @@ dependencies = [ "hex", "hkdf", "itertools", + "mockall", + "mockall_derive", "nalgebra", "ndarray", "ndarray_einsum_beta", @@ -634,6 +636,12 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499" +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" + [[package]] name = "digest" version = "0.9.0" @@ -655,6 +663,12 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" +[[package]] +name = "downcast" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb454f0228b18c7f4c3b0ebbee346ed9c52e7443b0999cd543ff3571205701d" + [[package]] name = "either" version = "1.6.1" @@ -741,6 +755,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "float-cmp" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4" +dependencies = [ + "num-traits", +] + [[package]] name = "flume" version = "0.10.9" @@ -769,6 +792,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fragile" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69a039c3498dc930fe810151a34ba0c1c70b02b8625035592e74432f678591f2" + [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -1365,6 +1394,33 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "mockall" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab571328afa78ae322493cacca3efac6a0f2e0a67305b4df31fd439ef129ac0" +dependencies = [ + "cfg-if 1.0.0", + "downcast", + "fragile", + "lazy_static", + "mockall_derive", + "predicates", + "predicates-tree", +] + +[[package]] +name = "mockall_derive" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e25b214433f669161f414959594216d8e6ba83b6679d3db96899c0b4639033" +dependencies = [ + "cfg-if 1.0.0", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "multer" version = "2.0.1" @@ -1437,6 +1493,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + [[package]] name = "ntapi" version = "0.3.6" @@ -1675,6 +1737,35 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +[[package]] +name = "predicates" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49cfaf7fdaa3bfacc6fa3e7054e65148878354a5cfddcf661df4c851f8021df" +dependencies = [ + "difference", + "float-cmp", + "normalize-line-endings", + "predicates-core", + "regex", +] + +[[package]] +name = "predicates-core" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451" + +[[package]] +name = "predicates-tree" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "338c7be2905b732ae3984a2f40032b5e94fd8f52505b186c7d4d68d193445df7" +dependencies = [ + "predicates-core", + "termtree", +] + [[package]] name = "pretty_assertions" version = "1.0.0" @@ -2838,6 +2929,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "termtree" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13a4ec180a2de59b57434704ccfad967f789b12737738798fa08798cd5824c16" + [[package]] name = "textwrap" version = "0.14.2" diff --git a/daemon/Cargo.toml b/daemon/Cargo.toml index 56ed3c8..e72fd65 100644 --- a/daemon/Cargo.toml +++ b/daemon/Cargo.toml @@ -53,6 +53,8 @@ name = "maker" path = "src/maker.rs" [dev-dependencies] +mockall = "0.10.2" +mockall_derive = "0.10.2" pretty_assertions = "1" serde_test = "1" time = { version = "0.3", features = ["std"] } diff --git a/daemon/tests/happy_path.rs b/daemon/tests/happy_path.rs index e6436ba..b3afe45 100644 --- a/daemon/tests/happy_path.rs +++ b/daemon/tests/happy_path.rs @@ -1,6 +1,6 @@ -use crate::harness::mocks::monitor::Monitor; -use crate::harness::mocks::oracle::Oracle; -use crate::harness::mocks::wallet::Wallet; +use crate::harness::bdk::dummy_partially_signed_transaction; +use crate::harness::mocks::oracle::dummy_announcement; +use crate::harness::mocks::wallet::build_party_params; use crate::harness::start_both; use anyhow::Context; use cfd_protocol::secp256k1_zkp::schnorrsig; @@ -8,9 +8,10 @@ use daemon::maker_cfd; use daemon::model::cfd::{Cfd, CfdState, Order, Origin}; use daemon::model::{Price, Usd}; use daemon::tokio_ext::FutureExt; +use harness::bdk::dummy_tx_id; use rust_decimal_macros::dec; use std::time::Duration; -use tokio::sync::watch; +use tokio::sync::{watch, MutexGuard}; use tracing::subscriber::DefaultGuard; use tracing_subscriber::filter::LevelFilter; use tracing_subscriber::util::SubscriberInitExt; @@ -20,15 +21,7 @@ mod harness; #[tokio::test] async fn taker_receives_order_from_maker_on_publication() { let _guard = init_tracing(); - let (mut maker, mut taker) = start_both( - Oracle::default(), - Monitor, - Wallet::default(), - Oracle::default(), - Monitor, - Wallet::default(), - ) - .await; + let (mut maker, mut taker) = start_both().await; assert!(is_next_none(&mut taker.order_feed).await); @@ -45,15 +38,7 @@ async fn taker_receives_order_from_maker_on_publication() { #[tokio::test] async fn taker_takes_order_and_maker_rejects() { let _guard = init_tracing(); - let (mut maker, mut taker) = start_both( - Oracle::default(), - Monitor, - Wallet::default().with_wallet_info(), - Oracle::default(), - Monitor, - Wallet::default().with_wallet_info(), - ) - .await; + let (mut maker, mut taker) = start_both().await; // TODO: Why is this needed? For the cfd stream it is not needed is_next_none(&mut taker.order_feed).await; @@ -86,28 +71,25 @@ async fn taker_takes_order_and_maker_rejects() { assert!(matches!(maker_cfd.state, CfdState::Rejected { .. })); } +// Helper function setting up a "happy path" wallet mock +fn mock_wallet_sign_and_broadcast(wallet: &mut MutexGuard<'_, harness::mocks::wallet::MockWallet>) { + let mut seq = mockall::Sequence::new(); + wallet + .expect_sign() + .times(1) + .returning(|_| Ok(dummy_partially_signed_transaction())) + .in_sequence(&mut seq); + wallet + .expect_broadcast() + .times(1) + .returning(|_| Ok(dummy_tx_id())) + .in_sequence(&mut seq); +} + #[tokio::test] async fn taker_takes_order_and_maker_accepts_and_contract_setup() { let _guard = init_tracing(); - let (mut maker, mut taker) = start_both( - Oracle::default() - .with_dummy_announcement(harness::cfd_protocol::OliviaData::example_0().announcement()), - Monitor, - Wallet::default() - .with_wallet_info() - .with_party_params() - .with_psbt(harness::bdk::dummy_partially_signed_transaction()) - .with_txid(harness::bdk::dummy_tx_id()), - Oracle::default() - .with_dummy_announcement(harness::cfd_protocol::OliviaData::example_0().announcement()), - Monitor, - Wallet::default() - .with_wallet_info() - .with_party_params() - .with_psbt(harness::bdk::dummy_partially_signed_transaction()) - .with_txid(harness::bdk::dummy_tx_id()), - ) - .await; + let (mut maker, mut taker) = start_both().await; is_next_none(&mut taker.order_feed).await; @@ -118,8 +100,40 @@ async fn taker_takes_order_and_maker_accepts_and_contract_setup() { taker.take_order(received.clone(), Usd::new(dec!(5))); let (_, _) = next_cfd(&mut taker.cfd_feed, &mut maker.cfd_feed).await; + maker + .mocks + .oracle() + .await + .expect_get_announcement() + .returning(|_| Some(dummy_announcement())); + + taker + .mocks + .oracle() + .await + .expect_get_announcement() + .returning(|_| Some(dummy_announcement())); + maker.accept_take_request(received.clone()); + #[allow(clippy::redundant_closure)] // clippy is in the wrong here + maker + .mocks + .wallet() + .await + .expect_build_party_params() + .times(1) + .returning(|msg| build_party_params(msg)); + + #[allow(clippy::redundant_closure)] // clippy is in the wrong here + taker + .mocks + .wallet() + .await + .expect_build_party_params() + .times(1) + .returning(|msg| build_party_params(msg)); + let (taker_cfd, maker_cfd) = next_cfd(&mut taker.cfd_feed, &mut maker.cfd_feed).await; // TODO: More elaborate Cfd assertions assert_eq!(taker_cfd.order.id, received.id); @@ -127,6 +141,9 @@ async fn taker_takes_order_and_maker_accepts_and_contract_setup() { assert!(matches!(taker_cfd.state, CfdState::ContractSetup { .. })); assert!(matches!(maker_cfd.state, CfdState::ContractSetup { .. })); + mock_wallet_sign_and_broadcast(&mut maker.mocks.wallet().await); + mock_wallet_sign_and_broadcast(&mut taker.mocks.wallet().await); + let (taker_cfd, maker_cfd) = next_cfd(&mut taker.cfd_feed, &mut maker.cfd_feed).await; // TODO: More elaborate Cfd assertions assert_eq!(taker_cfd.order.id, received.id); diff --git a/daemon/tests/harness/mocks/mod.rs b/daemon/tests/harness/mocks/mod.rs index 1a6fb41..edc90cf 100644 --- a/daemon/tests/harness/mocks/mod.rs +++ b/daemon/tests/harness/mocks/mod.rs @@ -1,3 +1,57 @@ +use std::sync::Arc; + +use tokio::sync::{Mutex, MutexGuard}; + +use self::monitor::MonitorActor; +use self::oracle::OracleActor; +use self::wallet::WalletActor; + pub mod monitor; pub mod oracle; pub mod wallet; + +#[derive(Clone)] +pub struct Mocks { + pub wallet: Arc>, + pub monitor: Arc>, + pub oracle: Arc>, +} + +impl Mocks { + pub async fn wallet(&mut self) -> MutexGuard<'_, wallet::MockWallet> { + self.wallet.lock().await + } + + #[allow(dead_code)] // will be used soon + pub async fn monitor(&mut self) -> MutexGuard<'_, monitor::MockMonitor> { + self.monitor.lock().await + } + + pub async fn oracle(&mut self) -> MutexGuard<'_, oracle::MockOracle> { + self.oracle.lock().await + } +} + +impl Default for Mocks { + fn default() -> Self { + Self { + oracle: Arc::new(Mutex::new(oracle::MockOracle::new())), + monitor: Arc::new(Mutex::new(monitor::MockMonitor::new())), + wallet: Arc::new(Mutex::new(wallet::MockWallet::new())), + } + } +} + +/// Creates actors with embedded mock handlers +pub fn create_actors(mocks: &Mocks) -> (OracleActor, MonitorActor, WalletActor) { + let oracle = OracleActor { + mock: mocks.oracle.clone(), + }; + let monitor = MonitorActor { + mock: mocks.monitor.clone(), + }; + let wallet = WalletActor { + mock: mocks.wallet.clone(), + }; + (oracle, monitor, wallet) +} diff --git a/daemon/tests/harness/mocks/monitor.rs b/daemon/tests/harness/mocks/monitor.rs index b03a394..52de3bf 100644 --- a/daemon/tests/harness/mocks/monitor.rs +++ b/daemon/tests/harness/mocks/monitor.rs @@ -1,29 +1,53 @@ +use std::sync::Arc; + use daemon::{monitor, oracle}; +use mockall::*; +use tokio::sync::Mutex; use xtra_productivity::xtra_productivity; -/// Test Stub simulating the Monitor actor -pub struct Monitor; -impl xtra::Actor for Monitor {} +/// Test Stub simulating the Monitor actor. +/// Serves as an entrypoint for injected mock handlers. +pub struct MonitorActor { + pub mock: Arc>, +} + +impl xtra::Actor for MonitorActor {} +impl Monitor for MonitorActor {} #[xtra_productivity(message_impl = false)] -impl Monitor { - async fn handle(&mut self, _msg: monitor::Sync) {} +impl MonitorActor { + async fn handle(&mut self, msg: monitor::Sync) { + self.mock.lock().await.sync(msg) + } - async fn handle(&mut self, _msg: monitor::StartMonitoring) { - todo!("stub this if needed") + async fn handle(&mut self, msg: monitor::StartMonitoring) { + self.mock.lock().await.start_monitoring(msg) } - async fn handle(&mut self, _msg: monitor::CollaborativeSettlement) { - todo!("stub this if needed") + async fn handle(&mut self, msg: monitor::CollaborativeSettlement) { + self.mock.lock().await.collaborative_settlement(msg) } - async fn handle(&mut self, _msg: oracle::Attestation) { - todo!("stub this if needed") + async fn handle(&mut self, msg: oracle::Attestation) { + self.mock.lock().await.oracle_attestation(msg) } } -impl Default for Monitor { - fn default() -> Self { - Monitor +#[automock] +pub trait Monitor { + fn sync(&mut self, _msg: monitor::Sync) { + unreachable!("mockall will reimplement this method") + } + + fn start_monitoring(&mut self, _msg: monitor::StartMonitoring) { + unreachable!("mockall will reimplement this method") + } + + fn collaborative_settlement(&mut self, _msg: monitor::CollaborativeSettlement) { + unreachable!("mockall will reimplement this method") + } + + fn oracle_attestation(&mut self, _msg: oracle::Attestation) { + unreachable!("mockall will reimplement this method") } } diff --git a/daemon/tests/harness/mocks/oracle.rs b/daemon/tests/harness/mocks/oracle.rs index 36aeaf5..fe2fac4 100644 --- a/daemon/tests/harness/mocks/oracle.rs +++ b/daemon/tests/harness/mocks/oracle.rs @@ -1,45 +1,57 @@ +use crate::harness::cfd_protocol::OliviaData; use daemon::model::BitMexPriceEventId; use daemon::oracle; +use mockall::*; +use std::sync::Arc; use time::OffsetDateTime; +use tokio::sync::Mutex; use xtra_productivity::xtra_productivity; -pub struct Oracle { - announcement: Option, +/// Test Stub simulating the Oracle actor. +/// Serves as an entrypoint for injected mock handlers. +pub struct OracleActor { + pub mock: Arc>, } -impl Oracle { - pub fn with_dummy_announcement( - mut self, - dummy_announcement: cfd_protocol::Announcement, - ) -> Self { - self.announcement = Some(oracle::Announcement { - id: BitMexPriceEventId::new(OffsetDateTime::UNIX_EPOCH, 0), - expected_outcome_time: OffsetDateTime::now_utc(), - nonce_pks: dummy_announcement.nonce_pks, - }); - - self +impl xtra::Actor for OracleActor {} +impl Oracle for OracleActor {} + +#[xtra_productivity(message_impl = false)] +impl OracleActor { + async fn handle(&mut self, msg: oracle::GetAnnouncement) -> Option { + self.mock.lock().await.get_announcement(msg) } -} -impl xtra::Actor for Oracle {} + async fn handle(&mut self, msg: oracle::MonitorAttestation) { + self.mock.lock().await.monitor_attestation(msg) + } -#[xtra_productivity(message_impl = false)] -impl Oracle { - async fn handle_get_announcement( - &mut self, - _msg: oracle::GetAnnouncement, - ) -> Option { - self.announcement.clone() + async fn handle(&mut self, msg: oracle::Sync) { + self.mock.lock().await.sync(msg) } +} - async fn handle(&mut self, _msg: oracle::MonitorAttestation) {} +#[automock] +pub trait Oracle { + fn get_announcement(&mut self, _msg: oracle::GetAnnouncement) -> Option { + unreachable!("mockall will reimplement this method") + } + + fn monitor_attestation(&mut self, _msg: oracle::MonitorAttestation) { + unreachable!("mockall will reimplement this method") + } - async fn handle(&mut self, _msg: oracle::Sync) {} + fn sync(&mut self, _msg: oracle::Sync) { + unreachable!("mockall will reimplement this method") + } } -impl Default for Oracle { - fn default() -> Self { - Oracle { announcement: None } +pub fn dummy_announcement() -> oracle::Announcement { + let announcement = OliviaData::example_0().announcement(); + + oracle::Announcement { + id: BitMexPriceEventId::new(OffsetDateTime::UNIX_EPOCH, 0), + expected_outcome_time: OffsetDateTime::now_utc(), + nonce_pks: announcement.nonce_pks, } } diff --git a/daemon/tests/harness/mocks/wallet.rs b/daemon/tests/harness/mocks/wallet.rs index 9883051..04a6d75 100644 --- a/daemon/tests/harness/mocks/wallet.rs +++ b/daemon/tests/harness/mocks/wallet.rs @@ -1,93 +1,81 @@ use crate::harness::cfd_protocol::dummy_wallet; -use anyhow::{anyhow, Result}; +use anyhow::Result; use bdk::bitcoin::util::psbt::PartiallySignedTransaction; use bdk::bitcoin::{ecdsa, Amount, Txid}; use cfd_protocol::secp256k1_zkp::Secp256k1; use cfd_protocol::{PartyParams, WalletExt}; use daemon::model::{Timestamp, WalletInfo}; -use daemon::wallet; +use daemon::wallet::{self}; +use mockall::*; use rand::thread_rng; +use std::sync::Arc; +use tokio::sync::Mutex; use xtra_productivity::xtra_productivity; -pub struct Wallet { - party_params: bool, - wallet_info: Option, - psbt: Option, - txid: Option, +/// Test Stub simulating the Wallet actor. +/// Serves as an entrypoint for injected mock handlers. +pub struct WalletActor { + pub mock: Arc>, } -impl Wallet { - pub fn with_party_params(mut self) -> Self { - self.party_params = true; - self - } +impl xtra::Actor for WalletActor {} - pub fn with_wallet_info(mut self) -> Self { - let s = Secp256k1::new(); - let public_key = ecdsa::PublicKey::new(s.generate_keypair(&mut thread_rng()).1); - let address = bdk::bitcoin::Address::p2pkh(&public_key, bdk::bitcoin::Network::Testnet); +#[xtra_productivity(message_impl = false)] +impl WalletActor { + async fn handle(&mut self, msg: wallet::BuildPartyParams) -> Result { + self.mock.lock().await.build_party_params(msg) + } + async fn handle(&mut self, msg: wallet::Sync) -> Result { + tracing::info!("We are handling the wallet sync msg"); + self.mock.lock().await.sync(msg) + } + async fn handle(&mut self, msg: wallet::Sign) -> Result { + self.mock.lock().await.sign(msg) + } + async fn handle(&mut self, msg: wallet::TryBroadcastTransaction) -> Result { + self.mock.lock().await.broadcast(msg) + } +} - self.wallet_info = Some(WalletInfo { - balance: bdk::bitcoin::Amount::ONE_BTC, - address, - last_updated_at: Timestamp::now().unwrap(), - }); +#[automock] +pub trait Wallet { + fn build_party_params(&mut self, _msg: wallet::BuildPartyParams) -> Result { + unreachable!("mockall will reimplement this method") + } - self + fn sign(&mut self, _msg: wallet::Sign) -> Result { + unreachable!("mockall will reimplement this method") } - pub fn with_psbt(mut self, psbt: PartiallySignedTransaction) -> Self { - self.psbt = Some(psbt); - self + fn broadcast(&mut self, _msg: wallet::TryBroadcastTransaction) -> Result { + unreachable!("mockall will reimplement this method") } - pub fn with_txid(mut self, txid: Txid) -> Self { - self.txid = Some(txid); - self + fn sync(&mut self, _msg: wallet::Sync) -> Result { + unreachable!("mockall will reimplement this method") } } -impl xtra::Actor for Wallet {} - -#[xtra_productivity(message_impl = false)] -impl Wallet { - async fn handle(&mut self, msg: wallet::BuildPartyParams) -> Result { - if self.party_params { - let mut rng = thread_rng(); - let wallet = dummy_wallet(&mut rng, Amount::from_btc(0.4).unwrap(), 5).unwrap(); - - let party_params = wallet - .build_party_params(msg.amount, msg.identity_pk) - .unwrap(); +#[allow(dead_code)] +/// tells the user they have plenty of moneys +fn dummy_wallet_info() -> Result { + let s = Secp256k1::new(); + let public_key = ecdsa::PublicKey::new(s.generate_keypair(&mut thread_rng()).1); + let address = bdk::bitcoin::Address::p2pkh(&public_key, bdk::bitcoin::Network::Testnet); - return Ok(party_params); - } - - panic!("Stub not configured to return party params") - } - async fn handle(&mut self, _msg: wallet::Sync) -> Result { - self.wallet_info - .clone() - .ok_or_else(|| anyhow!("Stub not configured to return WalletInfo")) - } - async fn handle(&mut self, _msg: wallet::Sign) -> Result { - self.psbt - .clone() - .ok_or_else(|| anyhow!("Stub not configured to return PartiallySignedTransaction")) - } - async fn handle(&mut self, _msg: wallet::TryBroadcastTransaction) -> Result { - self.txid - .ok_or_else(|| anyhow!("Stub not configured to return Txid")) - } + Ok(WalletInfo { + balance: bdk::bitcoin::Amount::ONE_BTC, + address, + last_updated_at: Timestamp::now()?, + }) } -impl Default for Wallet { - fn default() -> Self { - Wallet { - party_params: false, - wallet_info: None, - psbt: None, - txid: None, - } - } +pub fn build_party_params(msg: wallet::BuildPartyParams) -> Result { + let mut rng = thread_rng(); + let wallet = dummy_wallet(&mut rng, Amount::from_btc(0.4).unwrap(), 5).unwrap(); + + let party_params = wallet + .build_party_params(msg.amount, msg.identity_pk) + .unwrap(); + Ok(party_params) } diff --git a/daemon/tests/harness/mod.rs b/daemon/tests/harness/mod.rs index 9c89517..4631d71 100644 --- a/daemon/tests/harness/mod.rs +++ b/daemon/tests/harness/mod.rs @@ -1,6 +1,6 @@ -use crate::harness::mocks::monitor::Monitor; -use crate::harness::mocks::oracle::Oracle; -use crate::harness::mocks::wallet::Wallet; +use crate::harness::mocks::monitor::MonitorActor; +use crate::harness::mocks::oracle::OracleActor; +use crate::harness::mocks::wallet::WalletActor; use crate::schnorrsig; use daemon::maker_cfd::CfdAction; use daemon::model::cfd::{Cfd, Order}; @@ -18,54 +18,43 @@ pub mod bdk; pub mod cfd_protocol; pub mod mocks; -// TODO: Remove all these parameters once we have the mock framework (because we have -// Arcs then and can just default inside) -pub async fn start_both( - taker_oracle: Oracle, - taker_monitor: Monitor, - taker_wallet: Wallet, - maker_oracle: Oracle, - maker_monitor: Monitor, - maker_wallet: Wallet, -) -> (Maker, Taker) { +pub async fn start_both() -> (Maker, Taker) { let oracle_pk: schnorrsig::PublicKey = schnorrsig::PublicKey::from_str( "ddd4636845a90185991826be5a494cde9f4a6947b1727217afedc6292fa4caf7", ) .unwrap(); - let maker = Maker::start(oracle_pk, maker_oracle, maker_monitor, maker_wallet).await; - let taker = Taker::start( - oracle_pk, - maker.listen_addr, - taker_oracle, - taker_monitor, - taker_wallet, - ) - .await; + let maker = Maker::start(oracle_pk).await; + let taker = Taker::start(oracle_pk, maker.listen_addr).await; (maker, taker) } /// Maker Test Setup #[derive(Clone)] pub struct Maker { - pub cfd_actor_addr: - xtra::Address>, + pub cfd_actor_addr: xtra::Address< + maker_cfd::Actor, + >, pub order_feed: watch::Receiver>, pub cfd_feed: watch::Receiver>, #[allow(dead_code)] // we need to keep the xtra::Address for refcounting pub inc_conn_actor_addr: xtra::Address, pub listen_addr: SocketAddr, + pub mocks: mocks::Mocks, } impl Maker { - pub async fn start( - oracle_pk: schnorrsig::PublicKey, - oracle: Oracle, - monitor: Monitor, - wallet: Wallet, - ) -> Self { + pub async fn start(oracle_pk: schnorrsig::PublicKey) -> Self { let db = in_memory_db().await; + let mocks = mocks::Mocks::default(); + + let (oracle, monitor, wallet) = mocks::create_actors(&mocks); + + // Sync method need to be mocked before the actors start + mocks.oracle.lock().await.expect_sync().return_const(()); + mocks.monitor.lock().await.expect_sync().return_const(()); + let wallet_addr = wallet.create(None).spawn_global(); let settlement_time_interval_hours = time::Duration::hours(24); @@ -106,6 +95,7 @@ impl Maker { cfd_feed: maker.cfd_feed_receiver, inc_conn_actor_addr: maker.inc_conn_addr, listen_addr: address, + mocks, } } @@ -131,17 +121,12 @@ impl Maker { pub struct Taker { pub order_feed: watch::Receiver>, pub cfd_feed: watch::Receiver>, - pub cfd_actor_addr: xtra::Address>, + pub cfd_actor_addr: xtra::Address>, + pub mocks: mocks::Mocks, } impl Taker { - pub async fn start( - oracle_pk: schnorrsig::PublicKey, - maker_address: SocketAddr, - oracle: Oracle, - monitor: Monitor, - wallet: Wallet, - ) -> Self { + pub async fn start(oracle_pk: schnorrsig::PublicKey, maker_address: SocketAddr) -> Self { let connection::Actor { send_to_maker, read_from_maker, @@ -149,6 +134,13 @@ impl Taker { let db = in_memory_db().await; + let mocks = mocks::Mocks::default(); + let (oracle, monitor, wallet) = mocks::create_actors(&mocks); + + // Sync method need to be mocked before the actors start + mocks.oracle.lock().await.expect_sync().return_const(()); + mocks.monitor.lock().await.expect_sync().return_const(()); + let wallet_addr = wallet.create(None).spawn_global(); let taker = daemon::TakerActorSystem::new( @@ -167,6 +159,7 @@ impl Taker { order_feed: taker.order_feed_receiver, cfd_feed: taker.cfd_feed_receiver, cfd_actor_addr: taker.cfd_actor_addr, + mocks, } }