diff --git a/lana/sim-bootstrap/src/config.rs b/lana/sim-bootstrap/src/config.rs index 0c18bcb2f..b1b2a98e6 100644 --- a/lana/sim-bootstrap/src/config.rs +++ b/lana/sim-bootstrap/src/config.rs @@ -18,7 +18,7 @@ impl Default for BootstrapConfig { } fn default_num_facilities() -> u32 { - 4 + 1 } fn default_num_customers() -> u32 { diff --git a/lana/sim-bootstrap/src/lib.rs b/lana/sim-bootstrap/src/lib.rs index e1e5e6bda..04a4891d6 100644 --- a/lana/sim-bootstrap/src/lib.rs +++ b/lana/sim-bootstrap/src/lib.rs @@ -5,9 +5,6 @@ mod config; use futures::StreamExt; use rust_decimal_macros::dec; -use std::sync::{Arc, Mutex}; - -use std::collections::HashSet; use lana_app::{ app::LanaApp, @@ -20,32 +17,28 @@ pub use config::*; pub async fn run( superuser_email: String, - app: LanaApp, + app: &LanaApp, config: BootstrapConfig, ) -> anyhow::Result<()> { - dbg!(&config); - let sub = superuser_subject(&superuser_email, &app).await?; + let sub = superuser_subject(&superuser_email, app).await?; - let customer_ids = create_customers(&sub, &app, &config).await?; + let customer_ids = create_customers(&sub, app, &config).await?; - make_deposit(&sub, &app, &customer_ids, &config).await?; + make_deposit(&sub, app, &customer_ids, &config).await?; - let mut facility_ids = HashSet::new(); + let mut handles = Vec::new(); for customer_id in customer_ids { for _ in 0..config.num_facilities { - let id = create_facility_for_customer(&sub, &app, customer_id).await?; - facility_ids.insert(id); + let spawned_app = app.clone(); + + let handle = tokio::spawn(async move { + create_and_process_facility(sub.clone(), customer_id.clone(), spawned_app).await + }); + handles.push(handle); } } - let facility_ids = Arc::new(Mutex::new(facility_ids)); - - let spawned_app = app.clone(); - let _handle = tokio::spawn(async move { - let _ = process_repayment(sub, facility_ids, spawned_app).await; - }); - println!("waiting for real time"); sim_time::wait_until_realtime().await; println!("done"); @@ -53,43 +46,60 @@ pub async fn run( Ok(()) } -async fn process_repayment( +async fn create_and_process_facility( sub: Subject, - facility_ids: Arc>>, + customer_id: CustomerId, app: LanaApp, ) -> anyhow::Result<()> { + let terms = std_terms(); + + let cf = app + .credit_facilities() + .initiate( + &sub, + customer_id, + UsdCents::try_from_usd(dec!(10_000_000))?, + terms, + ) + .await?; + let mut stream = app.outbox().listen_persisted(None).await?; while let Some(msg) = stream.next().await { match &msg.payload { - Some(LanaEvent::Credit(CreditEvent::AccrualExecuted { - id: cf_id, amount, .. - })) if { - let ids = facility_ids.lock().unwrap(); - ids.contains(cf_id) && amount > &UsdCents::ZERO - } => + Some(LanaEvent::Credit(CreditEvent::FacilityApproved { id })) if cf.id == *id => { + app.credit_facilities() + .update_collateral(&sub, cf.id, Satoshis::try_from_btc(dec!(230))?) + .await?; + } + Some(LanaEvent::Credit(CreditEvent::FacilityActivated { id, .. })) if cf.id == *id => { + app.credit_facilities() + .initiate_disbursal(&sub, cf.id, UsdCents::try_from_usd(dec!(1_000_000))?) + .await?; + } + Some(LanaEvent::Credit(CreditEvent::AccrualExecuted { id, amount, .. })) + if { cf.id == *id && amount > &UsdCents::ZERO } => { let _ = app .credit_facilities() - .record_payment(&sub, *cf_id, *amount) + .record_payment(&sub, *id, *amount) .await; - let mut cf = app + let mut facility = app .credit_facilities() - .find_by_id(&sub, *cf_id) + .find_by_id(&sub, *id) .await? .expect("cf exists"); - if cf.interest_accrual_in_progress().is_none() { + if facility.interest_accrual_in_progress().is_none() { app.credit_facilities() - .record_payment(&sub, cf.id, cf.outstanding().total()) + .record_payment(&sub, facility.id, facility.outstanding().total()) .await?; app.credit_facilities() - .complete_facility(&sub, cf.id) + .complete_facility(&sub, facility.id) .await?; } } - Some(LanaEvent::Credit(CreditEvent::FacilityCompleted { id: cf_id, .. })) => { - let mut ids = facility_ids.lock().unwrap(); - if ids.remove(cf_id) && ids.is_empty() { + Some(LanaEvent::Credit(CreditEvent::FacilityCompleted { id, .. })) => { + if cf.id == *id { break; } } @@ -177,41 +187,6 @@ async fn superuser_subject(superuser_email: &String, app: &LanaApp) -> anyhow::R Ok(Subject::from(superuser.id)) } -async fn create_facility_for_customer( - sub: &Subject, - app: &LanaApp, - customer_id: CustomerId, -) -> anyhow::Result { - let terms = std_terms(); - - let cf = app - .credit_facilities() - .initiate( - sub, - customer_id, - UsdCents::try_from_usd(dec!(10_000_000))?, - terms, - ) - .await?; - - let id = cf.id; - - // hack to ensure that credit facility is activated - tokio::time::sleep(std::time::Duration::from_millis(500)).await; - - app.credit_facilities() - .update_collateral(sub, id, Satoshis::try_from_btc(dec!(230))?) - .await?; - - // hack to ensure that credit facility is activated - tokio::time::sleep(std::time::Duration::from_millis(500)).await; - - app.credit_facilities() - .initiate_disbursal(sub, id, UsdCents::try_from_usd(dec!(1_000_000))?) - .await?; - Ok(id) -} - fn std_terms() -> TermValues { TermValues::builder() .annual_rate(dec!(12))