-
Notifications
You must be signed in to change notification settings - Fork 7
/
redeem.rs
71 lines (66 loc) · 2.32 KB
/
redeem.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use std::{sync::Arc, time::Duration};
use runtime::{RedeemPallet, RequestRedeemEvent, ShutdownSender, SpacewalkParachain};
use service::{spawn_cancelable, Error as ServiceError};
use crate::{oracle::OracleAgent, requests::*, system::VaultIdManager, Error};
/// Listen for RequestRedeemEvent directed at this vault; upon reception, transfer
/// the respective Stellar asset and call execute_redeem.
///
/// # Arguments
///
/// * `parachain_rpc` - the parachain RPC handle
/// * `payment_margin` - minimum time to the the redeem execution deadline to make the stellar
/// payment.
pub async fn listen_for_redeem_requests(
shutdown_tx: ShutdownSender,
parachain_rpc: SpacewalkParachain,
vault_id_manager: VaultIdManager,
payment_margin: Duration,
oracle_agent: Arc<OracleAgent>,
) -> Result<(), ServiceError<Error>> {
parachain_rpc
.on_event::<RequestRedeemEvent, _, _, _>(
|event| async {
let vault = match vault_id_manager.get_vault(&event.vault_id).await {
Some(x) => x,
None => return, // event not directed at this vault
};
// within this event callback, we captured the arguments of
// listen_for_redeem_requests by reference. Since spawn requires static lifetimes,
// we will need to capture the arguments by value rather than by reference, so clone
// these:
let parachain_rpc = parachain_rpc.clone();
// Spawn a new task so that we handle these events concurrently
let oracle_agent = oracle_agent.clone();
spawn_cancelable(shutdown_tx.subscribe(), async move {
tracing::info!(
"Received new RequestRedeemEvent {:?}. Trying to execute...",
event
);
let result = async {
let request = Request::from_redeem_request(
event.redeem_id,
parachain_rpc.get_redeem_request(event.redeem_id).await?,
payment_margin,
)?;
request.pay_and_execute(parachain_rpc, vault, oracle_agent).await
}
.await;
match result {
Ok(_) => tracing::info!(
"Completed Redeem request #{:?} with amount {}",
event.redeem_id,
event.amount
),
Err(e) => tracing::error!(
"Failed to process Redeem request #{} due to error: {}",
event.redeem_id,
e.to_string()
),
}
});
},
|error| tracing::error!("Error reading redeem event: {}", error.to_string()),
)
.await?;
Ok(())
}