From cc7c9cc6001eb5466e074286ca4001ec8f0b4e7d Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Fri, 5 Jul 2024 14:57:12 +0800 Subject: [PATCH 01/63] add logs; change log level --- clients/vault/src/oracle/collector/handler.rs | 2 +- clients/vault/src/oracle/collector/proof_builder.rs | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/clients/vault/src/oracle/collector/handler.rs b/clients/vault/src/oracle/collector/handler.rs index 3eb7c3c7f..9d663edbf 100644 --- a/clients/vault/src/oracle/collector/handler.rs +++ b/clients/vault/src/oracle/collector/handler.rs @@ -25,7 +25,7 @@ impl ScpMessageCollector { // we are only interested with `ScpStExternalize`. Other messages are ignored. if let ScpStatementPledges::ScpStExternalize(stmt) = &env.statement.pledges { - tracing::trace!( + tracing::info!( "Handling Incoming ScpEnvelopes for slot {slot}: SCPStExternalize found: {}", to_base64_xdr_string(stmt) ); diff --git a/clients/vault/src/oracle/collector/proof_builder.rs b/clients/vault/src/oracle/collector/proof_builder.rs index 89dbeb2e0..f43eb1aea 100644 --- a/clients/vault/src/oracle/collector/proof_builder.rs +++ b/clients/vault/src/oracle/collector/proof_builder.rs @@ -68,6 +68,7 @@ impl Proof { impl ScpMessageCollector { /// fetch envelopes not found in the collector async fn fetch_missing_envelopes(&self, slot: Slot, sender: &StellarMessageSender) { + tracing::info!("fetch_missing_envelopes(): FOR SLOT {slot} check_slot_still_recoverable_from_overlay: LAST SLOT INDEX: {}",self.last_slot_index()); // If the current slot is still in the range of 'remembered' slots if check_slot_still_recoverable_from_overlay(self.last_slot_index(), slot) { tracing::debug!( @@ -75,8 +76,8 @@ impl ScpMessageCollector { ); self.ask_node_for_envelopes(slot, sender).await; } else { - tracing::debug!( - "fetch_missing_envelopes(): Proof Building for slot {slot}: fetching missing envelopes from Archive Node..." + tracing::info!( + "fetch_missing_envelopes(): Proof Building for slot {slot}: fetching from Archive Node..." ); self.ask_archive_for_envelopes(slot).await; } @@ -158,6 +159,7 @@ impl ScpMessageCollector { match tx_set { Some(res) => Some(res), None => { + tracing::info!("get_txset(): FOR SLOT {slot} check_slot_still_recoverable_from_overlay: LAST SLOT INDEX: {}",self.last_slot_index()); // If the current slot is still in the range of 'remembered' slots if check_slot_still_recoverable_from_overlay(self.last_slot_index(), slot) { self.fetch_missing_txset_from_overlay(slot, sender).await; @@ -210,7 +212,7 @@ impl ScpMessageCollector { /// * `envelopes_map_lock` - the map to insert the envelopes to. /// * `slot` - the slot where the envelopes belong to fn get_envelopes_from_horizon_archive(&self, slot: Slot) -> impl Future { - tracing::debug!("get_envelopes_from_horizon_archive(): Fetching SCP envelopes from horizon archive for slot {slot}..."); + tracing::info!("get_envelopes_from_horizon_archive(): Fetching SCP envelopes from horizon archive for slot {slot}..."); let envelopes_map_arc = self.envelopes_map_clone(); let env_from_archive_map = self.env_from_archive_map_clone(); From 5ea8b716b1a189eb8a01127cfe8f06ae58300155 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Fri, 5 Jul 2024 18:14:18 +0800 Subject: [PATCH 02/63] adding started logs for each task --- clients/vault/src/cancellation.rs | 1 + clients/vault/src/issue.rs | 4 ++++ clients/vault/src/oracle/collector/handler.rs | 2 +- clients/vault/src/system.rs | 3 +++ clients/wallet/src/horizon/horizon.rs | 1 + 5 files changed, 10 insertions(+), 1 deletion(-) diff --git a/clients/vault/src/cancellation.rs b/clients/vault/src/cancellation.rs index 246922b81..64f829226 100644 --- a/clients/vault/src/cancellation.rs +++ b/clients/vault/src/cancellation.rs @@ -204,6 +204,7 @@ impl Cancel mut self, mut event_listener: Receiver, ) -> Result<(), RuntimeError> { + tracing::info!("handle_cancellation(): started"); let mut list_state = ListState::Invalid; let mut active_requests: Vec = vec![]; diff --git a/clients/vault/src/issue.rs b/clients/vault/src/issue.rs index 6ceee56aa..2a3f5f4ca 100644 --- a/clients/vault/src/issue.rs +++ b/clients/vault/src/issue.rs @@ -60,6 +60,7 @@ pub async fn listen_for_issue_requests( issues: ArcRwLock, memos_to_issue_ids: ArcRwLock, ) -> Result<(), ServiceError> { + tracing::info!("listen_for_issue_requests(): started"); // Use references to prevent 'moved closure' errors let parachain_rpc = ¶chain_rpc; let vault_public_key = &vault_public_key; @@ -113,6 +114,7 @@ pub async fn listen_for_issue_cancels( issues: ArcRwLock, memos_to_issue_ids: ArcRwLock, ) -> Result<(), ServiceError> { + tracing::info!("listen_for_issue_cancels(): started"); let issues = &issues; let memos_to_issue_ids = &memos_to_issue_ids; @@ -145,6 +147,7 @@ pub async fn listen_for_executed_issues( issues: ArcRwLock, memos_to_issue_ids: ArcRwLock, ) -> Result<(), ServiceError> { + tracing::info!("listen_for_executed_issues(): started"); let issues = &issues; let memos_to_issue_ids = &memos_to_issue_ids; @@ -253,6 +256,7 @@ pub async fn process_issues_requests( issues: ArcRwLock, memos_to_issue_ids: ArcRwLock, ) -> Result<(), ServiceError> { + tracing::info!("process_issue_requests(): started"); // collects all the tasks that are executed or about to be executed. let mut processed_map = HashMap::new(); diff --git a/clients/vault/src/oracle/collector/handler.rs b/clients/vault/src/oracle/collector/handler.rs index 9d663edbf..3eb7c3c7f 100644 --- a/clients/vault/src/oracle/collector/handler.rs +++ b/clients/vault/src/oracle/collector/handler.rs @@ -25,7 +25,7 @@ impl ScpMessageCollector { // we are only interested with `ScpStExternalize`. Other messages are ignored. if let ScpStatementPledges::ScpStExternalize(stmt) = &env.statement.pledges { - tracing::info!( + tracing::trace!( "Handling Incoming ScpEnvelopes for slot {slot}: SCPStExternalize found: {}", to_base64_xdr_string(stmt) ); diff --git a/clients/vault/src/system.rs b/clients/vault/src/system.rs index c654d54ad..cabccd847 100644 --- a/clients/vault/src/system.rs +++ b/clients/vault/src/system.rs @@ -251,6 +251,7 @@ async fn active_block_listener( issue_tx: Sender, replace_tx: Sender, ) -> Result<(), ServiceError> { + tracing::info!("active_block_listener(): started"); let issue_tx = &issue_tx; let replace_tx = &replace_tx; parachain_rpc @@ -297,6 +298,7 @@ impl Service for VaultService { self.try_shutdown_wallet().await; if let Err(error) = result { + tracing::error!("start(): Failed to run service: {error:?}"); let _ = self.shutdown.send(()); Err(error) } else { @@ -609,6 +611,7 @@ impl VaultService { ( "Restart Timer", run(async move { + tracing::info!("Periodic restart in 3 hours."); tokio::time::sleep(RESTART_INTERVAL).await; tracing::info!("Initiating periodic restart..."); Err(ServiceError::ClientShutdown) diff --git a/clients/wallet/src/horizon/horizon.rs b/clients/wallet/src/horizon/horizon.rs index 5e54de558..f2adf2719 100644 --- a/clients/wallet/src/horizon/horizon.rs +++ b/clients/wallet/src/horizon/horizon.rs @@ -320,6 +320,7 @@ where U: Clone + IsEmptyExt, Filter: FilterWith + Clone, { + tracing::info!("listen_for_new_transactions(): started"); let horizon_client = reqwest::Client::new(); let mut fetcher = HorizonFetcher::new(horizon_client, vault_account_public_key, is_public_network); From 9a4b1c466c485a143f2e54cb82c61d14e9bd4f94 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:19:11 +0800 Subject: [PATCH 03/63] changing debug logs to info --- clients/vault/src/oracle/collector/collector.rs | 4 ++-- clients/vault/src/oracle/collector/handler.rs | 4 ++-- clients/vault/src/requests/execution.rs | 1 + clients/vault/src/system.rs | 1 + 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/clients/vault/src/oracle/collector/collector.rs b/clients/vault/src/oracle/collector/collector.rs index b8b57bb66..2591c868d 100644 --- a/clients/vault/src/oracle/collector/collector.rs +++ b/clients/vault/src/oracle/collector/collector.rs @@ -155,7 +155,7 @@ impl ScpMessageCollector { value.push(scp_envelope); envelopes_map.insert(slot, value); } else { - tracing::debug!("Collecting SCPEnvelopes for slot {slot}: success"); + tracing::info!("Collecting SCPEnvelopes for slot {slot}: success"); tracing::trace!( "Collecting SCPEnvelopes for slot {slot}: the scp envelope: {}", to_base64_xdr_string(&scp_envelope.statement) @@ -167,7 +167,7 @@ impl ScpMessageCollector { pub(super) fn save_txset_hash_and_slot(&self, txset_hash: TxSetHash, slot: Slot) { // save the mapping of the hash of the txset and the slot. let mut m = self.txset_and_slot_map.write(); - tracing::debug!("Collecting TxSet for slot {slot}: saving a map of txset_hash..."); + tracing::info!("Collecting TxSet for slot {slot}: saving a map of txset_hash..."); tracing::trace!( "Collecting TxSet for slot {slot}: the txset_hash: {}", hex::encode(&txset_hash) diff --git a/clients/vault/src/oracle/collector/handler.rs b/clients/vault/src/oracle/collector/handler.rs index 3eb7c3c7f..850e6cc49 100644 --- a/clients/vault/src/oracle/collector/handler.rs +++ b/clients/vault/src/oracle/collector/handler.rs @@ -25,7 +25,7 @@ impl ScpMessageCollector { // we are only interested with `ScpStExternalize`. Other messages are ignored. if let ScpStatementPledges::ScpStExternalize(stmt) = &env.statement.pledges { - tracing::trace!( + tracing::info!( "Handling Incoming ScpEnvelopes for slot {slot}: SCPStExternalize found: {}", to_base64_xdr_string(stmt) ); @@ -37,7 +37,7 @@ impl ScpMessageCollector { // Check if collector has a record of this hash. if self.is_txset_new(&txset_hash, &slot) { // if it doesn't exist, let's request from the Stellar Node. - tracing::debug!( + tracing::info!( "Handling Incoming ScpEnvelopes for slot {slot}: requesting TxSet..." ); message_sender.send(StellarMessage::GetTxSet(txset_hash)).await?; diff --git a/clients/vault/src/requests/execution.rs b/clients/vault/src/requests/execution.rs index 3273e836d..9aa734a55 100644 --- a/clients/vault/src/requests/execution.rs +++ b/clients/vault/src/requests/execution.rs @@ -291,6 +291,7 @@ pub async fn execute_open_requests( oracle_agent: Arc, payment_margin: Duration, ) -> Result<(), ServiceError> { + tracing::info!("execute_open_requests(): started"); let parachain_rpc_ref = ¶chain_rpc; // get all redeem and replace requests diff --git a/clients/vault/src/system.rs b/clients/vault/src/system.rs index cabccd847..85beea31e 100644 --- a/clients/vault/src/system.rs +++ b/clients/vault/src/system.rs @@ -332,6 +332,7 @@ async fn run_and_monitor_tasks( publish_tokio_metrics(metrics_iterators), )); + tracing::info!("run_and_monitor_tasks(): running all tasks..."); match join(tokio_metrics, join_all(tasks)).await { (Ok(Err(err)), _) => Err(err), (_, results) => results From 8b75f56530214594b08161371198423493fb413e Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Thu, 11 Jul 2024 18:50:54 +0800 Subject: [PATCH 04/63] reduce restart interval --- clients/vault/src/oracle/agent.rs | 1 + clients/vault/src/system.rs | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index dc72c8982..016ef96b7 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -156,6 +156,7 @@ impl OracleAgent { timeout(Duration::from_secs(timeout_seconds), async move { loop { + tracing::info!("get_proof(): attempt to build proof for slot {slot}"); let stellar_sender = sender.clone(); let collector = collector.read().await; match collector.build_proof(slot, &stellar_sender).await { diff --git a/clients/vault/src/system.rs b/clients/vault/src/system.rs index 85beea31e..9abc5c520 100644 --- a/clients/vault/src/system.rs +++ b/clients/vault/src/system.rs @@ -45,7 +45,7 @@ pub const AUTHORS: &str = env!("CARGO_PKG_AUTHORS"); pub const NAME: &str = env!("CARGO_PKG_NAME"); pub const ABOUT: &str = env!("CARGO_PKG_DESCRIPTION"); -const RESTART_INTERVAL: Duration = Duration::from_secs(10800); // restart every 3 hours +const RESTART_INTERVAL: Duration = Duration::from_secs(7200); // restart every 3 hours #[derive(Clone, Debug)] pub struct VaultData { @@ -263,6 +263,8 @@ async fn active_block_listener( |err| tracing::error!("Error (UpdateActiveBlockEvent): {}", err.to_string()), ) .await?; + + tracing::info!("active_block_listener(): ended"); Ok(()) } From 519b7ebb119d42460108a75fc07d026bf7d3cae4 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Fri, 12 Jul 2024 01:34:24 +0800 Subject: [PATCH 05/63] revert to debug the other logs --- clients/vault/src/error.rs | 3 --- clients/vault/src/oracle/collector/collector.rs | 4 ++-- clients/vault/src/oracle/collector/handler.rs | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/clients/vault/src/error.rs b/clients/vault/src/error.rs index 77361e857..2ac24e277 100644 --- a/clients/vault/src/error.rs +++ b/clients/vault/src/error.rs @@ -1,4 +1,3 @@ -use jsonrpc_core_client::RpcError; use parity_scale_codec::Error as CodecError; use sp_std::str::Utf8Error; use thiserror::Error; @@ -22,8 +21,6 @@ pub enum Error { #[error("Faucet url not set")] FaucetUrlNotSet, - #[error("RPC error: {0}")] - RpcError(#[from] RpcError), #[error("RuntimeError: {0}")] RuntimeError(#[from] RuntimeError), #[error("CodecError: {0}")] diff --git a/clients/vault/src/oracle/collector/collector.rs b/clients/vault/src/oracle/collector/collector.rs index 2591c868d..b8b57bb66 100644 --- a/clients/vault/src/oracle/collector/collector.rs +++ b/clients/vault/src/oracle/collector/collector.rs @@ -155,7 +155,7 @@ impl ScpMessageCollector { value.push(scp_envelope); envelopes_map.insert(slot, value); } else { - tracing::info!("Collecting SCPEnvelopes for slot {slot}: success"); + tracing::debug!("Collecting SCPEnvelopes for slot {slot}: success"); tracing::trace!( "Collecting SCPEnvelopes for slot {slot}: the scp envelope: {}", to_base64_xdr_string(&scp_envelope.statement) @@ -167,7 +167,7 @@ impl ScpMessageCollector { pub(super) fn save_txset_hash_and_slot(&self, txset_hash: TxSetHash, slot: Slot) { // save the mapping of the hash of the txset and the slot. let mut m = self.txset_and_slot_map.write(); - tracing::info!("Collecting TxSet for slot {slot}: saving a map of txset_hash..."); + tracing::debug!("Collecting TxSet for slot {slot}: saving a map of txset_hash..."); tracing::trace!( "Collecting TxSet for slot {slot}: the txset_hash: {}", hex::encode(&txset_hash) diff --git a/clients/vault/src/oracle/collector/handler.rs b/clients/vault/src/oracle/collector/handler.rs index 850e6cc49..de2cc1420 100644 --- a/clients/vault/src/oracle/collector/handler.rs +++ b/clients/vault/src/oracle/collector/handler.rs @@ -25,7 +25,7 @@ impl ScpMessageCollector { // we are only interested with `ScpStExternalize`. Other messages are ignored. if let ScpStatementPledges::ScpStExternalize(stmt) = &env.statement.pledges { - tracing::info!( + tracing::debug!( "Handling Incoming ScpEnvelopes for slot {slot}: SCPStExternalize found: {}", to_base64_xdr_string(stmt) ); From 878470d49024ba1f692d76150a4febef2c17e469 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 30 Jul 2024 21:24:58 +0800 Subject: [PATCH 06/63] make listen() async; use tokio::select --- clients/stellar-relay-lib/examples/connect.rs | 2 +- clients/stellar-relay-lib/src/overlay.rs | 38 +++++------ clients/stellar-relay-lib/src/tests/mod.rs | 4 +- clients/vault/src/oracle/agent.rs | 66 +++++++++---------- clients/vault/src/oracle/collector/handler.rs | 2 +- clients/vault/src/system.rs | 4 ++ 6 files changed, 55 insertions(+), 61 deletions(-) diff --git a/clients/stellar-relay-lib/examples/connect.rs b/clients/stellar-relay-lib/examples/connect.rs index 6e3283dc7..d63a73462 100644 --- a/clients/stellar-relay-lib/examples/connect.rs +++ b/clients/stellar-relay-lib/examples/connect.rs @@ -24,7 +24,7 @@ async fn main() -> Result<(), Box> { let mut overlay_connection = connect_to_stellar_overlay_network(cfg, &secret_key).await?; - while let Ok(Some(msg)) = overlay_connection.listen() { + while let Ok(Some(msg)) = overlay_connection.listen().await { match msg { StellarMessage::ScpMessage(msg) => { let node_id = msg.statement.node_id.to_encoding(); diff --git a/clients/stellar-relay-lib/src/overlay.rs b/clients/stellar-relay-lib/src/overlay.rs index 6ff44320a..13f1f8349 100644 --- a/clients/stellar-relay-lib/src/overlay.rs +++ b/clients/stellar-relay-lib/src/overlay.rs @@ -1,16 +1,17 @@ -use substrate_stellar_sdk::types::{ErrorCode, StellarMessage}; +use std::time::Duration; +use async_std::future::timeout; +use substrate_stellar_sdk::types::{StellarMessage}; use tokio::sync::{ mpsc, mpsc::{ - error::{SendError, TryRecvError}, + error::{SendError}, Sender, }, }; -use tracing::{error, info}; +use tracing::{debug, info}; use crate::{ connection::{poll_messages_from_stellar, ConnectionInfo, Connector}, - helper::error_to_string, node::NodeInfo, Error, }; @@ -56,26 +57,16 @@ impl StellarOverlayConnection { }) } - pub fn listen(&mut self) -> Result, Error> { - loop { - if !self.is_alive() { - return Err(Error::Disconnected); - } - - match self.receiver.try_recv() { - Ok(StellarMessage::ErrorMsg(e)) => { - error!("listen(): received error message: {e:?}"); - if e.code == ErrorCode::ErrConf || e.code == ErrorCode::ErrAuth { - return Err(Error::ConnectionFailed(error_to_string(e))); - } - - return Ok(None); - }, - Ok(msg) => return Ok(Some(msg)), - Err(TryRecvError::Disconnected) => return Err(Error::Disconnected), - Err(TryRecvError::Empty) => continue, - } + /// Listens for upcoming messages from Stellar Node via a receiver. + /// The sender pair can be found in [fn poll_messages_from_stellar](../src/connection/connector/message_reader.rs) + pub async fn listen(&mut self) -> Result, Error> { + if !self.is_alive() { + debug!("listen(): sender half of overlay has closed."); + return Err(Error::Disconnected) } + + timeout(Duration::from_secs(1), self.receiver.recv()).await + .map_err(|_| Error::Timeout) } pub fn is_alive(&mut self) -> bool { @@ -96,6 +87,7 @@ impl StellarOverlayConnection { impl Drop for StellarOverlayConnection { fn drop(&mut self) { + debug!("drop(): shutting down StellarOverlayConnection"); self.stop(); } } diff --git a/clients/stellar-relay-lib/src/tests/mod.rs b/clients/stellar-relay-lib/src/tests/mod.rs index e635a3493..60071bc19 100644 --- a/clients/stellar-relay-lib/src/tests/mod.rs +++ b/clients/stellar-relay-lib/src/tests/mod.rs @@ -52,7 +52,7 @@ async fn stellar_overlay_should_receive_scp_messages() { timeout(Duration::from_secs(300), async move { let mut ov_conn_locked = ov_conn.lock().await; - if let Ok(Some(msg)) = ov_conn_locked.listen() { + if let Ok(Some(msg)) = ov_conn_locked.listen().await { scps_vec_clone.lock().await.push(msg); ov_conn_locked.stop(); @@ -89,7 +89,7 @@ async fn stellar_overlay_should_receive_tx_set() { timeout(Duration::from_secs(500), async move { let mut ov_conn_locked = ov_conn.lock().await; - while let Ok(Some(msg)) = ov_conn_locked.listen() { + while let Ok(Some(msg)) = ov_conn_locked.listen().await { match msg { StellarMessage::ScpMessage(msg) => { if let ScpStatementPledges::ScpStExternalize(stmt) = &msg.statement.pledges { diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index 016ef96b7..d7836a2fe 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -1,7 +1,7 @@ use std::{sync::Arc, time::Duration}; use tokio::{ - sync::{mpsc, mpsc::error::TryRecvError, RwLock}, + sync::{mpsc, RwLock}, time::{sleep, timeout}, }; @@ -84,42 +84,40 @@ pub async fn start_oracle_agent( // Node let (disconnect_signal_sender, mut disconnect_signal_receiver) = mpsc::channel::<()>(2); + let sender_clone = overlay_conn.sender(); tokio::spawn(async move { - let sender_clone = overlay_conn.sender(); loop { - match disconnect_signal_receiver.try_recv() { - // if a disconnect signal was sent, disconnect from Stellar. - Ok(_) | Err(TryRecvError::Disconnected) => { - tracing::info!("start_oracle_agent(): disconnect overlay..."); - break; - }, - Err(TryRecvError::Empty) => {}, - } - - // listen for messages from Stellar - match overlay_conn.listen() { - Ok(Some(msg)) => { - let msg_as_str = to_base64_xdr_string(&msg); - if let Err(e) = - handle_message(msg, collector_clone.clone(), &sender_clone).await - { - tracing::error!( - "start_oracle_agent(): failed to handle message: {msg_as_str}: {e:?}" - ); - } + tokio::select! { + _ = sleep(Duration::from_millis(100)) => { + tracing::info!("start_oracle_agent(): go to sleep"); }, - Ok(None) => {}, - // connection got lost - Err(e) => { - tracing::error!("start_oracle_agent(): encounter error in overlay: {e:?}"); - - if let Err(e) = shutdown_sender_clone.send(()) { - tracing::error!( - "start_oracle_agent(): Failed to send shutdown signal in thread: {e:?}" - ); + // if a disconnect signal was sent, disconnect from Stellar. + result = disconnect_signal_receiver.recv() => { + if result.is_none() { + tracing::info!("start_oracle_agent(): disconnect overlay..."); + break } - break; }, + result = overlay_conn.listen() => { + tracing::info!("start_oracle_agent(): received message from overlay"); + match result { + Ok(Some(msg)) => { + let msg_as_str = to_base64_xdr_string(&msg); + if let Err(e) = handle_message(msg, collector_clone.clone(), &sender_clone).await { + tracing::error!("start_oracle_agent(): failed to handle message: {msg_as_str}: {e:?}"); + } + }, + Ok(None) => {}, + // connection got lost + Err(e) => { + tracing::error!("start_oracle_agent(): encounter error in overlay: {e:?}"); + + if let Err(e) = shutdown_sender_clone.send(()) { + tracing::error!("start_oracle_agent(): Failed to send shutdown signal in thread: {e:?}"); + } + break + }, + }}, } } @@ -164,12 +162,12 @@ impl OracleAgent { drop(collector); // give 10 seconds interval for every retry sleep(Duration::from_secs(10)).await; - continue; + continue }, Some(proof) => { tracing::info!("get_proof(): Successfully build proof for slot {slot}"); tracing::trace!(" with proof: {proof:?}"); - return Ok(proof); + return Ok(proof) }, } } diff --git a/clients/vault/src/oracle/collector/handler.rs b/clients/vault/src/oracle/collector/handler.rs index de2cc1420..feb889455 100644 --- a/clients/vault/src/oracle/collector/handler.rs +++ b/clients/vault/src/oracle/collector/handler.rs @@ -37,7 +37,7 @@ impl ScpMessageCollector { // Check if collector has a record of this hash. if self.is_txset_new(&txset_hash, &slot) { // if it doesn't exist, let's request from the Stellar Node. - tracing::info!( + tracing::debug!( "Handling Incoming ScpEnvelopes for slot {slot}: requesting TxSet..." ); message_sender.send(StellarMessage::GetTxSet(txset_hash)).await?; diff --git a/clients/vault/src/system.rs b/clients/vault/src/system.rs index 9abc5c520..03ac84600 100644 --- a/clients/vault/src/system.rs +++ b/clients/vault/src/system.rs @@ -795,6 +795,8 @@ impl VaultService { self.execute_open_requests(oracle_agent.clone()); + tracing::info!("CONTINUE ON HOOY"); + // issue handling // this vec is passed to the stellar wallet to filter out transactions that are not relevant // this has to be modified every time the issue set changes @@ -806,6 +808,8 @@ impl VaultService { issue::initialize_issue_set(&self.spacewalk_parachain, &issue_map, &memos_to_issue_ids) .await?; + tracing::info!("ISSUE INITIALIZE ISSUE SET!!!"); + let ledger_env_map: ArcRwLock = Arc::new(RwLock::new(HashMap::new())); tracing::info!("Starting all services..."); From 67e540c7581dd55f3c20d0f3c3031d2cd6ab6501 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Thu, 1 Aug 2024 22:46:16 +0800 Subject: [PATCH 07/63] first iteration --- clients/stellar-relay-lib/Cargo.toml | 2 + clients/stellar-relay-lib/examples/connect.rs | 1 + clients/vault/src/oracle/agent.rs | 104 ++++++++++++------ .../vault/src/oracle/collector/collector.rs | 1 - clients/vault/src/system.rs | 66 +++++------ 5 files changed, 110 insertions(+), 64 deletions(-) diff --git a/clients/stellar-relay-lib/Cargo.toml b/clients/stellar-relay-lib/Cargo.toml index 5f465c8f0..8aebded17 100644 --- a/clients/stellar-relay-lib/Cargo.toml +++ b/clients/stellar-relay-lib/Cargo.toml @@ -15,6 +15,8 @@ serial_test = "0.9.0" wallet = { path = "../wallet", features = ["testing-utils"] } [dependencies] +console-subscriber = { version = "0.4.0" } + hex = "0.4.3" tracing = { version = "0.1", features = ["log"] } diff --git a/clients/stellar-relay-lib/examples/connect.rs b/clients/stellar-relay-lib/examples/connect.rs index d63a73462..61b454c14 100644 --- a/clients/stellar-relay-lib/examples/connect.rs +++ b/clients/stellar-relay-lib/examples/connect.rs @@ -9,6 +9,7 @@ use wallet::keys::get_source_secret_key_from_env; #[tokio::main] async fn main() -> Result<(), Box> { env_logger::init(); + console_subscriber::init(); let args: Vec = std::env::args().collect(); let arg_network = if args.len() > 1 { &args[1] } else { "testnet" }; diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index d7836a2fe..bb0996df9 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -6,6 +6,7 @@ use tokio::{ }; use runtime::ShutdownSender; +use runtime::stellar::SecretKey; use stellar_relay_lib::{ connect_to_stellar_overlay_network, helper::to_base64_xdr_string, sdk::types::StellarMessage, StellarOverlayConfig, @@ -17,14 +18,33 @@ use crate::oracle::{ use wallet::Slot; pub struct OracleAgent { - collector: Arc>, + pub collector: Arc>, pub is_public_network: bool, /// sends message directly to Stellar Node message_sender: Option, /// sends an entire Vault shutdown - shutdown_sender: ShutdownSender, - /// sends a 'stop' signal to `StellarOverlayConnection` poll - overlay_conn_end_signal: mpsc::Sender<()>, + shutdown_sender: ShutdownSender +} + +impl OracleAgent { + pub fn new( + config: StellarOverlayConfig, + shutdown_sender: ShutdownSender + ) -> Self { + let is_public_network = config.is_public_network(); + + let collector = Arc::new(RwLock::new(ScpMessageCollector::new( + is_public_network, + config.stellar_history_archive_urls(), + ))); + + OracleAgent { + collector, + is_public_network, + message_sender: None, + shutdown_sender, + } + } } /// listens to data to collect the scp messages and txsets. @@ -57,6 +77,50 @@ async fn handle_message( Ok(()) } +pub async fn listen_for_stellar_messages( + config: StellarOverlayConfig, + collector: Arc>, + secret_key_as_str: &str, + shutdown_sender: ShutdownSender, +) -> Result<(),service::Error> { + tracing::info!("listen_for_stellar_messages(): Starting connection to Stellar overlay network..."); + + let mut overlay_conn = connect_to_stellar_overlay_network(config.clone(), secret_key_as_str).await + .map_err(|e| service::Error::VaultError(Error::Other(format!("{e:?}"))))?; + + // use StellarOverlayConnection's sender to send message to Stellar + let sender = overlay_conn.sender(); + + loop { + tokio::select! { + _ = sleep(Duration::from_millis(100)) => {}, + result = overlay_conn.listen() => match result { + Ok(None) => {}, + Ok(Some(msg)) => { + let msg_as_str = to_base64_xdr_string(&msg); + if let Err(e) = handle_message(msg, collector.clone(), &sender).await { + tracing::error!("listen_for_stellar_messages(): failed to handle message: {msg_as_str}: {e:?}"); + } + } + // connection got lost + Err(e) => { + tracing::error!("listen_for_stellar_messages(): encounter error in overlay: {e:?}"); + + if let Err(e) = shutdown_sender.send(()) { + tracing::error!("listen_for_stellar_messages(): Failed to send shutdown signal in thread: {e:?}"); + } + break + } + } + } + } + + tracing::info!("listen_for_stellar_messages(): shutting down overlay connection"); + overlay_conn.stop(); + + Ok(()) +} + /// Start the connection to the Stellar Node. /// Returns an `OracleAgent` that will handle incoming messages from Stellar Node, /// and to send messages to Stellar Node @@ -88,9 +152,7 @@ pub async fn start_oracle_agent( tokio::spawn(async move { loop { tokio::select! { - _ = sleep(Duration::from_millis(100)) => { - tracing::info!("start_oracle_agent(): go to sleep"); - }, + _ = sleep(Duration::from_millis(100)) => {}, // if a disconnect signal was sent, disconnect from Stellar. result = disconnect_signal_receiver.recv() => { if result.is_none() { @@ -98,9 +160,7 @@ pub async fn start_oracle_agent( break } }, - result = overlay_conn.listen() => { - tracing::info!("start_oracle_agent(): received message from overlay"); - match result { + result = overlay_conn.listen() => match result { Ok(Some(msg)) => { let msg_as_str = to_base64_xdr_string(&msg); if let Err(e) = handle_message(msg, collector_clone.clone(), &sender_clone).await { @@ -117,7 +177,7 @@ pub async fn start_oracle_agent( } break }, - }}, + }, } } @@ -130,8 +190,7 @@ pub async fn start_oracle_agent( collector, is_public_network, message_sender: Some(sender), - shutdown_sender, - overlay_conn_end_signal: disconnect_signal_sender, + shutdown_sender }) } @@ -177,25 +236,6 @@ impl OracleAgent { Error::ProofTimeout(format!("Timeout elapsed for building proof of slot {slot}")) })? } - - pub async fn last_slot_index(&self) -> Slot { - self.collector.read().await.last_slot_index() - } - - pub async fn remove_data(&self, slot: &Slot) { - self.collector.read().await.remove_data(slot); - } - - /// Stops listening for new SCP messages. - pub async fn shutdown(&self) { - tracing::debug!("shutdown(): Shutting down OracleAgent..."); - if let Err(e) = self.overlay_conn_end_signal.send(()).await { - tracing::error!( - "shutdown(): Failed to send overlay conn end signal in OracleAgent: {:?}", - e - ); - } - } } #[cfg(test)] diff --git a/clients/vault/src/oracle/collector/collector.rs b/clients/vault/src/oracle/collector/collector.rs index b8b57bb66..8e3e3b3fb 100644 --- a/clients/vault/src/oracle/collector/collector.rs +++ b/clients/vault/src/oracle/collector/collector.rs @@ -69,7 +69,6 @@ impl ScpMessageCollector { stellar_history_archive_urls, } } - pub fn envelopes_map_len(&self) -> usize { self.envelopes_map.read().len() } diff --git a/clients/vault/src/system.rs b/clients/vault/src/system.rs index 03ac84600..0ef49fb35 100644 --- a/clients/vault/src/system.rs +++ b/clients/vault/src/system.rs @@ -39,6 +39,7 @@ use crate::{ service::{CancellationScheduler, IssueCanceller}, ArcRwLock, Event, CHAIN_HEIGHT_POLLING_INTERVAL, }; +use crate::oracle::listen_for_stellar_messages; pub const VERSION: &str = env!("CARGO_PKG_VERSION"); pub const AUTHORS: &str = env!("CARGO_PKG_AUTHORS"); @@ -296,7 +297,6 @@ impl Service for VaultService { async fn start(&mut self) -> Result<(), ServiceError> { let result = self.run_service().await; - self.try_shutdown_agent().await; self.try_shutdown_wallet().await; if let Err(error) = result { @@ -415,29 +415,27 @@ impl VaultService { Ok(()) } - async fn create_oracle_agent( + fn create_oracle_agent( &self, is_public_network: bool, shutdown_sender: ShutdownSender, ) -> Result, ServiceError> { - let cfg_path = &self.config.stellar_overlay_config_filepath; - let stellar_overlay_cfg = - StellarOverlayConfig::try_from_path(cfg_path).map_err(Error::StellarRelayError)?; + let stellar_overlay_cfg = self.stellar_overlay_cfg()?; // check if both the config file and the wallet are the same. if is_public_network != stellar_overlay_cfg.is_public_network() { return Err(ServiceError::IncompatibleNetwork); } - let oracle_agent = crate::oracle::start_oracle_agent( - stellar_overlay_cfg, - &self.secret_key, - shutdown_sender, - ) - .await - .expect("Failed to start oracle agent"); + // let oracle_agent = crate::oracle::start_oracle_agent( + // stellar_overlay_cfg, + // &self.secret_key, + // shutdown_sender, + // ) + // .await + // .expect("Failed to start oracle agent"); - Ok(Arc::new(oracle_agent)) + Ok(Arc::new(OracleAgent::new(stellar_overlay_cfg,shutdown_sender))) } fn execute_open_requests(&self, oracle_agent: Arc) { @@ -707,6 +705,11 @@ impl VaultService { Ok(tasks) } + + fn stellar_overlay_cfg(&self) -> Result { + let cfg_path = &self.config.stellar_overlay_config_filepath; + StellarOverlayConfig::try_from_path(cfg_path).map_err(Error::StellarRelayError) + } } impl VaultService { @@ -789,14 +792,13 @@ impl VaultService { .await; drop(wallet); - let oracle_agent = - self.create_oracle_agent(is_public_network, self.shutdown.clone()).await?; + // let oracle_agent = + // self.create_oracle_agent(is_public_network, self.shutdown.clone()).await?; + let oracle_agent = self.create_oracle_agent(is_public_network, self.shutdown.clone())?; self.agent = Some(oracle_agent.clone()); self.execute_open_requests(oracle_agent.clone()); - tracing::info!("CONTINUE ON HOOY"); - // issue handling // this vec is passed to the stellar wallet to filter out transactions that are not relevant // this has to be modified every time the issue set changes @@ -808,12 +810,24 @@ impl VaultService { issue::initialize_issue_set(&self.spacewalk_parachain, &issue_map, &memos_to_issue_ids) .await?; - tracing::info!("ISSUE INITIALIZE ISSUE SET!!!"); - let ledger_env_map: ArcRwLock = Arc::new(RwLock::new(HashMap::new())); tracing::info!("Starting all services..."); - let tasks = self.create_tasks( + + // + let mut tasks = vec![( + "Stellar Messages Listener", + run( + listen_for_stellar_messages( + self.stellar_overlay_cfg()?, + oracle_agent.collector.clone(), + &self.secret_key, + self.shutdown.clone() + ) + ) + )]; + + let mut _tasks = self.create_tasks( startup_height, account_id, is_public_network, @@ -823,6 +837,7 @@ impl VaultService { ledger_env_map, memos_to_issue_ids, )?; + tasks.append(&mut _tasks); run_and_monitor_tasks(self.shutdown.clone(), tasks).await } @@ -957,15 +972,4 @@ impl VaultService { drop(wallet); } - async fn try_shutdown_agent(&mut self) { - let opt_agent = self.agent.clone(); - self.agent = None; - - if let Some(arc_agent) = opt_agent { - tracing::info!("try_shutdown_agent(): shutting down agent"); - arc_agent.shutdown().await; - } else { - tracing::debug!("try_shutdown_agent(): no agent found"); - } - } } From 12779c7996b7bc4473babf85bba7c9613192d8bd Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Fri, 2 Aug 2024 21:49:41 +0800 Subject: [PATCH 08/63] fix the trait bound `service::Error: From>` is not satisfied --> clients/vault/src/system.rs:820:4 --- clients/stellar-relay-lib/examples/connect.rs | 58 +++++++------ clients/stellar-relay-lib/src/config.rs | 8 +- .../src/connection/connector/connector.rs | 2 +- clients/stellar-relay-lib/src/overlay.rs | 12 ++- clients/stellar-relay-lib/src/tests/mod.rs | 2 +- clients/vault/Cargo.toml | 1 - clients/vault/src/issue.rs | 1 + clients/vault/src/oracle/agent.rs | 13 +-- clients/vault/src/oracle/errors.rs | 84 +++++++++---------- clients/vault/src/system.rs | 40 +++++++-- 10 files changed, 133 insertions(+), 88 deletions(-) diff --git a/clients/stellar-relay-lib/examples/connect.rs b/clients/stellar-relay-lib/examples/connect.rs index 61b454c14..82c0dca1b 100644 --- a/clients/stellar-relay-lib/examples/connect.rs +++ b/clients/stellar-relay-lib/examples/connect.rs @@ -1,8 +1,4 @@ -use stellar_relay_lib::{ - connect_to_stellar_overlay_network, - sdk::types::{ScpStatementPledges, StellarMessage}, - StellarOverlayConfig, -}; +use stellar_relay_lib::{connect_to_stellar_overlay_network, Error, sdk::types::{ScpStatementPledges, StellarMessage}, StellarOverlayConfig}; use wallet::keys::get_source_secret_key_from_env; @@ -15,7 +11,7 @@ async fn main() -> Result<(), Box> { let arg_network = if args.len() > 1 { &args[1] } else { "testnet" }; let cfg_file_path = if arg_network == "mainnet" { - "./clients/stellar-relay-lib/resources/config/mainnet/stellar_relay_config_mainnet_iowa.json" + "./clients/stellar-relay-lib/resources/config/mainnet/stellar_relay_config_singapore.json" } else { "./clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest1.json" }; @@ -23,33 +19,45 @@ async fn main() -> Result<(), Box> { let secret_key = get_source_secret_key_from_env(arg_network == "mainnet"); - let mut overlay_connection = connect_to_stellar_overlay_network(cfg, &secret_key).await?; - - while let Ok(Some(msg)) = overlay_connection.listen().await { - match msg { - StellarMessage::ScpMessage(msg) => { - let node_id = msg.statement.node_id.to_encoding(); - let node_id = base64::encode(&node_id); - let slot = msg.statement.slot_index; - - let stmt_type = match msg.statement.pledges { - ScpStatementPledges::ScpStPrepare(_) => "ScpStPrepare", - ScpStatementPledges::ScpStConfirm(_) => "ScpStConfirm", - ScpStatementPledges::ScpStExternalize(_) => "ScpStExternalize", - ScpStatementPledges::ScpStNominate(_) => "ScpStNominate ", - }; - tracing::info!( + let mut overlay_connection = connect_to_stellar_overlay_network(cfg, secret_key).await?; + + loop { + match overlay_connection.listen().await { + Ok(Some(msg)) => match msg { + StellarMessage::ScpMessage(msg) => { + let node_id = msg.statement.node_id.to_encoding(); + let node_id = base64::encode(&node_id); + let slot = msg.statement.slot_index; + + let stmt_type = match msg.statement.pledges { + ScpStatementPledges::ScpStPrepare(_) => "ScpStPrepare", + ScpStatementPledges::ScpStConfirm(_) => "ScpStConfirm", + ScpStatementPledges::ScpStExternalize(_) => "ScpStExternalize", + ScpStatementPledges::ScpStNominate(_) => "ScpStNominate ", + }; + tracing::info!( "{} sent StellarMessage of type {} for ledger {}", node_id, stmt_type, slot ); + }, + _ => { + let _ = overlay_connection.send_to_node(StellarMessage::GetPeers).await; + }, }, - _ => { - let _ = overlay_connection.send_to_node(StellarMessage::GetPeers).await; - }, + Ok(None) => {} + Err(Error::Timeout) => { + tracing::warn!("took more than a second to respond"); + } + Err(e) => { + tracing::error!("Error: {:?}", e); + break + } } + } + tracing::info!("ooops, connection stopped "); Ok(()) } diff --git a/clients/stellar-relay-lib/src/config.rs b/clients/stellar-relay-lib/src/config.rs index a00d3953f..d43d8e1c1 100644 --- a/clients/stellar-relay-lib/src/config.rs +++ b/clients/stellar-relay-lib/src/config.rs @@ -39,9 +39,9 @@ impl StellarOverlayConfig { } #[allow(dead_code)] - pub(crate) fn connection_info(&self, secret_key: &str) -> Result { + pub(crate) fn connection_info(&self, secret_key_as_string: String) -> Result { let cfg = &self.connection_info; - let secret_key = SecretKey::from_encoding(secret_key)?; + let secret_key = SecretKey::from_encoding(secret_key_as_string)?; let public_key = secret_key.get_public().to_encoding(); let public_key = std::str::from_utf8(&public_key).unwrap(); @@ -128,9 +128,9 @@ impl ConnectionInfoCfg { /// Returns the `StellarOverlayConnection` if connection is a success, otherwise an Error pub async fn connect_to_stellar_overlay_network( cfg: StellarOverlayConfig, - secret_key: &str, + secret_key_as_string: String, ) -> Result { - let conn_info = cfg.connection_info(secret_key)?; + let conn_info = cfg.connection_info(secret_key_as_string)?; let local_node = cfg.node_info; StellarOverlayConnection::connect(local_node.into(), conn_info).await diff --git a/clients/stellar-relay-lib/src/connection/connector/connector.rs b/clients/stellar-relay-lib/src/connection/connector/connector.rs index b9392fc54..d23f9c6a2 100644 --- a/clients/stellar-relay-lib/src/connection/connector/connector.rs +++ b/clients/stellar-relay-lib/src/connection/connector/connector.rs @@ -284,7 +284,7 @@ mod test { let cfg = StellarOverlayConfig::try_from_path(cfg_file_path).expect("should create a config"); let node_info = cfg.node_info(); - let conn_info = cfg.connection_info(&secret_key).expect("should create a connection info"); + let conn_info = cfg.connection_info(secret_key).expect("should create a connection info"); // this is a channel to communicate with the connection/config (this needs renaming) let connector = Connector::start(node_info.clone(), conn_info.clone()) diff --git a/clients/stellar-relay-lib/src/overlay.rs b/clients/stellar-relay-lib/src/overlay.rs index 13f1f8349..b0c1cc5d8 100644 --- a/clients/stellar-relay-lib/src/overlay.rs +++ b/clients/stellar-relay-lib/src/overlay.rs @@ -45,6 +45,16 @@ impl StellarOverlayConnection { let connector = Connector::start(local_node_info, conn_info).await?; + #[cfg(tokio_unstable)] + tokio::task::Builder::new() + .name("poll_messages_from_stellar") + .spawn(poll_messages_from_stellar( + connector, + send_to_user_sender, + send_to_node_receiver, + )).unwrap(); + + #[cfg(not(tokio_unstable))] tokio::spawn(poll_messages_from_stellar( connector, send_to_user_sender, @@ -65,7 +75,7 @@ impl StellarOverlayConnection { return Err(Error::Disconnected) } - timeout(Duration::from_secs(1), self.receiver.recv()).await + timeout(Duration::from_secs(5), self.receiver.recv()).await .map_err(|_| Error::Timeout) } diff --git a/clients/stellar-relay-lib/src/tests/mod.rs b/clients/stellar-relay-lib/src/tests/mod.rs index 60071bc19..716291816 100644 --- a/clients/stellar-relay-lib/src/tests/mod.rs +++ b/clients/stellar-relay-lib/src/tests/mod.rs @@ -33,7 +33,7 @@ fn overlay_infos(is_mainnet: bool) -> (NodeInfo, ConnectionInfo) { ( cfg.node_info(), - cfg.connection_info(&secret_key(is_mainnet)).expect("should return conn info"), + cfg.connection_info(secret_key(is_mainnet)).expect("should return conn info"), ) } diff --git a/clients/vault/Cargo.toml b/clients/vault/Cargo.toml index ffe1027c8..56bab7ec8 100644 --- a/clients/vault/Cargo.toml +++ b/clients/vault/Cargo.toml @@ -77,7 +77,6 @@ sp-runtime = { git = "https://github.com/paritytech/polkadot-sdk", branch = "rel sp-std = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } parking_lot = "0.12.1" -err-derive = "0.3.1" flate2 = "1.0" [dev-dependencies] diff --git a/clients/vault/src/issue.rs b/clients/vault/src/issue.rs index 2a3f5f4ca..a590d7b6a 100644 --- a/clients/vault/src/issue.rs +++ b/clients/vault/src/issue.rs @@ -26,6 +26,7 @@ pub(crate) async fn initialize_issue_set( issue_set: &ArcRwLock, memos_to_issue_ids: &ArcRwLock, ) -> Result<(), Error> { + tracing::info!("initialize_issue_set(): started"); let (mut issue_set, mut memos_to_issue_ids, requests) = future::join3( issue_set.write(), memos_to_issue_ids.write(), diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index bb0996df9..fd5845155 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -80,13 +80,16 @@ async fn handle_message( pub async fn listen_for_stellar_messages( config: StellarOverlayConfig, collector: Arc>, - secret_key_as_str: &str, + secret_key_as_string: String, shutdown_sender: ShutdownSender, -) -> Result<(),service::Error> { +) -> Result<(),service::Error> { tracing::info!("listen_for_stellar_messages(): Starting connection to Stellar overlay network..."); - let mut overlay_conn = connect_to_stellar_overlay_network(config.clone(), secret_key_as_str).await - .map_err(|e| service::Error::VaultError(Error::Other(format!("{e:?}"))))?; + let mut overlay_conn = connect_to_stellar_overlay_network(config.clone(), secret_key_as_string) + .await.map_err(|e|{ + tracing::error!("listen_for_stellar_messages(): Failed to connect to Stellar overlay network: {e:?}"); + service::Error::StartOracleAgentError + })?; // use StellarOverlayConnection's sender to send message to Stellar let sender = overlay_conn.sender(); @@ -133,7 +136,7 @@ pub async fn start_oracle_agent( tracing::info!("start_oracle_agent(): Starting connection to Stellar overlay network..."); - let mut overlay_conn = connect_to_stellar_overlay_network(config.clone(), secret_key).await?; + let mut overlay_conn = connect_to_stellar_overlay_network(config.clone(), secret_key.to_string()).await?; // use StellarOverlayConnection's sender to send message to Stellar let sender = overlay_conn.sender(); diff --git a/clients/vault/src/oracle/errors.rs b/clients/vault/src/oracle/errors.rs index b4c0e2643..d1187be79 100644 --- a/clients/vault/src/oracle/errors.rs +++ b/clients/vault/src/oracle/errors.rs @@ -4,39 +4,39 @@ use tokio::sync::{mpsc, oneshot}; use stellar_relay_lib::sdk::StellarSdkError; -#[derive(Debug, err_derive::Error)] +#[derive(Debug, thiserror::Error)] pub enum Error { - #[error(display = "{:?}", _0)] + #[error("Stellar SDK Error: {0:?}")] StellarSdkError(StellarSdkError), - #[error(display = "{:?}", _0)] - TryFromSliceError(TryFromSliceError), + #[error("TryFromSliceError: {0}")] + TryFromSliceError(#[from] TryFromSliceError), - #[error(display = "{:?}", _0)] - SerdeError(bincode::Error), + #[error("Serde Error: {0}")] + SerdeError(#[from] bincode::Error), - #[error(display = "{:?}", _0)] - StdIoError(std::io::Error), + #[error("StdIoError: {0}")] + StdIoError(#[from] std::io::Error), - #[error(display = "{:?}", _0)] + #[error("Other: {0}")] Other(String), - #[error(display = "{:?}", _0)] - ConnError(stellar_relay_lib::Error), + #[error("Stellar Relay Error: {0}")] + ConnError(#[from] stellar_relay_lib::Error), - #[error(display = "{:?}", _0)] - WalletError(wallet::error::Error), + #[error("Wallet Error: {0}")] + WalletError(#[from] wallet::error::Error), - #[error(display = "{:?}", _0)] + #[error("Proof Timeout: {0}")] ProofTimeout(String), - #[error(display = "{} is not initialized", _0)] + #[error("Unititialized: {0}")] Uninitialized(String), - #[error(display = "{}", _0)] + #[error("Archive Error: {0}")] ArchiveError(String), - #[error(display = "{}", _0)] + #[error("ArchiveResponseError: {0}")] ArchiveResponseError(String), } @@ -45,30 +45,30 @@ impl From for Error { Error::StellarSdkError(e) } } - -impl From for Error { - fn from(e: std::io::Error) -> Self { - Error::StdIoError(e) - } -} - -impl From for Error { - fn from(e: bincode::Error) -> Self { - Error::SerdeError(e) - } -} - -impl From for Error { - fn from(e: TryFromSliceError) -> Self { - Error::TryFromSliceError(e) - } -} - -impl From for Error { - fn from(e: stellar_relay_lib::Error) -> Self { - Error::ConnError(e) - } -} +// +// impl From for Error { +// fn from(e: std::io::Error) -> Self { +// Error::StdIoError(e) +// } +// } +// +// impl From for Error { +// fn from(e: bincode::Error) -> Self { +// Error::SerdeError(e) +// } +// } +// +// impl From for Error { +// fn from(e: TryFromSliceError) -> Self { +// Error::TryFromSliceError(e) +// } +// } +// +// impl From for Error { +// fn from(e: stellar_relay_lib::Error) -> Self { +// Error::ConnError(e) +// } +// } impl From> for Error { fn from(e: mpsc::error::SendError) -> Self { @@ -80,4 +80,4 @@ impl From for Error { fn from(e: oneshot::error::RecvError) -> Self { Error::ConnError(stellar_relay_lib::Error::SendFailed(e.to_string())) } -} +} \ No newline at end of file diff --git a/clients/vault/src/system.rs b/clients/vault/src/system.rs index 0ef49fb35..d31258da4 100644 --- a/clients/vault/src/system.rs +++ b/clients/vault/src/system.rs @@ -324,7 +324,13 @@ async fn run_and_monitor_tasks( _ => None, }?; let task = monitor.instrument(task); + + #[cfg(all(tokio_unstable, feature = "allow_debugger"))] + let task = tokio::task::Builder::new().name(name).spawn(task).unwrap(); + + #[cfg(not(feature = "allow-debugger"))] let task = tokio::spawn(task); + Some(((name.to_string(), metrics_iterator), task)) }) .unzip(); @@ -337,11 +343,25 @@ async fn run_and_monitor_tasks( tracing::info!("run_and_monitor_tasks(): running all tasks..."); match join(tokio_metrics, join_all(tasks)).await { (Ok(Err(err)), _) => Err(err), - (_, results) => results - .into_iter() - .find(|res| matches!(res, Ok(Err(_)))) - .and_then(|res| res.ok()) - .unwrap_or(Ok(())), + (_, results) => { + let res = results.into_iter() + .find(|res| matches!(res, Ok(()))) + .and_then(|res| res.ok()); + + if let Some(_) = res { + tracing::info!("run_and_monitor_tasks(): join ok"); + Ok(()) + } else { + tracing::info!("run_and_monitor_tasks(): returned None"); + Ok(()) + } + + // results + // .into_iter() + // .find(|res| matches!(res, Ok(Err(_)))) + // .and_then(|res| res.ok()) + // .unwrap_or(Ok(())) + }, } } @@ -744,6 +764,10 @@ impl VaultService { }) } + fn secret_key (&self) -> String { + self.secret_key.clone() + } + fn get_vault_id( &self, collateral_currency: CurrencyId, @@ -797,7 +821,8 @@ impl VaultService { let oracle_agent = self.create_oracle_agent(is_public_network, self.shutdown.clone())?; self.agent = Some(oracle_agent.clone()); - self.execute_open_requests(oracle_agent.clone()); + // self.execute_open_requests(oracle_agent.clone()); + tracing::info!("proceed to initializing issue sets"); // issue handling // this vec is passed to the stellar wallet to filter out transactions that are not relevant @@ -814,14 +839,13 @@ impl VaultService { tracing::info!("Starting all services..."); - // let mut tasks = vec![( "Stellar Messages Listener", run( listen_for_stellar_messages( self.stellar_overlay_cfg()?, oracle_agent.collector.clone(), - &self.secret_key, + self.secret_key(), self.shutdown.clone() ) ) From 806568d7262dde04d245aaa6c0be33741df8bc02 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Fri, 9 Aug 2024 23:32:09 +0800 Subject: [PATCH 09/63] cleanup clones; add names to threads --- Cargo.lock | 1 - clients/runtime/src/rpc.rs | 5 +- clients/stellar-relay-lib/src/config.rs | 2 +- .../src/connection/connector/connector.rs | 6 +- .../connection/connector/message_handler.rs | 2 +- .../connection/connector/message_reader.rs | 62 +++++++++--------- clients/stellar-relay-lib/src/node/mod.rs | 15 ++++- clients/stellar-relay-lib/src/node/remote.rs | 6 +- clients/stellar-relay-lib/src/overlay.rs | 4 +- clients/vault/src/error.rs | 3 + clients/vault/src/issue.rs | 23 ++++--- clients/vault/src/lib.rs | 14 +++++ clients/vault/src/main.rs | 11 +++- clients/vault/src/oracle/agent.rs | 11 +++- .../src/oracle/collector/proof_builder.rs | 11 +++- clients/vault/src/system.rs | 63 +++++++------------ 16 files changed, 138 insertions(+), 101 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index da761b8b1..cdad0ea35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12842,7 +12842,6 @@ dependencies = [ "clap 3.2.25", "console-subscriber", "env_logger 0.9.3", - "err-derive", "flate2", "frame-support", "futures 0.3.30", diff --git a/clients/runtime/src/rpc.rs b/clients/runtime/src/rpc.rs index 30885154f..7bd347655 100644 --- a/clients/runtime/src/rpc.rs +++ b/clients/runtime/src/rpc.rs @@ -5,6 +5,7 @@ use async_trait::async_trait; use codec::Encode; use futures::{future::join_all, stream::StreamExt, FutureExt, SinkExt}; use jsonrpsee::core::{client::Client, JsonValue}; +use jsonrpsee::tracing; use subxt::{ backend::{legacy::LegacyRpcMethods, rpc::RpcClient}, blocks::ExtrinsicEvents, @@ -1085,7 +1086,9 @@ impl IssuePallet for SpacewalkParachain { let key_hash = issue_id.as_slice(); // last bytes are the raw key let key = &key_hash[key_hash.len() - 32..]; - issue_requests.push((H256::from_slice(key), request)); + let key = H256::from_slice(key); + tracing::info!("get_all_active_issues: found {}", key.to_string()); + issue_requests.push((key, request)); } } Ok(issue_requests) diff --git a/clients/stellar-relay-lib/src/config.rs b/clients/stellar-relay-lib/src/config.rs index d43d8e1c1..7d8210f96 100644 --- a/clients/stellar-relay-lib/src/config.rs +++ b/clients/stellar-relay-lib/src/config.rs @@ -35,7 +35,7 @@ impl StellarOverlayConfig { #[allow(dead_code)] pub(crate) fn node_info(&self) -> NodeInfo { - self.node_info.clone().into() + NodeInfo::new(&self.node_info) } #[allow(dead_code)] diff --git a/clients/stellar-relay-lib/src/connection/connector/connector.rs b/clients/stellar-relay-lib/src/connection/connector/connector.rs index d23f9c6a2..e5f6ca3cd 100644 --- a/clients/stellar-relay-lib/src/connection/connector/connector.rs +++ b/clients/stellar-relay-lib/src/connection/connector/connector.rs @@ -335,7 +335,7 @@ mod test { cert: new_auth_cert, nonce: [0; 32], }; - connector.set_remote(RemoteInfo::new(&hello)); + connector.set_remote(RemoteInfo::new(hello)); assert!(connector.remote().is_some()); } @@ -359,7 +359,7 @@ mod test { cert: new_auth_cert, nonce: [0; 32], }; - connector.set_remote(RemoteInfo::new(&hello)); + connector.set_remote(RemoteInfo::new(hello)); assert_eq!(connector.remote().unwrap().sequence(), 0); connector.increment_remote_sequence().unwrap(); @@ -387,7 +387,7 @@ mod test { cert: new_auth_cert, nonce: [0; 32], }; - let remote = RemoteInfo::new(&hello); + let remote = RemoteInfo::new(hello); let remote_nonce = remote.nonce(); connector.set_remote(remote.clone()); diff --git a/clients/stellar-relay-lib/src/connection/connector/message_handler.rs b/clients/stellar-relay-lib/src/connection/connector/message_handler.rs index 1722bf9e1..1e4dcc591 100644 --- a/clients/stellar-relay-lib/src/connection/connector/message_handler.rs +++ b/clients/stellar-relay-lib/src/connection/connector/message_handler.rs @@ -132,7 +132,7 @@ impl Connector { return Err(Error::AuthCertInvalid); } - let remote_info = RemoteInfo::new(&hello); + let remote_info = RemoteInfo::new(hello); let shared_key = self.get_shared_key(remote_info.pub_key_ecdh()); self.set_hmac_keys(HMacKeys::new( diff --git a/clients/stellar-relay-lib/src/connection/connector/message_reader.rs b/clients/stellar-relay-lib/src/connection/connector/message_reader.rs index 98d901b52..fdc26e5c2 100644 --- a/clients/stellar-relay-lib/src/connection/connector/message_reader.rs +++ b/clients/stellar-relay-lib/src/connection/connector/message_reader.rs @@ -29,7 +29,7 @@ pub(crate) async fn poll_messages_from_stellar( if send_to_user_sender.is_closed() { info!("poll_messages_from_stellar(): closing receiver during disconnection"); // close this channel as communication to user was closed. - break; + break } // check for messages from user. @@ -46,26 +46,26 @@ pub(crate) async fn poll_messages_from_stellar( let xdr = match read_message_from_stellar(&mut connector).await { Err(e) => { error!("poll_messages_from_stellar(): {e:?}"); - break; + break }, Ok(xdr) => xdr, }; match connector.process_raw_message(xdr).await { - Ok(Some(stellar_msg)) => - // push message to user - { - if let Err(e) = send_to_user_sender.send(stellar_msg.clone()).await { + Ok(Some(stellar_msg)) => { + // push message to user + let stellar_msg_as_base64_xdr = stellar_msg.to_base64_xdr(); + if let Err(e) = send_to_user_sender.send(stellar_msg).await { warn!("poll_messages_from_stellar(): Error occurred during sending message {} to user: {e:?}", - String::from_utf8(stellar_msg.to_base64_xdr()) - .unwrap_or_else(|_| format!("{:?}", stellar_msg.to_base64_xdr())) - ); + String::from_utf8(stellar_msg_as_base64_xdr.clone()) + .unwrap_or_else(|_| format!("{stellar_msg_as_base64_xdr:?}")) + ); } }, Ok(None) => {}, Err(e) => { error!("poll_messages_from_stellar(): Error occurred during processing xdr message: {e:?}"); - break; + break }, } } @@ -106,13 +106,13 @@ async fn read_message_from_stellar(connector: &mut Connector) -> Result Result continue, - Ok(Some(xdr)) => return Ok(xdr), + Ok(false) => continue, + Ok(true) => return Ok(readbuf), Err(e) => { trace!("read_message_from_stellar(): ERROR: {e:?}"); - return Err(e); + return Err(e) }, } }, @@ -136,30 +136,30 @@ async fn read_message_from_stellar(connector: &mut Connector) -> Result continue, - Ok(Some(xdr)) => return Ok(xdr), + Ok(false) => continue, + Ok(true) => return Ok(readbuf), Err(e) => { trace!("read_message_from_stellar(): ERROR: {e:?}"); - return Err(e); + return Err(e) }, } }, Ok(Err(e)) => { trace!("read_message_from_stellar(): ERROR reading messages: {e:?}"); - return Err(Error::ReadFailed(e.to_string())); + return Err(Error::ReadFailed(e.to_string())) }, Err(_) => { trace!("read_message_from_stellar(): reading time elapsed."); - return Err(Error::Timeout); + return Err(Error::Timeout) }, } } } -/// Returns Xdr when all bytes from the stream have successfully been converted; else None. +/// Returns true when all bytes from the stream have successfully been converted; else false. /// This reads a number of bytes based on the expected message length. /// /// # Arguments @@ -168,12 +168,12 @@ async fn read_message_from_stellar(connector: &mut Connector) -> Result, xpect_msg_len: usize, -) -> Result, Error> { +) -> Result { let actual_msg_len = connector .tcp_stream .read(readbuf) @@ -182,7 +182,7 @@ async fn read_message( // only when the message has the exact expected size bytes, should we send to user. if actual_msg_len == xpect_msg_len { - return Ok(Some(readbuf.clone())); + return Ok(true) } // The next bytes are remnants from the previous stellar message. @@ -193,10 +193,10 @@ async fn read_message( "read_message(): received only partial message. Need {lack_bytes_from_prev} bytes to complete." ); - Ok(None) + Ok(false) } -/// Returns Xdr when all bytes from the stream have successfully been converted; else None. +/// Returns true when all bytes from the stream have successfully been converted; else false. /// Reads a continuation of bytes that belong to the previous message /// /// # Arguments @@ -204,11 +204,11 @@ async fn read_message( /// Stellar Node /// * `lack_bytes_from_prev` - the number of bytes remaining, to complete the previous message /// * `readbuf` - the buffer that holds the bytes of the previous and incomplete message -async fn read_unfinished_message( +async fn is_reading_unfinished_message_complete( connector: &mut Connector, lack_bytes_from_prev: &mut usize, readbuf: &mut Vec, -) -> Result, Error> { +) -> Result { // let's read the continuation number of bytes from the previous message. let mut cont_buf = vec![0; *lack_bytes_from_prev]; @@ -223,7 +223,7 @@ async fn read_unfinished_message( trace!("read_unfinished_message(): received continuation from the previous message."); readbuf.append(&mut cont_buf); - return Ok(Some(readbuf.clone())); + return Ok(true) } // this partial message is not enough to complete the previous message. @@ -236,5 +236,5 @@ async fn read_unfinished_message( ); } - Ok(None) + Ok(false) } diff --git a/clients/stellar-relay-lib/src/node/mod.rs b/clients/stellar-relay-lib/src/node/mod.rs index bd6fc642a..b50337b88 100644 --- a/clients/stellar-relay-lib/src/node/mod.rs +++ b/clients/stellar-relay-lib/src/node/mod.rs @@ -19,6 +19,19 @@ pub struct NodeInfo { pub network_id: NetworkId, } +impl NodeInfo { + pub(crate) fn new(cfg:&NodeInfoCfg) -> Self { + let network: &Network = if cfg.is_pub_net { &PUBLIC_NETWORK } else { &TEST_NETWORK }; + NodeInfo { + ledger_version: cfg.ledger_version, + overlay_version: cfg.overlay_version, + overlay_min_version: cfg.overlay_min_version, + version_str: cfg.version_str.clone(), + network_id: *network.get_id(), + } + } +} + impl Debug for NodeInfo { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("NodeInfo") @@ -42,4 +55,4 @@ impl From for NodeInfo { network_id: *network.get_id(), } } -} +} \ No newline at end of file diff --git a/clients/stellar-relay-lib/src/node/remote.rs b/clients/stellar-relay-lib/src/node/remote.rs index ee6752d15..580dcb932 100644 --- a/clients/stellar-relay-lib/src/node/remote.rs +++ b/clients/stellar-relay-lib/src/node/remote.rs @@ -36,11 +36,11 @@ impl Debug for RemoteInfo { } impl RemoteInfo { - pub fn new(hello: &Hello) -> Self { + pub fn new(hello: Hello) -> Self { RemoteInfo { sequence: 0, - pub_key_ecdh: hello.cert.pubkey.clone(), - pub_key: hello.peer_id.clone(), + pub_key_ecdh: hello.cert.pubkey, + pub_key: hello.peer_id, nonce: hello.nonce, node: NodeInfo { ledger_version: hello.ledger_version, diff --git a/clients/stellar-relay-lib/src/overlay.rs b/clients/stellar-relay-lib/src/overlay.rs index b0c1cc5d8..583550498 100644 --- a/clients/stellar-relay-lib/src/overlay.rs +++ b/clients/stellar-relay-lib/src/overlay.rs @@ -18,7 +18,7 @@ use crate::{ /// Used to send/receive messages to/from Stellar Node pub struct StellarOverlayConnection { - sender: mpsc::Sender, + sender: Sender, receiver: mpsc::Receiver, } @@ -47,7 +47,7 @@ impl StellarOverlayConnection { #[cfg(tokio_unstable)] tokio::task::Builder::new() - .name("poll_messages_from_stellar") + .name("poll stellar messages") .spawn(poll_messages_from_stellar( connector, send_to_user_sender, diff --git a/clients/vault/src/error.rs b/clients/vault/src/error.rs index 2ac24e277..12c440d39 100644 --- a/clients/vault/src/error.rs +++ b/clients/vault/src/error.rs @@ -46,6 +46,9 @@ pub enum Error { #[error("StdIoError: {0}")] StdIoError(#[from] std::io::Error), + + #[error("Other error: {0}")] + Other(String) } impl From for service::Error { diff --git a/clients/vault/src/issue.rs b/clients/vault/src/issue.rs index a590d7b6a..fbdc31201 100644 --- a/clients/vault/src/issue.rs +++ b/clients/vault/src/issue.rs @@ -14,7 +14,7 @@ use wallet::{ types::FilterWith, LedgerTxEnvMap, Slot, SlotTask, SlotTaskStatus, TransactionResponse, }; -use crate::{oracle::OracleAgent, ArcRwLock, Error, Event}; +use crate::{oracle::OracleAgent, ArcRwLock, Error, Event, tokio_spawn}; fn is_vault(p1: &PublicKey, p2_raw: [u8; 32]) -> bool { return *p1.as_binary() == p2_raw; @@ -272,15 +272,18 @@ pub async fn process_issues_requests( continue; }; - tokio::spawn(execute_issue( - parachain_rpc.clone(), - tx_env.clone(), - issues.clone(), - memos_to_issue_ids.clone(), - oracle_agent.clone(), - *slot, - sender, - )); + tokio_spawn( + "execute_issue", + execute_issue( + parachain_rpc.clone(), + tx_env.clone(), + issues.clone(), + memos_to_issue_ids.clone(), + oracle_agent.clone(), + *slot, + sender, + ) + ); } // Give 5 seconds interval before starting again. diff --git a/clients/vault/src/lib.rs b/clients/vault/src/lib.rs index ad5f14a4e..801aa5e4e 100644 --- a/clients/vault/src/lib.rs +++ b/clients/vault/src/lib.rs @@ -59,3 +59,17 @@ cfg_if::cfg_if! { pub type DecimalsLookupImpl = primitives::AmplitudeDecimalsLookup; } } + +pub fn tokio_spawn(task_name: &str, future: F) -> tokio::task::JoinHandle + where + F: std::future::Future + Send + 'static, + F::Output: Send + 'static, +{ + cfg_if::cfg_if!{ + if #[cfg(all(tokio_unstable, feature = "allow-debugger"))] { + tokio::task::Builder::new().name(task_name).spawn(future).unwrap() + } else { + tokio::spawn(future) + } + } +} \ No newline at end of file diff --git a/clients/vault/src/main.rs b/clients/vault/src/main.rs index 5a2d13f7e..e86d1e6b4 100644 --- a/clients/vault/src/main.rs +++ b/clients/vault/src/main.rs @@ -70,7 +70,7 @@ async fn catch_signals( where F: Future>> + Send + 'static, { - let blocking_task = tokio::task::spawn(future); + let blocking_task = tokio_spawn("blocking task", future); tokio::select! { res = blocking_task => { return res?; @@ -117,7 +117,7 @@ async fn start() -> Result<(), ServiceError> { ); let prometheus_port = opts.monitoring.prometheus_port; - tokio::task::spawn(async move { + tokio_spawn("Prometheus", async move { warp::serve(metrics_route) .run(SocketAddr::new(prometheus_host.into(), prometheus_port)) .await; @@ -164,6 +164,9 @@ async fn main() { mod tests { use std::{thread, time::Duration}; + use runtime::AccountId; + use vault::tokio_spawn; + use super::*; #[tokio::test] @@ -171,7 +174,9 @@ mod tests { let termination_signals = &[SIGHUP, SIGTERM, SIGINT, SIGQUIT]; for sig in termination_signals { let task = - tokio::spawn(catch_signals(Signals::new(termination_signals).unwrap(), async { + tokio_spawn( + "catch signals", + catch_signals(Signals::new(termination_signals).unwrap(), async { tokio::time::sleep(Duration::from_millis(100_000)).await; Ok(()) })); diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index fd5845155..05439b427 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -16,6 +16,7 @@ use crate::oracle::{ collector::ScpMessageCollector, errors::Error, types::StellarMessageSender, AddTxSet, Proof, }; use wallet::Slot; +use crate::tokio_spawn; pub struct OracleAgent { pub collector: Arc>, @@ -26,6 +27,12 @@ pub struct OracleAgent { shutdown_sender: ShutdownSender } +impl Clone for OracleAgent { + fn clone(&self) -> Self { + todo!() + } +} + impl OracleAgent { pub fn new( config: StellarOverlayConfig, @@ -152,7 +159,9 @@ pub async fn start_oracle_agent( let (disconnect_signal_sender, mut disconnect_signal_receiver) = mpsc::channel::<()>(2); let sender_clone = overlay_conn.sender(); - tokio::spawn(async move { + tokio_spawn( + "overlay connection started", + async move { loop { tokio::select! { _ = sleep(Duration::from_millis(100)) => {}, diff --git a/clients/vault/src/oracle/collector/proof_builder.rs b/clients/vault/src/oracle/collector/proof_builder.rs index f43eb1aea..48bfa9e75 100644 --- a/clients/vault/src/oracle/collector/proof_builder.rs +++ b/clients/vault/src/oracle/collector/proof_builder.rs @@ -15,6 +15,7 @@ use crate::oracle::{ types::StellarMessageSender, ScpArchiveStorage, ScpMessageCollector, TransactionsArchiveStorage, }; +use crate::tokio_spawn; /// Returns true if the SCP messages for a given slot are still recoverable from the overlay /// because the slot is not too far back. @@ -107,7 +108,10 @@ impl ScpMessageCollector { /// fetches envelopes from the archive async fn ask_archive_for_envelopes(&self, slot: Slot) { - tokio::spawn(self.get_envelopes_from_horizon_archive(slot)); + tokio_spawn( + "envelopes from archive", + self.get_envelopes_from_horizon_archive(slot) + ); } /// Returns either a list of ScpEnvelopes @@ -164,7 +168,10 @@ impl ScpMessageCollector { if check_slot_still_recoverable_from_overlay(self.last_slot_index(), slot) { self.fetch_missing_txset_from_overlay(slot, sender).await; } else { - tokio::spawn(self.get_txset_from_horizon_archive(slot)); + tokio_spawn( + "txset from archive", + self.get_txset_from_horizon_archive(slot) + ); } tracing::warn!("get_txset(): Proof Building for slot {slot}: no txset found"); diff --git a/clients/vault/src/system.rs b/clients/vault/src/system.rs index d31258da4..5dfa0aa68 100644 --- a/clients/vault/src/system.rs +++ b/clients/vault/src/system.rs @@ -26,19 +26,7 @@ use service::{wait_or_shutdown, Error as ServiceError, MonitoringConfig, Service use stellar_relay_lib::{sdk::PublicKey, StellarOverlayConfig}; use wallet::{LedgerTxEnvMap, StellarWallet, RESUBMISSION_INTERVAL_IN_SECS}; -use crate::{ - cancellation::ReplaceCanceller, - error::Error, - issue, - issue::IssueFilter, - metrics::{monitor_bridge_metrics, poll_metrics, publish_tokio_metrics, PerCurrencyMetrics}, - oracle::OracleAgent, - redeem::listen_for_redeem_requests, - replace::{listen_for_accept_replace, listen_for_execute_replace, listen_for_replace_requests}, - requests::execution::execute_open_requests, - service::{CancellationScheduler, IssueCanceller}, - ArcRwLock, Event, CHAIN_HEIGHT_POLLING_INTERVAL, -}; +use crate::{cancellation::ReplaceCanceller, error::Error, issue, issue::IssueFilter, metrics::{monitor_bridge_metrics, poll_metrics, publish_tokio_metrics, PerCurrencyMetrics}, oracle::OracleAgent, redeem::listen_for_redeem_requests, replace::{listen_for_accept_replace, listen_for_execute_replace, listen_for_replace_requests}, requests::execution::execute_open_requests, service::{CancellationScheduler, IssueCanceller}, ArcRwLock, Event, CHAIN_HEIGHT_POLLING_INTERVAL, tokio_spawn}; use crate::oracle::listen_for_stellar_messages; pub const VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -325,42 +313,35 @@ async fn run_and_monitor_tasks( }?; let task = monitor.instrument(task); - #[cfg(all(tokio_unstable, feature = "allow_debugger"))] - let task = tokio::task::Builder::new().name(name).spawn(task).unwrap(); - - #[cfg(not(feature = "allow-debugger"))] - let task = tokio::spawn(task); - + let task = tokio_spawn(name, task); Some(((name.to_string(), metrics_iterator), task)) }) .unzip(); - let tokio_metrics = tokio::spawn(wait_or_shutdown( - shutdown_tx.clone(), - publish_tokio_metrics(metrics_iterators), - )); + let tokio_metrics = tokio_spawn( + "tokio metrics publisher", + wait_or_shutdown( + shutdown_tx.clone(), + publish_tokio_metrics(metrics_iterators), + ) + ); tracing::info!("run_and_monitor_tasks(): running all tasks..."); + + match join(tokio_metrics, join_all(tasks)).await { (Ok(Err(err)), _) => Err(err), (_, results) => { - let res = results.into_iter() - .find(|res| matches!(res, Ok(()))) - .and_then(|res| res.ok()); - - if let Some(_) = res { - tracing::info!("run_and_monitor_tasks(): join ok"); - Ok(()) - } else { - tracing::info!("run_and_monitor_tasks(): returned None"); - Ok(()) + for result in results { + match result { + Ok(_) => {} + Err(e) => { + tracing::error!("run_and_monitor_tasks(): One of the tasks failed: {e:?}"); + return Err(ServiceError::TokioError(e)); + } + } } - - // results - // .into_iter() - // .find(|res| matches!(res, Ok(Err(_)))) - // .and_then(|res| res.ok()) - // .unwrap_or(Ok(())) + Ok(()) }, } } @@ -430,7 +411,7 @@ impl VaultService { .await?; Ok::<_, Error>(()) }); - tokio::task::spawn(err_listener); + tokio_spawn("error listener", err_listener); Ok(()) } @@ -821,7 +802,7 @@ impl VaultService { let oracle_agent = self.create_oracle_agent(is_public_network, self.shutdown.clone())?; self.agent = Some(oracle_agent.clone()); - // self.execute_open_requests(oracle_agent.clone()); + self.execute_open_requests(oracle_agent.clone()); tracing::info!("proceed to initializing issue sets"); // issue handling From b110ad1dd5b9f5b0ed71cb0a497b93d264a0cf4c Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 13 Aug 2024 00:53:57 +0800 Subject: [PATCH 10/63] add a precheck signal --- clients/service/src/lib.rs | 14 +++- clients/vault/src/oracle/agent.rs | 40 ++++++---- clients/vault/src/system.rs | 120 +++++++++++++++--------------- 3 files changed, 102 insertions(+), 72 deletions(-) diff --git a/clients/service/src/lib.rs b/clients/service/src/lib.rs index c950db8f0..f4994a537 100644 --- a/clients/service/src/lib.rs +++ b/clients/service/src/lib.rs @@ -168,10 +168,22 @@ impl ConnectionManager { } } -pub async fn wait_or_shutdown(shutdown_tx: ShutdownSender, future2: F) -> Result<(), E> +pub async fn wait_or_shutdown( + shutdown_tx: ShutdownSender, + future2: F, + // a consumer that receives a precheck signal to start a task. + precheck_signal: Option> +) -> Result<(), E> where F: Future>, { + if let Some(mut precheck_signal) = precheck_signal { + if let Err(e) = precheck_signal.recv().await { + tracing::error!("Error receiving precheck signal: {:?}", e); + return Ok(()) + } + } + match run_cancelable(shutdown_tx.subscribe(), future2).await { TerminationStatus::Cancelled => { tracing::trace!("Received shutdown signal"); diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index 05439b427..016cc2c5c 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -1,4 +1,5 @@ use std::{sync::Arc, time::Duration}; +use std::future::Future; use tokio::{ sync::{mpsc, RwLock}, @@ -84,12 +85,15 @@ async fn handle_message( Ok(()) } -pub async fn listen_for_stellar_messages( +pub async fn listen_for_stellar_messages( config: StellarOverlayConfig, collector: Arc>, secret_key_as_string: String, shutdown_sender: ShutdownSender, -) -> Result<(),service::Error> { + // executes a task that determines whether other tasks should run or not + pre_task_execution: Option<(F, tokio::sync::broadcast::Sender<()>)> +) -> Result<(),service::Error> +where F: Future>> + Send + 'static { tracing::info!("listen_for_stellar_messages(): Starting connection to Stellar overlay network..."); let mut overlay_conn = connect_to_stellar_overlay_network(config.clone(), secret_key_as_string) @@ -98,16 +102,37 @@ pub async fn listen_for_stellar_messages( service::Error::StartOracleAgentError })?; + if let Some((pre_task_execution, signal_sender)) = pre_task_execution { + pre_task_execution.await?; + + if let Err(e) = signal_sender.send(()) { + tracing::error!("listen_for_stellar_messages(): Failed to send signal: {e:?}"); + } + } + // use StellarOverlayConnection's sender to send message to Stellar let sender = overlay_conn.sender(); + // occasionally log a new message received. + let mut log_counter:u8 = 0; loop { + if log_counter == u8::MAX { + log_counter = 0; + } else { + log_counter += 1; + } + tokio::select! { _ = sleep(Duration::from_millis(100)) => {}, result = overlay_conn.listen() => match result { Ok(None) => {}, Ok(Some(msg)) => { let msg_as_str = to_base64_xdr_string(&msg); + + if log_counter % 100 == 0 { + tracing::info!("listen_for_stellar_messages(): received message: {msg_as_str}"); + } + if let Err(e) = handle_message(msg, collector.clone(), &sender).await { tracing::error!("listen_for_stellar_messages(): failed to handle message: {msg_as_str}: {e:?}"); } @@ -154,10 +179,6 @@ pub async fn start_oracle_agent( let collector_clone = collector.clone(); let shutdown_sender_clone = shutdown_sender.clone(); - // disconnect signal sender tells the StellarOverlayConnection to close its TcpStream to Stellar - // Node - let (disconnect_signal_sender, mut disconnect_signal_receiver) = mpsc::channel::<()>(2); - let sender_clone = overlay_conn.sender(); tokio_spawn( "overlay connection started", @@ -165,13 +186,6 @@ pub async fn start_oracle_agent( loop { tokio::select! { _ = sleep(Duration::from_millis(100)) => {}, - // if a disconnect signal was sent, disconnect from Stellar. - result = disconnect_signal_receiver.recv() => { - if result.is_none() { - tracing::info!("start_oracle_agent(): disconnect overlay..."); - break - } - }, result = overlay_conn.listen() => match result { Ok(Some(msg)) => { let msg_as_str = to_base64_xdr_string(&msg); diff --git a/clients/vault/src/system.rs b/clients/vault/src/system.rs index 5dfa0aa68..226b7c027 100644 --- a/clients/vault/src/system.rs +++ b/clients/vault/src/system.rs @@ -9,11 +9,12 @@ use clap::Parser; use futures::{ channel::{ mpsc, - mpsc::{Receiver, Sender}, + mpsc::{Receiver as mpscReceiver, Sender as mpscSender}, }, future::{join, join_all}, SinkExt, TryFutureExt, }; +use tokio::sync::broadcast::{self, Receiver as bcReceiver, Sender as bcSender }; use tokio::{sync::RwLock, time::sleep}; use runtime::{ @@ -237,8 +238,8 @@ pub struct VaultServiceConfig { async fn active_block_listener( parachain_rpc: SpacewalkParachain, - issue_tx: Sender, - replace_tx: Sender, + issue_tx: mpscSender, + replace_tx: mpscSender, ) -> Result<(), ServiceError> { tracing::info!("active_block_listener(): started"); let issue_tx = &issue_tx; @@ -300,6 +301,8 @@ impl Service for VaultService { async fn run_and_monitor_tasks( shutdown_tx: ShutdownSender, items: Vec<(&str, ServiceTask)>, + // Sends a signal to start those tasks requiring a precheck. + mut precheck_signals: Vec> ) -> Result<(), ServiceError> { let (metrics_iterators, tasks): (HashMap, Vec<_>) = items .into_iter() @@ -308,7 +311,9 @@ async fn run_and_monitor_tasks( let metrics_iterator = monitor.intervals(); let task = match task { ServiceTask::Optional(true, t) | ServiceTask::Essential(t) => - Some(wait_or_shutdown(shutdown_tx.clone(), t)), + Some(wait_or_shutdown(shutdown_tx.clone(), t,None)), + ServiceTask::PrecheckRequired(t) => + Some(wait_or_shutdown(shutdown_tx.clone(),t,precheck_signals.pop())), _ => None, }?; let task = monitor.instrument(task); @@ -323,6 +328,7 @@ async fn run_and_monitor_tasks( wait_or_shutdown( shutdown_tx.clone(), publish_tokio_metrics(metrics_iterators), + None ) ); @@ -351,6 +357,19 @@ type Task = Pin>> + Send enum ServiceTask { Optional(bool, Task), Essential(Task), + // Runs a task after a prequisite check has passed. + PrecheckRequired(Task) +} + +/// returns a single-producer multi-consumer channel to send a signal to start a task +fn precheck_signals(num_of_signals_required:u8) -> (bcSender<()>, Vec>){ + let (sender, receiver) = broadcast::channel(1); + let mut subscribers = vec![receiver]; + while subscribers.len() < usize::from(num_of_signals_required) { + subscribers.push(sender.subscribe()); + } + + (sender, subscribers) } fn maybe_run(should_run: bool, task: F) -> ServiceTask @@ -369,6 +388,14 @@ where ServiceTask::Essential(Box::pin(task.map_err(|x| x.into()))) } +fn run_with_precheck(task: F) -> ServiceTask + where + F: Future> + Send + 'static, + E: Into>, +{ + ServiceTask::PrecheckRequired(Box::pin(task.map_err(|x| x.into()))) +} + type RegistrationData = Vec<(CurrencyId, CurrencyId, Option)>; // dedicated for running the service impl VaultService { @@ -410,7 +437,7 @@ impl VaultService { .on_event_error(|e| tracing::debug!("Client Service: Received error event: {}", e)) .await?; Ok::<_, Error>(()) - }); + },None); tokio_spawn("error listener", err_listener); Ok(()) @@ -428,45 +455,13 @@ impl VaultService { return Err(ServiceError::IncompatibleNetwork); } - // let oracle_agent = crate::oracle::start_oracle_agent( - // stellar_overlay_cfg, - // &self.secret_key, - // shutdown_sender, - // ) - // .await - // .expect("Failed to start oracle agent"); - Ok(Arc::new(OracleAgent::new(stellar_overlay_cfg,shutdown_sender))) } - fn execute_open_requests(&self, oracle_agent: Arc) { - let open_request_executor = execute_open_requests( - self.shutdown.clone(), - self.spacewalk_parachain.clone(), - self.vault_id_manager.clone(), - self.stellar_wallet.clone(), - oracle_agent, - self.config.payment_margin_minutes, - ); - - let shutdown_clone = self.shutdown.clone(); - service::spawn_cancelable(self.shutdown.subscribe(), async move { - match open_request_executor.await { - Ok(_) => tracing::info!("Done processing open requests"), - Err(e) => { - tracing::error!("Failed to process open requests: {}", e); - if let Err(err) = shutdown_clone.send(()) { - tracing::error!("Failed to send shutdown signal: {}", err); - } - }, - } - }); - } - fn create_issue_tasks( &self, - issue_event_tx: Sender, - issue_event_rx: Receiver, + issue_event_tx: mpscSender, + issue_event_rx: mpscReceiver, startup_height: BlockNumber, account_id: AccountId, vault_public_key: PublicKey, @@ -478,7 +473,7 @@ impl VaultService { vec![ ( "Issue Request Listener", - run(issue::listen_for_issue_requests( + run_with_precheck(issue::listen_for_issue_requests( self.spacewalk_parachain.clone(), vault_public_key, issue_event_tx, @@ -488,7 +483,7 @@ impl VaultService { ), ( "Issue Cancel Listener", - run(issue::listen_for_issue_cancels( + run_with_precheck(issue::listen_for_issue_cancels( self.spacewalk_parachain.clone(), issue_map.clone(), memos_to_issue_ids.clone(), @@ -496,7 +491,7 @@ impl VaultService { ), ( "Issue Execute Listener", - run(issue::listen_for_executed_issues( + run_with_precheck(issue::listen_for_executed_issues( self.spacewalk_parachain.clone(), issue_map.clone(), memos_to_issue_ids.clone(), @@ -517,7 +512,7 @@ impl VaultService { ), ( "Issue Cancel Scheduler", - run(CancellationScheduler::new( + run_with_precheck(CancellationScheduler::new( self.spacewalk_parachain.clone(), startup_height, account_id, @@ -529,8 +524,8 @@ impl VaultService { fn create_replace_tasks( &self, - replace_event_tx: Sender, - replace_event_rx: Receiver, + replace_event_tx: mpscSender, + replace_event_rx: mpscReceiver, startup_height: BlockNumber, account_id: AccountId, oracle_agent: Arc, @@ -538,7 +533,7 @@ impl VaultService { vec![ ( "Request Replace Listener", - run(listen_for_replace_requests( + run_with_precheck(listen_for_replace_requests( self.spacewalk_parachain.clone(), self.vault_id_manager.clone(), replace_event_tx.clone(), @@ -547,7 +542,7 @@ impl VaultService { ), ( "Accept Replace Listener", - run(listen_for_accept_replace( + run_with_precheck(listen_for_accept_replace( self.shutdown.clone(), self.spacewalk_parachain.clone(), self.vault_id_manager.clone(), @@ -561,7 +556,7 @@ impl VaultService { ), ( "Replace Cancellation Scheduler", - run(CancellationScheduler::new( + run_with_precheck(CancellationScheduler::new( self.spacewalk_parachain.clone(), startup_height, account_id, @@ -596,8 +591,8 @@ impl VaultService { fn create_initial_tasks( &self, is_public_network: bool, - issue_event_tx: Sender, - replace_event_tx: Sender, + issue_event_tx: mpscSender, + replace_event_tx: mpscSender, vault_public_key: PublicKey, issue_map: ArcRwLock, ledger_env_map: ArcRwLock, @@ -632,7 +627,7 @@ impl VaultService { ), ( "Parachain Block Listener", - run(active_block_listener( + run_with_precheck(active_block_listener( self.spacewalk_parachain.clone(), issue_event_tx, replace_event_tx, @@ -797,14 +792,9 @@ impl VaultService { .await; drop(wallet); - // let oracle_agent = - // self.create_oracle_agent(is_public_network, self.shutdown.clone()).await?; let oracle_agent = self.create_oracle_agent(is_public_network, self.shutdown.clone())?; self.agent = Some(oracle_agent.clone()); - self.execute_open_requests(oracle_agent.clone()); - tracing::info!("proceed to initializing issue sets"); - // issue handling // this vec is passed to the stellar wallet to filter out transactions that are not relevant // this has to be modified every time the issue set changes @@ -816,6 +806,8 @@ impl VaultService { issue::initialize_issue_set(&self.spacewalk_parachain, &issue_map, &memos_to_issue_ids) .await?; + let (precheck_sender, precheck_receivers) = precheck_signals(8); + let ledger_env_map: ArcRwLock = Arc::new(RwLock::new(HashMap::new())); tracing::info!("Starting all services..."); @@ -827,7 +819,19 @@ impl VaultService { self.stellar_overlay_cfg()?, oracle_agent.collector.clone(), self.secret_key(), - self.shutdown.clone() + self.shutdown.clone(), + // this is the prequisite task that should be performed + // BEFORE tasks (with precheck requirement) run. + Some((execute_open_requests( + self.shutdown.clone(), + self.spacewalk_parachain.clone(), + self.vault_id_manager.clone(), + self.stellar_wallet.clone(), + oracle_agent.clone(), + self.config.payment_margin_minutes + ), + precheck_sender + )) ) ) )]; @@ -844,7 +848,7 @@ impl VaultService { )?; tasks.append(&mut _tasks); - run_and_monitor_tasks(self.shutdown.clone(), tasks).await + run_and_monitor_tasks(self.shutdown.clone(), tasks, precheck_receivers).await } async fn register_public_key_if_not_present(&mut self) -> Result<(), Error> { From fe685199315e8588e005f88e34885fb54715a18a Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 13 Aug 2024 02:58:36 +0800 Subject: [PATCH 11/63] reduce timeouts; write log every 2 minutes --- .../connection/connector/message_reader.rs | 1 + clients/stellar-relay-lib/src/overlay.rs | 5 +- clients/vault/src/oracle/agent.rs | 54 +++++++++---------- 3 files changed, 28 insertions(+), 32 deletions(-) diff --git a/clients/stellar-relay-lib/src/connection/connector/message_reader.rs b/clients/stellar-relay-lib/src/connection/connector/message_reader.rs index fdc26e5c2..9778a6003 100644 --- a/clients/stellar-relay-lib/src/connection/connector/message_reader.rs +++ b/clients/stellar-relay-lib/src/connection/connector/message_reader.rs @@ -61,6 +61,7 @@ pub(crate) async fn poll_messages_from_stellar( .unwrap_or_else(|_| format!("{stellar_msg_as_base64_xdr:?}")) ); } + tokio::task::yield_now().await; }, Ok(None) => {}, Err(e) => { diff --git a/clients/stellar-relay-lib/src/overlay.rs b/clients/stellar-relay-lib/src/overlay.rs index 583550498..f0dda51a8 100644 --- a/clients/stellar-relay-lib/src/overlay.rs +++ b/clients/stellar-relay-lib/src/overlay.rs @@ -47,7 +47,7 @@ impl StellarOverlayConnection { #[cfg(tokio_unstable)] tokio::task::Builder::new() - .name("poll stellar messages") + .name("Poll Stellar Messages") .spawn(poll_messages_from_stellar( connector, send_to_user_sender, @@ -75,8 +75,7 @@ impl StellarOverlayConnection { return Err(Error::Disconnected) } - timeout(Duration::from_secs(5), self.receiver.recv()).await - .map_err(|_| Error::Timeout) + Ok(self.receiver.recv().await) } pub fn is_alive(&mut self) -> bool { diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index 016cc2c5c..aed34c8ad 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -5,6 +5,7 @@ use tokio::{ sync::{mpsc, RwLock}, time::{sleep, timeout}, }; +use tokio::time::Instant; use runtime::ShutdownSender; use runtime::stellar::SecretKey; @@ -113,39 +114,34 @@ where F: Future>> + Send + 'sta // use StellarOverlayConnection's sender to send message to Stellar let sender = overlay_conn.sender(); - // occasionally log a new message received. - let mut log_counter:u8 = 0; + // log a new message received, every 2 minutes. + let interval = Duration::from_secs(120); + let mut next_time = Instant::now() + interval; loop { - if log_counter == u8::MAX { - log_counter = 0; - } else { - log_counter += 1; - } - - tokio::select! { - _ = sleep(Duration::from_millis(100)) => {}, - result = overlay_conn.listen() => match result { - Ok(None) => {}, - Ok(Some(msg)) => { - let msg_as_str = to_base64_xdr_string(&msg); - - if log_counter % 100 == 0 { - tracing::info!("listen_for_stellar_messages(): received message: {msg_as_str}"); - } + match overlay_conn.listen().await { + Ok(None) => { + tracing::info!("listen_for_stellar_messages(): yielding to outside tasks"); + tokio::task::yield_now().await; + }, + Ok(Some(msg)) => { + let msg_as_str = to_base64_xdr_string(&msg); + if Instant::now() >= next_time { + tracing::info!("listen_for_stellar_messages(): received message: {msg_as_str}"); + next_time += interval; + } - if let Err(e) = handle_message(msg, collector.clone(), &sender).await { - tracing::error!("listen_for_stellar_messages(): failed to handle message: {msg_as_str}: {e:?}"); - } + if let Err(e) = handle_message(msg, collector.clone(), &sender).await { + tracing::error!("listen_for_stellar_messages(): failed to handle message: {msg_as_str}: {e:?}"); } - // connection got lost - Err(e) => { - tracing::error!("listen_for_stellar_messages(): encounter error in overlay: {e:?}"); - - if let Err(e) = shutdown_sender.send(()) { - tracing::error!("listen_for_stellar_messages(): Failed to send shutdown signal in thread: {e:?}"); - } - break + } + // connection got lost + Err(e) => { + tracing::error!("listen_for_stellar_messages(): encounter error in overlay: {e:?}"); + + if let Err(e) = shutdown_sender.send(()) { + tracing::error!("listen_for_stellar_messages(): Failed to send shutdown signal in thread: {e:?}"); } + break } } } From 4d3183b078bc4b931209632c4925daf86636c9bd Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 13 Aug 2024 15:59:21 +0800 Subject: [PATCH 12/63] update config and remove precheck when listening for stellar messages --- clients/stellar-relay-lib/Cargo.toml | 2 +- clients/stellar-relay-lib/src/overlay.rs | 2 -- clients/vault/src/oracle/agent.rs | 36 +++++++------------ .../vault/src/oracle/collector/collector.rs | 2 +- clients/vault/src/requests/execution.rs | 12 +++++++ clients/vault/src/system.rs | 26 +++++++------- clients/vault/tests/helper/mod.rs | 12 ++++++- .../vault/tests/vault_integration_tests.rs | 9 +++-- 8 files changed, 58 insertions(+), 43 deletions(-) diff --git a/clients/stellar-relay-lib/Cargo.toml b/clients/stellar-relay-lib/Cargo.toml index 8aebded17..6c8e2b7b3 100644 --- a/clients/stellar-relay-lib/Cargo.toml +++ b/clients/stellar-relay-lib/Cargo.toml @@ -15,7 +15,7 @@ serial_test = "0.9.0" wallet = { path = "../wallet", features = ["testing-utils"] } [dependencies] -console-subscriber = { version = "0.4.0" } +console-subscriber = { version = "0.3.0" } hex = "0.4.3" tracing = { version = "0.1", features = ["log"] } diff --git a/clients/stellar-relay-lib/src/overlay.rs b/clients/stellar-relay-lib/src/overlay.rs index f0dda51a8..ea5416fcc 100644 --- a/clients/stellar-relay-lib/src/overlay.rs +++ b/clients/stellar-relay-lib/src/overlay.rs @@ -1,5 +1,3 @@ -use std::time::Duration; -use async_std::future::timeout; use substrate_stellar_sdk::types::{StellarMessage}; use tokio::sync::{ mpsc, diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index aed34c8ad..365b7aa69 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -54,6 +54,10 @@ impl OracleAgent { shutdown_sender, } } + + pub async fn is_proof_building_ready(&self) -> bool { + self.collector.read().await.last_slot_index() > 0 + } } /// listens to data to collect the scp messages and txsets. @@ -86,15 +90,12 @@ async fn handle_message( Ok(()) } -pub async fn listen_for_stellar_messages( +pub async fn listen_for_stellar_messages( config: StellarOverlayConfig, collector: Arc>, secret_key_as_string: String, shutdown_sender: ShutdownSender, - // executes a task that determines whether other tasks should run or not - pre_task_execution: Option<(F, tokio::sync::broadcast::Sender<()>)> -) -> Result<(),service::Error> -where F: Future>> + Send + 'static { +) -> Result<(),service::Error> { tracing::info!("listen_for_stellar_messages(): Starting connection to Stellar overlay network..."); let mut overlay_conn = connect_to_stellar_overlay_network(config.clone(), secret_key_as_string) @@ -103,30 +104,19 @@ where F: Future>> + Send + 'sta service::Error::StartOracleAgentError })?; - if let Some((pre_task_execution, signal_sender)) = pre_task_execution { - pre_task_execution.await?; - - if let Err(e) = signal_sender.send(()) { - tracing::error!("listen_for_stellar_messages(): Failed to send signal: {e:?}"); - } - } - // use StellarOverlayConnection's sender to send message to Stellar let sender = overlay_conn.sender(); - // log a new message received, every 2 minutes. - let interval = Duration::from_secs(120); + // log a new message received, every 1 minute. + let interval = Duration::from_secs(5); let mut next_time = Instant::now() + interval; loop { match overlay_conn.listen().await { - Ok(None) => { - tracing::info!("listen_for_stellar_messages(): yielding to outside tasks"); - tokio::task::yield_now().await; - }, + Ok(None) => {}, Ok(Some(msg)) => { let msg_as_str = to_base64_xdr_string(&msg); if Instant::now() >= next_time { - tracing::info!("listen_for_stellar_messages(): received message: {msg_as_str}"); + tracing::info!("listen_for_stellar_messages(): health check: received message from Stellar"); next_time += interval; } @@ -290,11 +280,11 @@ mod tests { .expect("Failed to start agent"); let mut latest_slot = 0; - while latest_slot == 0 { + while !agent.is_proof_building_ready().await{ sleep(Duration::from_secs(1)).await; - latest_slot = agent.last_slot_index().await; } - latest_slot += 1; + latest_slot = agent.collector.read().await.last_slot_index(); + // let's wait for envelopes and txset to be available for creating a proof sleep(Duration::from_secs(5)).await; diff --git a/clients/vault/src/oracle/collector/collector.rs b/clients/vault/src/oracle/collector/collector.rs index 8e3e3b3fb..507554125 100644 --- a/clients/vault/src/oracle/collector/collector.rs +++ b/clients/vault/src/oracle/collector/collector.rs @@ -120,7 +120,7 @@ impl ScpMessageCollector { self.txset_and_slot_map.read().get_txset_hash_by_slot(slot).cloned() } - pub(crate) fn last_slot_index(&self) -> u64 { + pub fn last_slot_index(&self) -> u64 { self.last_slot_index } } diff --git a/clients/vault/src/requests/execution.rs b/clients/vault/src/requests/execution.rs index 9aa734a55..756b644fb 100644 --- a/clients/vault/src/requests/execution.rs +++ b/clients/vault/src/requests/execution.rs @@ -290,6 +290,7 @@ pub async fn execute_open_requests( wallet: Arc>, oracle_agent: Arc, payment_margin: Duration, + precheck_signal: tokio::sync::broadcast::Sender<()> ) -> Result<(), ServiceError> { tracing::info!("execute_open_requests(): started"); let parachain_rpc_ref = ¶chain_rpc; @@ -304,6 +305,12 @@ pub async fn execute_open_requests( let rate_limiter = Arc::new(RateLimiter::direct(YIELD_RATE)); + while !oracle_agent.is_proof_building_ready().await { + tracing::debug!("execute_open_requests(): agent is not yet ready. Waiting..."); + } + + tracing::info!("execute_open_requests(): Oracle agent is ready."); + // Check if the open requests have a corresponding payment on Stellar // and are just waiting to be executed on the parachain spawn_tasks_to_execute_open_requests_async( @@ -327,5 +334,10 @@ pub async fn execute_open_requests( rate_limiter, ); + + if let Err(e) = precheck_signal.send(()) { + tracing::error!("execute_open_requests(): Failed to send signal: {e:?}"); + } + Ok(()) } diff --git a/clients/vault/src/system.rs b/clients/vault/src/system.rs index 226b7c027..264bf40d7 100644 --- a/clients/vault/src/system.rs +++ b/clients/vault/src/system.rs @@ -807,6 +807,18 @@ impl VaultService { .await?; let (precheck_sender, precheck_receivers) = precheck_signals(8); + tokio_spawn( + "Execute Open Requests", + execute_open_requests( + self.shutdown.clone(), + self.spacewalk_parachain.clone(), + self.vault_id_manager.clone(), + self.stellar_wallet.clone(), + oracle_agent.clone(), + self.config.payment_margin_minutes, + precheck_sender + ) + ); let ledger_env_map: ArcRwLock = Arc::new(RwLock::new(HashMap::new())); @@ -819,19 +831,7 @@ impl VaultService { self.stellar_overlay_cfg()?, oracle_agent.collector.clone(), self.secret_key(), - self.shutdown.clone(), - // this is the prequisite task that should be performed - // BEFORE tasks (with precheck requirement) run. - Some((execute_open_requests( - self.shutdown.clone(), - self.spacewalk_parachain.clone(), - self.vault_id_manager.clone(), - self.stellar_wallet.clone(), - oracle_agent.clone(), - self.config.payment_margin_minutes - ), - precheck_sender - )) + self.shutdown.clone() ) ) )]; diff --git a/clients/vault/tests/helper/mod.rs b/clients/vault/tests/helper/mod.rs index 115c574eb..2ca3e0030 100644 --- a/clients/vault/tests/helper/mod.rs +++ b/clients/vault/tests/helper/mod.rs @@ -24,6 +24,7 @@ use vault::{ oracle::{random_stellar_relay_config, start_oracle_agent, OracleAgent}, ArcRwLock, }; +use vault::oracle::listen_for_stellar_messages; use wallet::{ keys::{get_dest_secret_key_from_env, get_source_secret_key_from_env}, StellarWallet, @@ -144,10 +145,19 @@ where let shutdown_tx = ShutdownSender::new(); let oracle_agent = - start_oracle_agent(stellar_config.clone(), &vault_stellar_secret, shutdown_tx) + start_oracle_agent(stellar_config.clone(), &vault_stellar_secret, shutdown_tx.clone()) .await .expect("failed to start agent"); let oracle_agent = Arc::new(oracle_agent); + tokio::spawn( + listen_for_stellar_messages( + stellar_config, + oracle_agent.collector.clone(), + vault_stellar_secret, + shutdown_tx + ) + ); + execute(client, vault_wallet, user_wallet, oracle_agent, vault_id, vault_provider).await } diff --git a/clients/vault/tests/vault_integration_tests.rs b/clients/vault/tests/vault_integration_tests.rs index 6e4a615ca..7c9aae29c 100644 --- a/clients/vault/tests/vault_integration_tests.rs +++ b/clients/vault/tests/vault_integration_tests.rs @@ -3,7 +3,7 @@ use std::{collections::HashMap, convert::TryInto, sync::Arc, time::Duration}; use frame_support::assert_ok; use futures::{ channel::mpsc, - future::{join, join3, join4}, + future::{join, join3, join4, join5}, FutureExt, SinkExt, }; use serial_test::serial; @@ -1163,8 +1163,9 @@ async fn test_execute_open_requests_succeeds() { // add it to the set sleep(Duration::from_secs(5)).await; + let (precheck_signal, mut rceiver) = tokio::sync::broadcast::channel(1); let shutdown_tx = ShutdownSender::new(); - join4( + join5( vault::service::execute_open_requests( shutdown_tx.clone(), vault_provider, @@ -1172,8 +1173,12 @@ async fn test_execute_open_requests_succeeds() { vault_wallet.clone(), oracle_agent.clone(), Duration::from_secs(0), + precheck_signal ) .map(Result::unwrap), + async move { + assert_ok!(rceiver.recv().await); + }, // Redeem 0 should be executed without creating an extra payment since we already // sent one just before assert_execute_redeem_event(TIMEOUT * 3, user_provider.clone(), redeem_ids[0]), From 53c88de33f866d385fbde0fdf74665561057ce48 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 13 Aug 2024 16:01:21 +0800 Subject: [PATCH 13/63] log every minute --- clients/vault/src/oracle/agent.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index 365b7aa69..faf6286ef 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -108,7 +108,7 @@ pub async fn listen_for_stellar_messages( let sender = overlay_conn.sender(); // log a new message received, every 1 minute. - let interval = Duration::from_secs(5); + let interval = Duration::from_secs(60); let mut next_time = Instant::now() + interval; loop { match overlay_conn.listen().await { From 8c345e1127df28dffba18d56a0adac3b3d92ace2 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 13 Aug 2024 16:38:38 +0800 Subject: [PATCH 14/63] cleanup --- clients/vault/src/error.rs | 3 - clients/vault/src/oracle/agent.rs | 90 +++++-------------- clients/vault/src/system.rs | 2 +- clients/vault/tests/helper/mod.rs | 23 ++--- .../vault/tests/vault_integration_tests.rs | 6 +- 5 files changed, 31 insertions(+), 93 deletions(-) diff --git a/clients/vault/src/error.rs b/clients/vault/src/error.rs index 12c440d39..2ac24e277 100644 --- a/clients/vault/src/error.rs +++ b/clients/vault/src/error.rs @@ -46,9 +46,6 @@ pub enum Error { #[error("StdIoError: {0}")] StdIoError(#[from] std::io::Error), - - #[error("Other error: {0}")] - Other(String) } impl From for service::Error { diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index faf6286ef..2e30d7d4a 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -29,15 +29,9 @@ pub struct OracleAgent { shutdown_sender: ShutdownSender } -impl Clone for OracleAgent { - fn clone(&self) -> Self { - todo!() - } -} - impl OracleAgent { pub fn new( - config: StellarOverlayConfig, + config: &StellarOverlayConfig, shutdown_sender: ShutdownSender ) -> Self { let is_public_network = config.is_public_network(); @@ -141,69 +135,25 @@ pub async fn listen_for_stellar_messages( Ok(()) } - -/// Start the connection to the Stellar Node. -/// Returns an `OracleAgent` that will handle incoming messages from Stellar Node, -/// and to send messages to Stellar Node +#[cfg(test)] pub async fn start_oracle_agent( - config: StellarOverlayConfig, - secret_key: &str, - shutdown_sender: ShutdownSender, -) -> Result { - let is_public_network = config.is_public_network(); - - tracing::info!("start_oracle_agent(): Starting connection to Stellar overlay network..."); - - let mut overlay_conn = connect_to_stellar_overlay_network(config.clone(), secret_key.to_string()).await?; - // use StellarOverlayConnection's sender to send message to Stellar - let sender = overlay_conn.sender(); + cfg: StellarOverlayConfig, + vault_stellar_secret: String, + shutdown_sender: ShutdownSender +) -> OracleAgent { + let oracle_agent = OracleAgent::new(&cfg, shutdown_sender.clone()); + + tokio::spawn( + listen_for_stellar_messages( + cfg, + oracle_agent.collector.clone(), + vault_stellar_secret, + shutdown_sender + ) + ); - let collector = Arc::new(RwLock::new(ScpMessageCollector::new( - config.is_public_network(), - config.stellar_history_archive_urls(), - ))); - let collector_clone = collector.clone(); - - let shutdown_sender_clone = shutdown_sender.clone(); - let sender_clone = overlay_conn.sender(); - tokio_spawn( - "overlay connection started", - async move { - loop { - tokio::select! { - _ = sleep(Duration::from_millis(100)) => {}, - result = overlay_conn.listen() => match result { - Ok(Some(msg)) => { - let msg_as_str = to_base64_xdr_string(&msg); - if let Err(e) = handle_message(msg, collector_clone.clone(), &sender_clone).await { - tracing::error!("start_oracle_agent(): failed to handle message: {msg_as_str}: {e:?}"); - } - }, - Ok(None) => {}, - // connection got lost - Err(e) => { - tracing::error!("start_oracle_agent(): encounter error in overlay: {e:?}"); - - if let Err(e) = shutdown_sender_clone.send(()) { - tracing::error!("start_oracle_agent(): Failed to send shutdown signal in thread: {e:?}"); - } - break - }, - }, - } - } + oracle_agent - tracing::info!("start_oracle_agent(): shutting down overlay connection"); - // shutdown the overlay connection - overlay_conn.stop(); - }); - - Ok(OracleAgent { - collector, - is_public_network, - message_sender: Some(sender), - shutdown_sender - }) } impl OracleAgent { @@ -305,7 +255,7 @@ mod tests { let shutdown_sender = ShutdownSender::new(); let agent = start_oracle_agent( specific_stellar_relay_config(is_public_network, 1), - &get_source_secret_key_from_env(is_public_network), + get_source_secret_key_from_env(is_public_network), shutdown_sender, ) .await @@ -346,7 +296,7 @@ mod tests { let shutdown_sender = ShutdownSender::new(); let agent = start_oracle_agent( modified_config, - &get_source_secret_key_from_env(is_public_network), + get_source_secret_key_from_env(is_public_network), shutdown_sender, ) .await @@ -378,7 +328,7 @@ mod tests { let shutdown = ShutdownSender::new(); let agent = start_oracle_agent( modified_config, - &get_source_secret_key_from_env(is_public_network), + get_source_secret_key_from_env(is_public_network), shutdown, ) .await diff --git a/clients/vault/src/system.rs b/clients/vault/src/system.rs index 264bf40d7..0d45c17c8 100644 --- a/clients/vault/src/system.rs +++ b/clients/vault/src/system.rs @@ -455,7 +455,7 @@ impl VaultService { return Err(ServiceError::IncompatibleNetwork); } - Ok(Arc::new(OracleAgent::new(stellar_overlay_cfg,shutdown_sender))) + Ok(Arc::new(OracleAgent::new(&stellar_overlay_cfg,shutdown_sender))) } fn create_issue_tasks( diff --git a/clients/vault/tests/helper/mod.rs b/clients/vault/tests/helper/mod.rs index 2ca3e0030..2b413694f 100644 --- a/clients/vault/tests/helper/mod.rs +++ b/clients/vault/tests/helper/mod.rs @@ -21,10 +21,10 @@ use stellar_relay_lib::StellarOverlayConfig; use subxt::utils::AccountId32 as AccountId; use tokio::sync::RwLock; use vault::{ - oracle::{random_stellar_relay_config, start_oracle_agent, OracleAgent}, + oracle::{random_stellar_relay_config, OracleAgent}, ArcRwLock, }; -use vault::oracle::listen_for_stellar_messages; +use vault::oracle::{start_oracle_agent}; use wallet::{ keys::{get_dest_secret_key_from_env, get_source_secret_key_from_env}, StellarWallet, @@ -144,20 +144,11 @@ where let vault_stellar_secret = get_source_secret_key_from_env(is_public_network); let shutdown_tx = ShutdownSender::new(); - let oracle_agent = - start_oracle_agent(stellar_config.clone(), &vault_stellar_secret, shutdown_tx.clone()) - .await - .expect("failed to start agent"); - let oracle_agent = Arc::new(oracle_agent); + let oracle_agent = start_oracle_agent( + stellar_config,vault_stellar_secret,shutdown_tx + ).await; - tokio::spawn( - listen_for_stellar_messages( - stellar_config, - oracle_agent.collector.clone(), - vault_stellar_secret, - shutdown_tx - ) - ); + let oracle_agent = Arc::new(oracle_agent); execute(client, vault_wallet, user_wallet, oracle_agent, vault_id, vault_provider).await -} +} \ No newline at end of file diff --git a/clients/vault/tests/vault_integration_tests.rs b/clients/vault/tests/vault_integration_tests.rs index 7c9aae29c..6cec6a943 100644 --- a/clients/vault/tests/vault_integration_tests.rs +++ b/clients/vault/tests/vault_integration_tests.rs @@ -24,7 +24,7 @@ mod helper; use helper::*; use primitives::DecimalsLookup; use subxt::utils::AccountId32 as AccountId; -use vault::oracle::{random_stellar_relay_config, start_oracle_agent}; +use vault::oracle::{random_stellar_relay_config}; use wallet::keys::get_source_secret_key_from_env; #[tokio::test(flavor = "multi_thread")] @@ -655,7 +655,7 @@ async fn test_issue_execution_succeeds_from_archive_on_network(is_public_network .expect("Conversion should not fail"); let destination_public_key = PublicKey::from_binary(issue.vault_stellar_public_key); let stellar_asset = - primitives::AssetConversion::lookup(*issue.asset).expect("Asset not found"); + primitives::AssetConversion::lookup(issue.asset).expect("Asset not found"); let transaction_response = send_payment_to_address( user_wallet, @@ -681,7 +681,7 @@ async fn test_issue_execution_succeeds_from_archive_on_network(is_public_network let vault_stellar_secret = get_source_secret_key_from_env(is_public_network); // Create new oracle agent with the same configuration as the previous one let oracle_agent = - start_oracle_agent(stellar_config.clone(), &vault_stellar_secret, shutdown_tx) + start_oracle_agent(stellar_config.clone(), vault_stellar_secret, shutdown_tx) .await .expect("failed to start agent"); let oracle_agent = Arc::new(oracle_agent); From 2ad0d7fb56141e3b42d09ecffb4d81a49af9a882 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 13 Aug 2024 20:04:47 +0800 Subject: [PATCH 15/63] reduce timeout by moving it out to `poll_messages_from_stellar()` --- .../connection/connector/message_reader.rs | 40 +++++++++---------- clients/vault/src/oracle/agent.rs | 14 +++---- clients/vault/src/oracle/errors.rs | 24 ----------- clients/vault/src/replace.rs | 3 ++ 4 files changed, 28 insertions(+), 53 deletions(-) diff --git a/clients/stellar-relay-lib/src/connection/connector/message_reader.rs b/clients/stellar-relay-lib/src/connection/connector/message_reader.rs index 9778a6003..cb24d0ea1 100644 --- a/clients/stellar-relay-lib/src/connection/connector/message_reader.rs +++ b/clients/stellar-relay-lib/src/connection/connector/message_reader.rs @@ -43,12 +43,20 @@ pub(crate) async fn poll_messages_from_stellar( } // check for messages from Stellar Node. - let xdr = match read_message_from_stellar(&mut connector).await { - Err(e) => { + // if reading took too much time, flag it as "disconnected" + let xdr = match timeout( + Duration::from_secs(READ_TIMEOUT_IN_SECS), + read_message_from_stellar(&mut connector) + ).await { + Ok(Ok(xdr)) => xdr, + Ok(Err(e)) => { error!("poll_messages_from_stellar(): {e:?}"); break }, - Ok(xdr) => xdr, + Err(_) => { + error!("poll_messages_from_stellar(): timed out"); + break + } }; match connector.process_raw_message(xdr).await { @@ -91,14 +99,10 @@ async fn read_message_from_stellar(connector: &mut Connector) -> Result continue, - Ok(_) if lack_bytes_from_prev == 0 => { + match connector.tcp_stream.read(&mut buff_for_reading) + .await { + Ok(0) => continue, + Ok(_) if lack_bytes_from_prev == 0 => { // if there are no more bytes lacking from the previous message, // then check the size of next stellar message. let expect_msg_len = get_xdr_message_length(&buff_for_reading); @@ -128,8 +132,8 @@ async fn read_message_from_stellar(connector: &mut Connector) -> Result { + } + Ok(size) => { // The next few bytes was read. Add it to the readbuf. lack_bytes_from_prev = lack_bytes_from_prev.saturating_sub(size); readbuf.append(&mut buff_for_reading); @@ -147,15 +151,11 @@ async fn read_message_from_stellar(connector: &mut Connector) -> Result { + } + Err(e) => { trace!("read_message_from_stellar(): ERROR reading messages: {e:?}"); return Err(Error::ReadFailed(e.to_string())) - }, - Err(_) => { - trace!("read_message_from_stellar(): reading time elapsed."); - return Err(Error::Timeout) - }, + } } } } diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index 2e30d7d4a..8c102e5a4 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -223,11 +223,10 @@ mod tests { // We use a random secret key to avoid conflicts with other tests. let agent = start_oracle_agent( specific_stellar_relay_config(true, 0), - &get_random_secret_key(), + get_random_secret_key(), shutdown_sender, ) - .await - .expect("Failed to start agent"); + .await; let mut latest_slot = 0; while !agent.is_proof_building_ready().await{ @@ -258,8 +257,7 @@ mod tests { get_source_secret_key_from_env(is_public_network), shutdown_sender, ) - .await - .expect("Failed to start agent"); + .await; sleep(Duration::from_secs(5)).await; // This slot should be archived on the public network @@ -299,8 +297,7 @@ mod tests { get_source_secret_key_from_env(is_public_network), shutdown_sender, ) - .await - .expect("Failed to start agent"); + .await; sleep(Duration::from_secs(5)).await; // This slot should be archived on the public network @@ -331,8 +328,7 @@ mod tests { get_source_secret_key_from_env(is_public_network), shutdown, ) - .await - .expect("Failed to start agent"); + .await; // This slot should be archived on the public network let target_slot = 44041116; diff --git a/clients/vault/src/oracle/errors.rs b/clients/vault/src/oracle/errors.rs index d1187be79..a167f719a 100644 --- a/clients/vault/src/oracle/errors.rs +++ b/clients/vault/src/oracle/errors.rs @@ -45,30 +45,6 @@ impl From for Error { Error::StellarSdkError(e) } } -// -// impl From for Error { -// fn from(e: std::io::Error) -> Self { -// Error::StdIoError(e) -// } -// } -// -// impl From for Error { -// fn from(e: bincode::Error) -> Self { -// Error::SerdeError(e) -// } -// } -// -// impl From for Error { -// fn from(e: TryFromSliceError) -> Self { -// Error::TryFromSliceError(e) -// } -// } -// -// impl From for Error { -// fn from(e: stellar_relay_lib::Error) -> Self { -// Error::ConnError(e) -// } -// } impl From> for Error { fn from(e: mpsc::error::SendError) -> Self { diff --git a/clients/vault/src/replace.rs b/clients/vault/src/replace.rs index 5c96e8914..180133e45 100644 --- a/clients/vault/src/replace.rs +++ b/clients/vault/src/replace.rs @@ -28,6 +28,7 @@ pub async fn listen_for_accept_replace( payment_margin: Duration, oracle_agent: Arc, ) -> Result<(), ServiceError> { + tracing::info!("listen_for_accept_replace(): started"); let parachain_rpc = ¶chain_rpc; let vault_id_manager = &vault_id_manager; let shutdown_tx = &shutdown_tx; @@ -96,6 +97,8 @@ pub async fn listen_for_replace_requests( event_channel: Sender, accept_replace_requests: bool, ) -> Result<(), ServiceError> { + tracing::info!("listen_for_replace_requests(): started"); + let parachain_rpc = ¶chain_rpc; let vault_id_manager = &vault_id_manager; let event_channel = &event_channel; From 0cb2927d2392b95b2f6be08d01f5a2d3a9dd62f9 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 13 Aug 2024 23:35:45 +0800 Subject: [PATCH 16/63] fix https://github.com/pendulum-chain/spacewalk/actions/runs/10369361893/job/28704943452?pr=545 OracleAgent is now `Arc>`, since the message_sender is updated late in the code; inside the `listen_for_stellar_messages` --- clients/vault/src/issue.rs | 8 +-- clients/vault/src/lib.rs | 4 +- clients/vault/src/main.rs | 6 ++- clients/vault/src/oracle/agent.rs | 52 ++++++++++++------- clients/vault/src/redeem.rs | 10 ++-- clients/vault/src/replace.rs | 7 +-- clients/vault/src/requests/execution.rs | 37 ++++++------- clients/vault/src/requests/helper.rs | 6 +-- clients/vault/src/requests/structs.rs | 11 ++-- clients/vault/src/system.rs | 14 ++--- clients/vault/tests/helper/helper.rs | 6 +-- clients/vault/tests/helper/mod.rs | 4 +- .../vault/tests/vault_integration_tests.rs | 13 +++-- 13 files changed, 91 insertions(+), 87 deletions(-) diff --git a/clients/vault/src/issue.rs b/clients/vault/src/issue.rs index fbdc31201..cc98ddff5 100644 --- a/clients/vault/src/issue.rs +++ b/clients/vault/src/issue.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, sync::Arc, time::Duration}; +use std::{collections::HashMap, time::Duration}; use futures::{channel::mpsc::Sender, future, SinkExt}; use sp_runtime::traits::StaticLookup; @@ -252,7 +252,7 @@ async fn cleanup_ledger_env_map( /// * `issues` - a map of all issue requests pub async fn process_issues_requests( parachain_rpc: SpacewalkParachain, - oracle_agent: Arc, + oracle_agent: ArcRwLock, ledger_env_map: ArcRwLock, issues: ArcRwLock, memos_to_issue_ids: ArcRwLock, @@ -308,13 +308,13 @@ pub async fn execute_issue( tx_env: TransactionEnvelope, issues: ArcRwLock, memos_to_issue_ids: ArcRwLock, - oracle_agent: Arc, + oracle_agent: ArcRwLock, slot: Slot, sender: tokio::sync::oneshot::Sender, ) { // Get the proof of the given slot let proof = - match oracle_agent.get_proof(slot).await { + match oracle_agent.read().await.get_proof(slot).await { Ok(proof) => proof, Err(e) => { tracing::error!("Could not execute Issue for slot {slot} due to error with proof building: {e:?}"); diff --git a/clients/vault/src/lib.rs b/clients/vault/src/lib.rs index 801aa5e4e..0f12e819c 100644 --- a/clients/vault/src/lib.rs +++ b/clients/vault/src/lib.rs @@ -60,14 +60,14 @@ cfg_if::cfg_if! { } } -pub fn tokio_spawn(task_name: &str, future: F) -> tokio::task::JoinHandle +pub fn tokio_spawn(_task_name: &str, future: F) -> tokio::task::JoinHandle where F: std::future::Future + Send + 'static, F::Output: Send + 'static, { cfg_if::cfg_if!{ if #[cfg(all(tokio_unstable, feature = "allow-debugger"))] { - tokio::task::Builder::new().name(task_name).spawn(future).unwrap() + tokio::task::Builder::new().name(_task_name).spawn(future).unwrap() } else { tokio::spawn(future) } diff --git a/clients/vault/src/main.rs b/clients/vault/src/main.rs index e86d1e6b4..171cf2813 100644 --- a/clients/vault/src/main.rs +++ b/clients/vault/src/main.rs @@ -2,6 +2,7 @@ use std::{ net::{Ipv4Addr, SocketAddr}, sync::Arc, }; +use std::time::Duration; use clap::Parser; use futures::Future; @@ -149,7 +150,10 @@ async fn start() -> Result<(), ServiceError> { #[tokio::main] async fn main() { #[cfg(feature = "allow-debugger")] - console_subscriber::init(); + console_subscriber::ConsoleLayer::builder().with_default_env() + .publish_interval(Duration::from_secs(2)) + .event_buffer_capacity(1024*500) + .init(); let exit_code = if let Err(err) = start().await { tracing::error!("Exiting: {}", err); diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index 8c102e5a4..ff92a0cfb 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -1,14 +1,12 @@ use std::{sync::Arc, time::Duration}; -use std::future::Future; use tokio::{ - sync::{mpsc, RwLock}, + sync::RwLock, time::{sleep, timeout}, }; use tokio::time::Instant; use runtime::ShutdownSender; -use runtime::stellar::SecretKey; use stellar_relay_lib::{ connect_to_stellar_overlay_network, helper::to_base64_xdr_string, sdk::types::StellarMessage, StellarOverlayConfig, @@ -18,7 +16,7 @@ use crate::oracle::{ collector::ScpMessageCollector, errors::Error, types::StellarMessageSender, AddTxSet, Proof, }; use wallet::Slot; -use crate::tokio_spawn; +use crate::ArcRwLock; pub struct OracleAgent { pub collector: Arc>, @@ -86,7 +84,7 @@ async fn handle_message( pub async fn listen_for_stellar_messages( config: StellarOverlayConfig, - collector: Arc>, + oracle_agent:ArcRwLock, secret_key_as_string: String, shutdown_sender: ShutdownSender, ) -> Result<(),service::Error> { @@ -100,11 +98,16 @@ pub async fn listen_for_stellar_messages( // use StellarOverlayConnection's sender to send message to Stellar let sender = overlay_conn.sender(); + { + oracle_agent.write().await.message_sender = Some(sender.clone()); + }; // log a new message received, every 1 minute. let interval = Duration::from_secs(60); let mut next_time = Instant::now() + interval; loop { + let collector = oracle_agent.read().await.collector.clone(); + match overlay_conn.listen().await { Ok(None) => {}, Ok(Some(msg)) => { @@ -135,18 +138,18 @@ pub async fn listen_for_stellar_messages( Ok(()) } -#[cfg(test)] +#[cfg(any(test, feature = "integration"))] pub async fn start_oracle_agent( cfg: StellarOverlayConfig, vault_stellar_secret: String, shutdown_sender: ShutdownSender -) -> OracleAgent { - let oracle_agent = OracleAgent::new(&cfg, shutdown_sender.clone()); +) -> ArcRwLock { + let oracle_agent = Arc::new(RwLock::new(OracleAgent::new(&cfg, shutdown_sender.clone()))); tokio::spawn( listen_for_stellar_messages( cfg, - oracle_agent.collector.clone(), + oracle_agent.clone(), vault_stellar_secret, shutdown_sender ) @@ -228,16 +231,16 @@ mod tests { ) .await; - let mut latest_slot = 0; - while !agent.is_proof_building_ready().await{ + while !agent.read().await.is_proof_building_ready().await{ sleep(Duration::from_secs(1)).await; } - latest_slot = agent.collector.read().await.last_slot_index(); + + let latest_slot = agent.read().await.collector.read().await.last_slot_index(); // let's wait for envelopes and txset to be available for creating a proof sleep(Duration::from_secs(5)).await; - let proof_result = agent.get_proof(latest_slot).await; + let proof_result = agent.read().await.get_proof(latest_slot).await; assert!(proof_result.is_ok(), "Failed to get proof for slot: {}", latest_slot); } @@ -259,10 +262,13 @@ mod tests { ) .await; - sleep(Duration::from_secs(5)).await; + while !agent.read().await.is_proof_building_ready().await{ + sleep(Duration::from_secs(1)).await; + } + // This slot should be archived on the public network let target_slot = 44041116; - let proof = agent.get_proof(target_slot).await.expect("should return a proof"); + let proof = agent.read().await.get_proof(target_slot).await.expect("should return a proof"); assert_eq!(proof.slot(), 44041116); @@ -299,10 +305,13 @@ mod tests { ) .await; - sleep(Duration::from_secs(5)).await; + while !agent.read().await.is_proof_building_ready().await{ + sleep(Duration::from_secs(1)).await; + } + // This slot should be archived on the public network let target_slot = 44041116; - let proof = agent.get_proof(target_slot).await.expect("should return a proof"); + let proof = agent.read().await.get_proof(target_slot).await.expect("should return a proof"); assert_eq!(proof.slot(), 44041116); @@ -332,9 +341,12 @@ mod tests { // This slot should be archived on the public network let target_slot = 44041116; - tracing::info!("let's sleep for 3 seconds,to get the network up and running"); - sleep(Duration::from_secs(3)).await; - let proof_result = agent.get_proof(target_slot).await; + + while !agent.read().await.is_proof_building_ready().await{ + sleep(Duration::from_secs(1)).await; + } + + let proof_result = agent.read().await.get_proof(target_slot).await; assert!(matches!(proof_result, Err(Error::ProofTimeout(_)))); diff --git a/clients/vault/src/redeem.rs b/clients/vault/src/redeem.rs index c248b8b6e..d89fe9363 100644 --- a/clients/vault/src/redeem.rs +++ b/clients/vault/src/redeem.rs @@ -1,9 +1,9 @@ -use std::{sync::Arc, time::Duration}; +use std::time::Duration; use runtime::{RedeemPallet, RequestRedeemEvent, ShutdownSender, SpacewalkParachain}; use service::{spawn_cancelable, Error as ServiceError}; -use crate::{oracle::OracleAgent, requests::*, system::VaultIdManager, Error}; +use crate::{oracle::OracleAgent, requests::*, system::VaultIdManager, Error, ArcRwLock}; /// Listen for RequestRedeemEvent directed at this vault; upon reception, transfer /// the respective Stellar asset and call execute_redeem. @@ -18,7 +18,7 @@ pub async fn listen_for_redeem_requests( parachain_rpc: SpacewalkParachain, vault_id_manager: VaultIdManager, payment_margin: Duration, - oracle_agent: Arc, + oracle_agent: ArcRwLock, ) -> Result<(), ServiceError> { parachain_rpc .on_event::( @@ -33,8 +33,8 @@ pub async fn listen_for_redeem_requests( // we will need to capture the arguments by value rather than by reference, so clone // these: let parachain_rpc = parachain_rpc.clone(); + let oracle_agent_clone = oracle_agent.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...", @@ -46,7 +46,7 @@ pub async fn listen_for_redeem_requests( parachain_rpc.get_redeem_request(event.redeem_id).await?, payment_margin, )?; - request.pay_and_execute(parachain_rpc, vault, oracle_agent).await + request.pay_and_execute(parachain_rpc, vault, oracle_agent_clone).await } .await; diff --git a/clients/vault/src/replace.rs b/clients/vault/src/replace.rs index 180133e45..e5845b920 100644 --- a/clients/vault/src/replace.rs +++ b/clients/vault/src/replace.rs @@ -3,10 +3,7 @@ use std::{sync::Arc, time::Duration}; use futures::{channel::mpsc::Sender, future::try_join3, SinkExt}; use tokio::sync::RwLock; -use crate::{ - cancellation::Event, error::Error, oracle::OracleAgent, requests::Request, - system::VaultIdManager, -}; +use crate::{ArcRwLock, cancellation::Event, error::Error, oracle::OracleAgent, requests::Request, system::VaultIdManager}; use runtime::{ AcceptReplaceEvent, CollateralBalancesPallet, ExecuteReplaceEvent, PrettyPrint, ReplacePallet, RequestReplaceEvent, ShutdownSender, SpacewalkParachain, UtilFuncs, VaultId, @@ -26,7 +23,7 @@ pub async fn listen_for_accept_replace( parachain_rpc: SpacewalkParachain, vault_id_manager: VaultIdManager, payment_margin: Duration, - oracle_agent: Arc, + oracle_agent: ArcRwLock, ) -> Result<(), ServiceError> { tracing::info!("listen_for_accept_replace(): started"); let parachain_rpc = ¶chain_rpc; diff --git a/clients/vault/src/requests/execution.rs b/clients/vault/src/requests/execution.rs index 756b644fb..79603d0cf 100644 --- a/clients/vault/src/requests/execution.rs +++ b/clients/vault/src/requests/execution.rs @@ -1,16 +1,11 @@ -use crate::{ - error::Error, - oracle::OracleAgent, - requests::{ - helper::{ - get_all_transactions_of_wallet_async, get_request_for_stellar_tx, - retrieve_open_redeem_replace_requests_async, PayAndExecuteExt, - }, - structs::Request, - PayAndExecute, +use crate::{ArcRwLock, error::Error, oracle::OracleAgent, requests::{ + helper::{ + get_all_transactions_of_wallet_async, get_request_for_stellar_tx, + retrieve_open_redeem_replace_requests_async, PayAndExecuteExt, }, - VaultIdManager, YIELD_RATE, -}; + structs::Request, + PayAndExecute, +}, VaultIdManager, YIELD_RATE}; use async_trait::async_trait; use governor::{ clock::{Clock, ReasonablyRealtime}, @@ -41,10 +36,10 @@ const MAX_EXECUTION_RETRIES: u32 = 3; /// * `rate_limiter` - a rate limiter async fn spawn_tasks_to_execute_open_requests_async( requests: &mut HashMap, - wallet: Arc>, + wallet: ArcRwLock, shutdown_tx: ShutdownSender, parachain_rpc: &SpacewalkParachain, - oracle_agent: Arc, + oracle_agent: ArcRwLock, rate_limiter: Arc>, ) where S: DirectStateStore, @@ -96,7 +91,7 @@ fn spawn_task_to_execute_open_request( transaction: TransactionResponse, shutdown_tx: ShutdownSender, parachain_rpc: SpacewalkParachain, - oracle_agent: Arc, + oracle_agent: ArcRwLock, ) -> TextMemo { let hash_as_memo = derive_shortened_request_id(&request.hash_inner()); @@ -147,7 +142,7 @@ async fn execute_open_request_async( tx_envelope: TransactionEnvelope, slot: Slot, parachain_rpc: SpacewalkParachain, - oracle_agent: Arc, + oracle_agent: ArcRwLock, ) { let mut retry_count = 0; // A counter for every execution retry @@ -156,7 +151,7 @@ async fn execute_open_request_async( tracing::info!("Performing retry #{retry_count} out of {MAX_EXECUTION_RETRIES} retries for {:?} request #{}",request.request_type(),request.hash()); } - match oracle_agent.get_proof(slot).await { + match oracle_agent.read().await.get_proof(slot).await { Ok(proof) => { let Err(e) = request.execute(parachain_rpc.clone(), tx_envelope.clone(), proof).await @@ -211,7 +206,7 @@ where vault_id_manager: VaultIdManager, shutdown_tx: ShutdownSender, parachain_rpc: &SpacewalkParachain, - oracle_agent: Arc, + oracle_agent: ArcRwLock, rate_limiter: Arc>, ) { for (_, request) in requests { @@ -236,7 +231,7 @@ where request: Request, vault_id_manager: VaultIdManager, parachain_rpc: SpacewalkParachain, - oracle_agent: Arc, + oracle_agent: ArcRwLock, rate_limiter: Arc>, ) { let Some(vault) = vault_id_manager.get_vault(request.vault_id()).await else { @@ -288,7 +283,7 @@ pub async fn execute_open_requests( parachain_rpc: SpacewalkParachain, vault_id_manager: VaultIdManager, wallet: Arc>, - oracle_agent: Arc, + oracle_agent: ArcRwLock, payment_margin: Duration, precheck_signal: tokio::sync::broadcast::Sender<()> ) -> Result<(), ServiceError> { @@ -305,7 +300,7 @@ pub async fn execute_open_requests( let rate_limiter = Arc::new(RateLimiter::direct(YIELD_RATE)); - while !oracle_agent.is_proof_building_ready().await { + while !oracle_agent.read().await.is_proof_building_ready().await { tracing::debug!("execute_open_requests(): agent is not yet ready. Waiting..."); } diff --git a/clients/vault/src/requests/helper.rs b/clients/vault/src/requests/helper.rs index f5f2a62bc..eb24dd97b 100644 --- a/clients/vault/src/requests/helper.rs +++ b/clients/vault/src/requests/helper.rs @@ -3,7 +3,7 @@ use futures::try_join; use std::{collections::HashMap, sync::Arc, time::Duration}; use tokio::sync::RwLock; -use crate::{requests::structs::Request, Error, VaultIdManager}; +use crate::{requests::structs::Request, Error, VaultIdManager, ArcRwLock}; use crate::oracle::OracleAgent; use primitives::{derive_shortened_request_id, TextMemo, TransactionEnvelopeExt}; @@ -32,7 +32,7 @@ pub(crate) trait PayAndExecuteExt { vault_id_manager: VaultIdManager, shutdown_tx: ShutdownSender, parachain_rpc: &SpacewalkParachain, - oracle_agent: Arc, + oracle_agent: ArcRwLock, rate_limiter: Arc, ); @@ -52,7 +52,7 @@ pub(crate) trait PayAndExecuteExt { request: Request, vault_id_manager: VaultIdManager, parachain_rpc: SpacewalkParachain, - oracle_agent: Arc, + oracle_agent: ArcRwLock, rate_limiter: Arc, ); } diff --git a/clients/vault/src/requests/structs.rs b/clients/vault/src/requests/structs.rs index 3b657ea1b..84b651aaa 100644 --- a/clients/vault/src/requests/structs.rs +++ b/clients/vault/src/requests/structs.rs @@ -1,9 +1,4 @@ -use crate::{ - metrics::update_stellar_metrics, - oracle::{OracleAgent, Proof}, - system::VaultData, - Error, -}; +use crate::{metrics::update_stellar_metrics, oracle::{OracleAgent, Proof}, system::VaultData, Error, ArcRwLock}; use primitives::{stellar::PublicKey, CurrencyId}; use runtime::{ Error as EnrichedError, OraclePallet, Recoverability, RedeemPallet, ReplacePallet, RetryPolicy, @@ -147,7 +142,7 @@ impl Request { &self, parachain_rpc: P, vault: VaultData, - oracle_agent: Arc, + oracle_agent: ArcRwLock, ) -> Result<(), Error> { // ensure the deadline has not expired yet if let Some(ref deadline) = self.deadline { @@ -159,7 +154,7 @@ impl Request { let response = self.transfer_stellar_asset(vault.stellar_wallet.clone()).await?; let tx_env = response.to_envelope()?; - let proof = oracle_agent.get_proof(response.ledger as Slot).await?; + let proof = oracle_agent.read().await.get_proof(response.ledger as Slot).await?; let _ = update_stellar_metrics(&vault, ¶chain_rpc).await; self.execute(parachain_rpc, tx_env, proof).await diff --git a/clients/vault/src/system.rs b/clients/vault/src/system.rs index 0d45c17c8..970a95c43 100644 --- a/clients/vault/src/system.rs +++ b/clients/vault/src/system.rs @@ -266,7 +266,7 @@ pub struct VaultService { shutdown: ShutdownSender, vault_id_manager: VaultIdManager, secret_key: String, - agent: Option>, + agent: Option>, } #[async_trait] @@ -447,7 +447,7 @@ impl VaultService { &self, is_public_network: bool, shutdown_sender: ShutdownSender, - ) -> Result, ServiceError> { + ) -> Result, ServiceError> { let stellar_overlay_cfg = self.stellar_overlay_cfg()?; // check if both the config file and the wallet are the same. @@ -455,7 +455,7 @@ impl VaultService { return Err(ServiceError::IncompatibleNetwork); } - Ok(Arc::new(OracleAgent::new(&stellar_overlay_cfg,shutdown_sender))) + Ok(Arc::new(RwLock::new(OracleAgent::new(&stellar_overlay_cfg,shutdown_sender)))) } fn create_issue_tasks( @@ -465,7 +465,7 @@ impl VaultService { startup_height: BlockNumber, account_id: AccountId, vault_public_key: PublicKey, - oracle_agent: Arc, + oracle_agent: ArcRwLock, issue_map: ArcRwLock, ledger_env_map: ArcRwLock, memos_to_issue_ids: ArcRwLock, @@ -528,7 +528,7 @@ impl VaultService { replace_event_rx: mpscReceiver, startup_height: BlockNumber, account_id: AccountId, - oracle_agent: Arc, + oracle_agent: ArcRwLock, ) -> Vec<(&str, ServiceTask)> { vec![ ( @@ -642,7 +642,7 @@ impl VaultService { account_id: AccountId, is_public_network: bool, vault_public_key: PublicKey, - oracle_agent: Arc, + oracle_agent: ArcRwLock, issue_map: ArcRwLock, ledger_env_map: ArcRwLock, memos_to_issue_ids: ArcRwLock, @@ -829,7 +829,7 @@ impl VaultService { run( listen_for_stellar_messages( self.stellar_overlay_cfg()?, - oracle_agent.collector.clone(), + oracle_agent.clone(), self.secret_key(), self.shutdown.clone() ) diff --git a/clients/vault/tests/helper/helper.rs b/clients/vault/tests/helper/helper.rs index fb8d947c1..178a0c97b 100644 --- a/clients/vault/tests/helper/helper.rs +++ b/clients/vault/tests/helper/helper.rs @@ -13,7 +13,7 @@ use runtime::{ }; use sp_keyring::AccountKeyring; use sp_runtime::traits::StaticLookup; -use std::{sync::Arc, time::Duration}; +use std::time::Duration; use stellar_relay_lib::sdk::{PublicKey, SecretKey}; use subxt::utils::AccountId32 as AccountId; use vault::{oracle::OracleAgent, ArcRwLock}; @@ -177,7 +177,7 @@ pub async fn assert_issue( wallet: ArcRwLock, vault_id: &VaultId, amount: u128, - oracle_agent: Arc, + oracle_agent: ArcRwLock, ) { let issue = parachain_rpc .request_issue(amount, vault_id) @@ -203,7 +203,7 @@ pub async fn assert_issue( let slot = response.ledger as u64; // Loop pending proofs until it is ready - let proof = oracle_agent.get_proof(slot).await.expect("Proof should be available"); + let proof = oracle_agent.read().await.get_proof(slot).await.expect("Proof should be available"); let tx_envelope_xdr_encoded = response.envelope_xdr; let (envelopes_xdr_encoded, tx_set_xdr_encoded) = proof.encode(); diff --git a/clients/vault/tests/helper/mod.rs b/clients/vault/tests/helper/mod.rs index 2b413694f..7f8ac2fbb 100644 --- a/clients/vault/tests/helper/mod.rs +++ b/clients/vault/tests/helper/mod.rs @@ -115,7 +115,7 @@ pub async fn test_with_vault( SubxtClient, ArcRwLock, ArcRwLock, - Arc, + ArcRwLock, VaultId, SpacewalkParachain, ) -> F, @@ -148,7 +148,5 @@ where stellar_config,vault_stellar_secret,shutdown_tx ).await; - let oracle_agent = Arc::new(oracle_agent); - execute(client, vault_wallet, user_wallet, oracle_agent, vault_id, vault_provider).await } \ No newline at end of file diff --git a/clients/vault/tests/vault_integration_tests.rs b/clients/vault/tests/vault_integration_tests.rs index 6cec6a943..f12eff6ac 100644 --- a/clients/vault/tests/vault_integration_tests.rs +++ b/clients/vault/tests/vault_integration_tests.rs @@ -24,7 +24,7 @@ mod helper; use helper::*; use primitives::DecimalsLookup; use subxt::utils::AccountId32 as AccountId; -use vault::oracle::{random_stellar_relay_config}; +use vault::oracle::{random_stellar_relay_config, start_oracle_agent}; use wallet::keys::get_source_secret_key_from_env; #[tokio::test(flavor = "multi_thread")] @@ -682,12 +682,15 @@ async fn test_issue_execution_succeeds_from_archive_on_network(is_public_network // Create new oracle agent with the same configuration as the previous one let oracle_agent = start_oracle_agent(stellar_config.clone(), vault_stellar_secret, shutdown_tx) - .await - .expect("failed to start agent"); + .await; let oracle_agent = Arc::new(oracle_agent); + while !oracle_agent.read().await.is_proof_building_ready().await{ + sleep(Duration::from_secs(1)).await; + } + // Loop pending proofs until it is ready - let proof = oracle_agent.get_proof(slot).await.expect("Proof should be available"); + let proof = oracle_agent.read().await.get_proof(slot).await.expect("Proof should be available"); let tx_envelope_xdr_encoded = transaction_response.envelope_xdr; let (envelopes_xdr_encoded, tx_set_xdr_encoded) = proof.encode(); @@ -774,7 +777,7 @@ async fn test_issue_overpayment_succeeds() { let slot = transaction_response.ledger as u64; // Loop pending proofs until it is ready - let proof = oracle_agent.get_proof(slot).await.expect("Proof should be available"); + let proof = oracle_agent.read().await.get_proof(slot).await.expect("Proof should be available"); let tx_envelope_xdr_encoded = transaction_response.envelope_xdr; let (envelopes_xdr_encoded, tx_set_xdr_encoded) = proof.encode(); From 7e891d43f14dc2b498d4e1c155baa7bcc5829c16 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Fri, 23 Aug 2024 04:18:22 +0800 Subject: [PATCH 17/63] move checking of proof building inside `fn start_oracle_agent()` for integration tests --- .../stellar_relay_config_frankfurt.json | 2 +- .../mainnet/stellar_relay_config_iowa.json | 2 +- .../stellar_relay_config_singapore.json | 2 +- .../stellar_relay_config_sdftest1.json | 6 +++--- .../stellar_relay_config_sdftest2.json | 6 +++--- .../stellar_relay_config_sdftest3.json | 6 +++--- clients/vault/src/main.rs | 1 - clients/vault/src/oracle/agent.rs | 20 ++++--------------- .../vault/tests/vault_integration_tests.rs | 6 ++---- 9 files changed, 18 insertions(+), 33 deletions(-) diff --git a/clients/vault/resources/config/mainnet/stellar_relay_config_frankfurt.json b/clients/vault/resources/config/mainnet/stellar_relay_config_frankfurt.json index 7a93a15aa..7eabe4eb4 100644 --- a/clients/vault/resources/config/mainnet/stellar_relay_config_frankfurt.json +++ b/clients/vault/resources/config/mainnet/stellar_relay_config_frankfurt.json @@ -7,7 +7,7 @@ "ledger_version": 21, "overlay_version": 34, "overlay_min_version": 32, - "version_str": "stellar-core 21.1.0 (b3aeb14cc798f6d11deb2be913041be916f3b0cc)", + "version_str": "stellar-core 21.2.0 (d78f48eacabb51753e34443de7618b956e61c59f)", "is_pub_net": true }, "stellar_history_archive_urls": [ diff --git a/clients/vault/resources/config/mainnet/stellar_relay_config_iowa.json b/clients/vault/resources/config/mainnet/stellar_relay_config_iowa.json index 697f731af..d2e9aa416 100644 --- a/clients/vault/resources/config/mainnet/stellar_relay_config_iowa.json +++ b/clients/vault/resources/config/mainnet/stellar_relay_config_iowa.json @@ -7,7 +7,7 @@ "ledger_version": 21, "overlay_version": 34, "overlay_min_version": 32, - "version_str": "stellar-core 21.1.0 (b3aeb14cc798f6d11deb2be913041be916f3b0cc)", + "version_str": "stellar-core 21.2.0 (d78f48eacabb51753e34443de7618b956e61c59f)", "is_pub_net": true }, "stellar_history_archive_urls": [ diff --git a/clients/vault/resources/config/mainnet/stellar_relay_config_singapore.json b/clients/vault/resources/config/mainnet/stellar_relay_config_singapore.json index 504213c9e..2e2c23670 100644 --- a/clients/vault/resources/config/mainnet/stellar_relay_config_singapore.json +++ b/clients/vault/resources/config/mainnet/stellar_relay_config_singapore.json @@ -7,7 +7,7 @@ "ledger_version": 21, "overlay_version": 34, "overlay_min_version": 32, - "version_str": "stellar-core 21.1.0 (b3aeb14cc798f6d11deb2be913041be916f3b0cc)", + "version_str": "stellar-core 21.2.0 (d78f48eacabb51753e34443de7618b956e61c59f)", "is_pub_net": true }, "stellar_history_archive_urls": [ diff --git a/clients/vault/resources/config/testnet/stellar_relay_config_sdftest1.json b/clients/vault/resources/config/testnet/stellar_relay_config_sdftest1.json index 44e908d25..17da944d8 100644 --- a/clients/vault/resources/config/testnet/stellar_relay_config_sdftest1.json +++ b/clients/vault/resources/config/testnet/stellar_relay_config_sdftest1.json @@ -5,9 +5,9 @@ }, "node_info": { "ledger_version": 21, - "overlay_version": 34, - "overlay_min_version": 32, - "version_str": "stellar-core 21.2.0 (d78f48eacabb51753e34443de7618b956e61c59f)", + "overlay_version": 35, + "overlay_min_version": 33, + "version_str": "stellar-core 21.3.0.rc1 (55ec348409407ec7def75cae60ae1b520bef4adc)", "is_pub_net": false }, "stellar_history_archive_urls": [ diff --git a/clients/vault/resources/config/testnet/stellar_relay_config_sdftest2.json b/clients/vault/resources/config/testnet/stellar_relay_config_sdftest2.json index 3b431ef78..68a13de6e 100644 --- a/clients/vault/resources/config/testnet/stellar_relay_config_sdftest2.json +++ b/clients/vault/resources/config/testnet/stellar_relay_config_sdftest2.json @@ -5,9 +5,9 @@ }, "node_info": { "ledger_version": 21, - "overlay_version": 34, - "overlay_min_version": 32, - "version_str": "stellar-core 21.2.0 (d78f48eacabb51753e34443de7618b956e61c59f)", + "overlay_version": 35, + "overlay_min_version": 33, + "version_str": "stellar-core 21.3.0.rc1 (55ec348409407ec7def75cae60ae1b520bef4adc)", "is_pub_net": false }, "stellar_history_archive_urls": [ diff --git a/clients/vault/resources/config/testnet/stellar_relay_config_sdftest3.json b/clients/vault/resources/config/testnet/stellar_relay_config_sdftest3.json index 404ded3bb..961b33098 100644 --- a/clients/vault/resources/config/testnet/stellar_relay_config_sdftest3.json +++ b/clients/vault/resources/config/testnet/stellar_relay_config_sdftest3.json @@ -5,9 +5,9 @@ }, "node_info": { "ledger_version": 21, - "overlay_version": 34, - "overlay_min_version": 32, - "version_str": "stellar-core 21.2.0 (d78f48eacabb51753e34443de7618b956e61c59f)", + "overlay_version": 35, + "overlay_min_version": 33, + "version_str": "stellar-core 21.3.0.rc1 (55ec348409407ec7def75cae60ae1b520bef4adc)", "is_pub_net": false }, "stellar_history_archive_urls": [ diff --git a/clients/vault/src/main.rs b/clients/vault/src/main.rs index 171cf2813..9bcce93aa 100644 --- a/clients/vault/src/main.rs +++ b/clients/vault/src/main.rs @@ -2,7 +2,6 @@ use std::{ net::{Ipv4Addr, SocketAddr}, sync::Arc, }; -use std::time::Duration; use clap::Parser; use futures::Future; diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index ff92a0cfb..7ca6c1d34 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -155,6 +155,10 @@ pub async fn start_oracle_agent( ) ); + while !oracle_agent.read().await.is_proof_building_ready().await{ + sleep(Duration::from_millis(500)).await; + } + oracle_agent } @@ -231,10 +235,6 @@ mod tests { ) .await; - while !agent.read().await.is_proof_building_ready().await{ - sleep(Duration::from_secs(1)).await; - } - let latest_slot = agent.read().await.collector.read().await.last_slot_index(); // let's wait for envelopes and txset to be available for creating a proof @@ -262,10 +262,6 @@ mod tests { ) .await; - while !agent.read().await.is_proof_building_ready().await{ - sleep(Duration::from_secs(1)).await; - } - // This slot should be archived on the public network let target_slot = 44041116; let proof = agent.read().await.get_proof(target_slot).await.expect("should return a proof"); @@ -305,10 +301,6 @@ mod tests { ) .await; - while !agent.read().await.is_proof_building_ready().await{ - sleep(Duration::from_secs(1)).await; - } - // This slot should be archived on the public network let target_slot = 44041116; let proof = agent.read().await.get_proof(target_slot).await.expect("should return a proof"); @@ -342,10 +334,6 @@ mod tests { // This slot should be archived on the public network let target_slot = 44041116; - while !agent.read().await.is_proof_building_ready().await{ - sleep(Duration::from_secs(1)).await; - } - let proof_result = agent.read().await.get_proof(target_slot).await; assert!(matches!(proof_result, Err(Error::ProofTimeout(_)))); diff --git a/clients/vault/tests/vault_integration_tests.rs b/clients/vault/tests/vault_integration_tests.rs index f12eff6ac..df3f2837f 100644 --- a/clients/vault/tests/vault_integration_tests.rs +++ b/clients/vault/tests/vault_integration_tests.rs @@ -685,10 +685,6 @@ async fn test_issue_execution_succeeds_from_archive_on_network(is_public_network .await; let oracle_agent = Arc::new(oracle_agent); - while !oracle_agent.read().await.is_proof_building_ready().await{ - sleep(Duration::from_secs(1)).await; - } - // Loop pending proofs until it is ready let proof = oracle_agent.read().await.get_proof(slot).await.expect("Proof should be available"); let tx_envelope_xdr_encoded = transaction_response.envelope_xdr; @@ -1168,6 +1164,8 @@ async fn test_execute_open_requests_succeeds() { let (precheck_signal, mut rceiver) = tokio::sync::broadcast::channel(1); let shutdown_tx = ShutdownSender::new(); + + join5( vault::service::execute_open_requests( shutdown_tx.clone(), From deba3daadd8a838582e6fa5ff88ec3a6808e3fc3 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Wed, 4 Sep 2024 18:41:19 +0800 Subject: [PATCH 18/63] rebase --- clients/runtime/src/rpc.rs | 5 +-- .../connection/connector/message_reader.rs | 6 ++-- clients/stellar-relay-lib/src/tests/mod.rs | 33 ++++++++++++------- clients/vault/src/main.rs | 7 +--- clients/vault/src/oracle/agent.rs | 3 -- .../vault/tests/vault_integration_tests.rs | 2 +- 6 files changed, 27 insertions(+), 29 deletions(-) diff --git a/clients/runtime/src/rpc.rs b/clients/runtime/src/rpc.rs index 7bd347655..30885154f 100644 --- a/clients/runtime/src/rpc.rs +++ b/clients/runtime/src/rpc.rs @@ -5,7 +5,6 @@ use async_trait::async_trait; use codec::Encode; use futures::{future::join_all, stream::StreamExt, FutureExt, SinkExt}; use jsonrpsee::core::{client::Client, JsonValue}; -use jsonrpsee::tracing; use subxt::{ backend::{legacy::LegacyRpcMethods, rpc::RpcClient}, blocks::ExtrinsicEvents, @@ -1086,9 +1085,7 @@ impl IssuePallet for SpacewalkParachain { let key_hash = issue_id.as_slice(); // last bytes are the raw key let key = &key_hash[key_hash.len() - 32..]; - let key = H256::from_slice(key); - tracing::info!("get_all_active_issues: found {}", key.to_string()); - issue_requests.push((key, request)); + issue_requests.push((H256::from_slice(key), request)); } } Ok(issue_requests) diff --git a/clients/stellar-relay-lib/src/connection/connector/message_reader.rs b/clients/stellar-relay-lib/src/connection/connector/message_reader.rs index cb24d0ea1..a22b22bf4 100644 --- a/clients/stellar-relay-lib/src/connection/connector/message_reader.rs +++ b/clients/stellar-relay-lib/src/connection/connector/message_reader.rs @@ -29,7 +29,7 @@ pub(crate) async fn poll_messages_from_stellar( if send_to_user_sender.is_closed() { info!("poll_messages_from_stellar(): closing receiver during disconnection"); // close this channel as communication to user was closed. - break + break; } // check for messages from user. @@ -74,7 +74,7 @@ pub(crate) async fn poll_messages_from_stellar( Ok(None) => {}, Err(e) => { error!("poll_messages_from_stellar(): Error occurred during processing xdr message: {e:?}"); - break + break; }, } } @@ -111,7 +111,7 @@ async fn read_message_from_stellar(connector: &mut Connector) -> Result Date: Mon, 9 Sep 2024 11:37:20 +0800 Subject: [PATCH 19/63] https://github.com/pendulum-chain/spacewalk/actions/runs/10724299988/job/29739630347?pr=545#step:13:1938 --- clients/vault/src/main.rs | 2 +- clients/vault/tests/helper/mod.rs | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/clients/vault/src/main.rs b/clients/vault/src/main.rs index 0d82814bf..5638af631 100644 --- a/clients/vault/src/main.rs +++ b/clients/vault/src/main.rs @@ -146,7 +146,7 @@ async fn start() -> Result<(), ServiceError> { async fn main() { #[cfg(feature = "allow-debugger")] console_subscriber::ConsoleLayer::builder().with_default_env() - .publish_interval(Duration::from_secs(2)) + .publish_interval(std::time::Duration::from_secs(2)) .event_buffer_capacity(1024*500) .init(); diff --git a/clients/vault/tests/helper/mod.rs b/clients/vault/tests/helper/mod.rs index ff3047f63..edc2079da 100644 --- a/clients/vault/tests/helper/mod.rs +++ b/clients/vault/tests/helper/mod.rs @@ -20,6 +20,7 @@ use std::{future::Future, sync::Arc}; use stellar_relay_lib::StellarOverlayConfig; use subxt::utils::AccountId32 as AccountId; use tokio::sync::RwLock; +use tokio::time::sleep; use vault::{ oracle::{random_stellar_relay_config, OracleAgent}, ArcRwLock, @@ -149,7 +150,9 @@ where ).await; // continue ONLY if the oracle agent has received the first slot - while oracle_agent.last_slot_index().await == 0 {} + while !oracle_agent.read().await.is_proof_building_ready() { + sleep(std::time::Duration::from_millis(500)).await; + } execute(client, vault_wallet, user_wallet, oracle_agent, vault_id, vault_provider).await } \ No newline at end of file From a4f2477fb5491875e0b3f4be401905d9548f9c20 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Mon, 9 Sep 2024 17:19:41 +0800 Subject: [PATCH 20/63] await before performing a compare --- clients/vault/tests/helper/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/vault/tests/helper/mod.rs b/clients/vault/tests/helper/mod.rs index edc2079da..9f19d47d9 100644 --- a/clients/vault/tests/helper/mod.rs +++ b/clients/vault/tests/helper/mod.rs @@ -150,7 +150,7 @@ where ).await; // continue ONLY if the oracle agent has received the first slot - while !oracle_agent.read().await.is_proof_building_ready() { + while !oracle_agent.read().await.is_proof_building_ready().await { sleep(std::time::Duration::from_millis(500)).await; } From 7b45cc5018bc2d817476b7b9ddcd842ee0094f6f Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Wed, 11 Sep 2024 23:06:40 +0800 Subject: [PATCH 21/63] update test config, and add `ntest` for long-running test cases --- .../config/testnet/stellar_relay_config_sdftest1.json | 6 +++--- .../config/testnet/stellar_relay_config_sdftest2.json | 6 +++--- .../config/testnet/stellar_relay_config_sdftest3.json | 6 +++--- .../config/testnet/stellar_relay_config_sdftest1.json | 2 +- .../config/testnet/stellar_relay_config_sdftest2.json | 2 +- .../config/testnet/stellar_relay_config_sdftest3.json | 2 +- clients/vault/tests/vault_integration_tests.rs | 1 + 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest1.json b/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest1.json index 44e908d25..070253e8c 100644 --- a/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest1.json +++ b/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest1.json @@ -5,9 +5,9 @@ }, "node_info": { "ledger_version": 21, - "overlay_version": 34, - "overlay_min_version": 32, - "version_str": "stellar-core 21.2.0 (d78f48eacabb51753e34443de7618b956e61c59f)", + "overlay_version": 35, + "overlay_min_version": 33, + "version_str": "stellar-core 21.3.1 (4ede19620438bcd136276cdc8d4ed1f2c3b64624)", "is_pub_net": false }, "stellar_history_archive_urls": [ diff --git a/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest2.json b/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest2.json index 3b431ef78..003d98e12 100644 --- a/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest2.json +++ b/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest2.json @@ -5,9 +5,9 @@ }, "node_info": { "ledger_version": 21, - "overlay_version": 34, - "overlay_min_version": 32, - "version_str": "stellar-core 21.2.0 (d78f48eacabb51753e34443de7618b956e61c59f)", + "overlay_version": 35, + "overlay_min_version": 33, + "version_str": "stellar-core 21.3.1 (4ede19620438bcd136276cdc8d4ed1f2c3b64624)", "is_pub_net": false }, "stellar_history_archive_urls": [ diff --git a/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest3.json b/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest3.json index 404ded3bb..9e6cbaf2d 100644 --- a/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest3.json +++ b/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest3.json @@ -5,9 +5,9 @@ }, "node_info": { "ledger_version": 21, - "overlay_version": 34, - "overlay_min_version": 32, - "version_str": "stellar-core 21.2.0 (d78f48eacabb51753e34443de7618b956e61c59f)", + "overlay_version": 35, + "overlay_min_version": 33, + "version_str": "stellar-core 21.3.1 (4ede19620438bcd136276cdc8d4ed1f2c3b64624)", "is_pub_net": false }, "stellar_history_archive_urls": [ diff --git a/clients/vault/resources/config/testnet/stellar_relay_config_sdftest1.json b/clients/vault/resources/config/testnet/stellar_relay_config_sdftest1.json index 17da944d8..070253e8c 100644 --- a/clients/vault/resources/config/testnet/stellar_relay_config_sdftest1.json +++ b/clients/vault/resources/config/testnet/stellar_relay_config_sdftest1.json @@ -7,7 +7,7 @@ "ledger_version": 21, "overlay_version": 35, "overlay_min_version": 33, - "version_str": "stellar-core 21.3.0.rc1 (55ec348409407ec7def75cae60ae1b520bef4adc)", + "version_str": "stellar-core 21.3.1 (4ede19620438bcd136276cdc8d4ed1f2c3b64624)", "is_pub_net": false }, "stellar_history_archive_urls": [ diff --git a/clients/vault/resources/config/testnet/stellar_relay_config_sdftest2.json b/clients/vault/resources/config/testnet/stellar_relay_config_sdftest2.json index 68a13de6e..003d98e12 100644 --- a/clients/vault/resources/config/testnet/stellar_relay_config_sdftest2.json +++ b/clients/vault/resources/config/testnet/stellar_relay_config_sdftest2.json @@ -7,7 +7,7 @@ "ledger_version": 21, "overlay_version": 35, "overlay_min_version": 33, - "version_str": "stellar-core 21.3.0.rc1 (55ec348409407ec7def75cae60ae1b520bef4adc)", + "version_str": "stellar-core 21.3.1 (4ede19620438bcd136276cdc8d4ed1f2c3b64624)", "is_pub_net": false }, "stellar_history_archive_urls": [ diff --git a/clients/vault/resources/config/testnet/stellar_relay_config_sdftest3.json b/clients/vault/resources/config/testnet/stellar_relay_config_sdftest3.json index 961b33098..9e6cbaf2d 100644 --- a/clients/vault/resources/config/testnet/stellar_relay_config_sdftest3.json +++ b/clients/vault/resources/config/testnet/stellar_relay_config_sdftest3.json @@ -7,7 +7,7 @@ "ledger_version": 21, "overlay_version": 35, "overlay_min_version": 33, - "version_str": "stellar-core 21.3.0.rc1 (55ec348409407ec7def75cae60ae1b520bef4adc)", + "version_str": "stellar-core 21.3.1 (4ede19620438bcd136276cdc8d4ed1f2c3b64624)", "is_pub_net": false }, "stellar_history_archive_urls": [ diff --git a/clients/vault/tests/vault_integration_tests.rs b/clients/vault/tests/vault_integration_tests.rs index 3fd28b48d..502534b89 100644 --- a/clients/vault/tests/vault_integration_tests.rs +++ b/clients/vault/tests/vault_integration_tests.rs @@ -1073,6 +1073,7 @@ async fn test_automatic_issue_execution_succeeds_for_other_vault() { #[tokio::test(flavor = "multi_thread")] #[serial] +#[ntest::timeout(1_200_000)] // timeout at 20 minutes async fn test_execute_open_requests_succeeds() { let is_public_network = false; test_with_vault( From bcc59034c94dd3bd9676010d1a0b3a5acfdbcb9e Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Thu, 12 Sep 2024 00:10:18 +0800 Subject: [PATCH 22/63] use ubuntu 20, instead of the latest 22 --- .github/workflows/ci-main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-main.yml b/.github/workflows/ci-main.yml index 2b69a18aa..cb65e4fb8 100644 --- a/.github/workflows/ci-main.yml +++ b/.github/workflows/ci-main.yml @@ -10,7 +10,7 @@ jobs: max-parallel: 2 matrix: rust: [ stable, nightly ] - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 env: RUST_BACKTRACE: full # Make sure CI fails on all warnings, including Clippy lints From 2d664c4f5941f0e006b7b6ebabc92bdb0ceef415 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Fri, 13 Sep 2024 13:11:39 +0800 Subject: [PATCH 23/63] remove tokio spawns on archives; add ntest --- Cargo.lock | 75 ++++++- clients/stellar-relay-lib/Cargo.toml | 1 + clients/stellar-relay-lib/src/tests/mod.rs | 14 +- .../src/oracle/collector/proof_builder.rs | 205 +++++++++++------- 4 files changed, 206 insertions(+), 89 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 141e3a101..c0196aa9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1548,7 +1548,20 @@ dependencies = [ "futures-core", "prost 0.12.6", "prost-types 0.12.6", - "tonic", + "tonic 0.10.2", + "tracing-core", +] + +[[package]] +name = "console-api" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a257c22cd7e487dd4a13d413beabc512c5052f0bc048db0da6a84c3d8a6142fd" +dependencies = [ + "futures-core", + "prost 0.12.6", + "prost-types 0.12.6", + "tonic 0.11.0", "tracing-core", ] @@ -1558,19 +1571,44 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7481d4c57092cd1c19dd541b92bdce883de840df30aa5d03fd48a3935c01842e" dependencies = [ - "console-api", + "console-api 0.6.0", + "crossbeam-channel", + "crossbeam-utils", + "futures-task", + "hdrhistogram", + "humantime 2.1.0", + "prost-types 0.12.6", + "serde", + "serde_json", + "thread_local", + "tokio", + "tokio-stream", + "tonic 0.10.2", + "tracing", + "tracing-core", + "tracing-subscriber 0.3.18", +] + +[[package]] +name = "console-subscriber" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31c4cc54bae66f7d9188996404abdf7fdfa23034ef8e43478c8810828abad758" +dependencies = [ + "console-api 0.7.0", "crossbeam-channel", "crossbeam-utils", "futures-task", "hdrhistogram", "humantime 2.1.0", + "prost 0.12.6", "prost-types 0.12.6", "serde", "serde_json", "thread_local", "tokio", "tokio-stream", - "tonic", + "tonic 0.11.0", "tracing", "tracing-core", "tracing-subscriber 0.3.18", @@ -11603,10 +11641,12 @@ version = "1.0.10" dependencies = [ "async-std", "base64 0.13.1", + "console-subscriber 0.3.0", "env_logger 0.9.3", "err-derive", "hex", "hmac 0.12.1", + "ntest", "rand 0.8.5", "serde", "serde_json", @@ -12390,6 +12430,33 @@ dependencies = [ "tracing", ] +[[package]] +name = "tonic" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76c4eb7a4e9ef9d4763600161f12f5070b92a578e1b634db88a6887844c91a13" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.21.7", + "bytes", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.28", + "hyper-timeout", + "percent-encoding 2.3.1", + "pin-project", + "prost 0.12.6", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower" version = "0.4.13" @@ -12841,7 +12908,7 @@ dependencies = [ "bincode", "cfg-if 1.0.0", "clap 3.2.25", - "console-subscriber", + "console-subscriber 0.2.0", "env_logger 0.9.3", "flate2", "frame-support", diff --git a/clients/stellar-relay-lib/Cargo.toml b/clients/stellar-relay-lib/Cargo.toml index 6c8e2b7b3..dbb312d63 100644 --- a/clients/stellar-relay-lib/Cargo.toml +++ b/clients/stellar-relay-lib/Cargo.toml @@ -11,6 +11,7 @@ path = "src/lib.rs" [dev-dependencies] env_logger = "0.9.0" +ntest = "0.9.0" serial_test = "0.9.0" wallet = { path = "../wallet", features = ["testing-utils"] } diff --git a/clients/stellar-relay-lib/src/tests/mod.rs b/clients/stellar-relay-lib/src/tests/mod.rs index dfbc7aea3..aedc32cc7 100644 --- a/clients/stellar-relay-lib/src/tests/mod.rs +++ b/clients/stellar-relay-lib/src/tests/mod.rs @@ -139,14 +139,24 @@ async fn stellar_overlay_should_receive_tx_set() { #[tokio::test(flavor = "multi_thread")] #[serial] +#[ntest::timeout(300_000)] // timeout at 5 minutes async fn stellar_overlay_disconnect_works() { let (node_info, conn_info) = overlay_infos(false); let mut overlay_connection = StellarOverlayConnection::connect(node_info.clone(), conn_info).await.unwrap(); - // let it run for a second, before disconnecting. - sleep(Duration::from_secs(1)); + loop { + if let Some(message) = overlay_connection.listen().await.expect("should return a message") { + match message { + // fail the test case if an error message is received + StellarMessage::ErrorMsg(_) => panic!("Error message received: {:?}", message), + // it means it has received a message from stellar node + _ => break, + } + } + } + overlay_connection.stop(); // let the disconnection call pass for a few seconds, before checking its status. diff --git a/clients/vault/src/oracle/collector/proof_builder.rs b/clients/vault/src/oracle/collector/proof_builder.rs index 48bfa9e75..d8aa52042 100644 --- a/clients/vault/src/oracle/collector/proof_builder.rs +++ b/clients/vault/src/oracle/collector/proof_builder.rs @@ -15,17 +15,6 @@ use crate::oracle::{ types::StellarMessageSender, ScpArchiveStorage, ScpMessageCollector, TransactionsArchiveStorage, }; -use crate::tokio_spawn; - -/// Returns true if the SCP messages for a given slot are still recoverable from the overlay -/// because the slot is not too far back. -fn check_slot_still_recoverable_from_overlay(last_slot_index: Slot, slot: Slot) -> bool { - let recoverable_point = last_slot_index.saturating_sub(MAX_SLOTS_TO_REMEMBER); - log::trace!( - "check_slot_still_recoverable_from_overlay(): Proof Building for slot {slot}: Last Slot to refer to overlay: {recoverable_point}" - ); - last_slot_index != 0 && slot > recoverable_point -} /// The Proof of Transactions that needed to be processed #[derive(Debug, Eq, PartialEq)] @@ -67,51 +56,23 @@ impl Proof { // handle missing envelopes impl ScpMessageCollector { - /// fetch envelopes not found in the collector - async fn fetch_missing_envelopes(&self, slot: Slot, sender: &StellarMessageSender) { - tracing::info!("fetch_missing_envelopes(): FOR SLOT {slot} check_slot_still_recoverable_from_overlay: LAST SLOT INDEX: {}",self.last_slot_index()); - // If the current slot is still in the range of 'remembered' slots - if check_slot_still_recoverable_from_overlay(self.last_slot_index(), slot) { - tracing::debug!( - "fetch_missing_envelopes(): Proof Building for slot {slot}: fetching missing envelopes from Stellar Node..." - ); - self.ask_node_for_envelopes(slot, sender).await; - } else { - tracing::info!( - "fetch_missing_envelopes(): Proof Building for slot {slot}: fetching from Archive Node..." + /// Returns the Proof + /// + /// # Arguments + /// + /// * `slot` - the slot where the txset is to get. + /// * `sender` - used to send messages to Stellar Node + pub async fn build_proof(&self, slot: Slot, sender: &StellarMessageSender) -> Option { + let Some(envelopes) = self.get_envelopes(slot, sender).await else { + // return early if we don't have enough envelopes + tracing::warn!( + "build_proof(): Couldn't build proof for slot {slot} due to missing envelopes" ); - self.ask_archive_for_envelopes(slot).await; - } - } - - /// fetches envelopes from the stellar node - async fn ask_node_for_envelopes(&self, slot: Slot, sender: &StellarMessageSender) { - // for this slot to be processed, we must put this in our watch list. - let slot = match u32::try_from(slot) { - Ok(slot) => slot, - Err(e) => { - tracing::error!( - "ask_node_for_envelopes(): Proof Building for slot {slot:} failed to convert slot value into u32 datatype: {e:?}" - ); - return; - }, + return None; }; - if let Err(e) = sender.send(StellarMessage::GetScpState(slot)).await { - tracing::error!( - "ask_node_for_envelopes(): Proof Building for slot {slot}: failed to send `GetScpState` message: {e:?}" - ); - return; - } - tracing::info!("ask_node_for_envelopes(): Proof Building for slot {slot}: requesting to StellarNode for messages..."); - } - - /// fetches envelopes from the archive - async fn ask_archive_for_envelopes(&self, slot: Slot) { - tokio_spawn( - "envelopes from archive", - self.get_envelopes_from_horizon_archive(slot) - ); + let tx_set = self.get_txset(slot, sender).await?; + Some(Proof { slot, envelopes, tx_set }) } /// Returns either a list of ScpEnvelopes @@ -141,11 +102,51 @@ impl ScpMessageCollector { } // forcefully retrieve envelopes - self.fetch_missing_envelopes(slot, sender).await; + self._get_envelopes(slot, sender).await; return None; } + /// fetch envelopes not found in the collector + async fn _get_envelopes(&self, slot: Slot, sender: &StellarMessageSender) { + tracing::info!("_get_envelopes(): FOR SLOT {slot} check_slot_still_recoverable_from_overlay: LAST SLOT INDEX: {}",self.last_slot_index()); + // If the current slot is still in the range of 'remembered' slots, retrieve the envelopes + // from the overlay network + if check_slot_still_recoverable_from_overlay(self.last_slot_index(), slot) { + tracing::debug!( + "_get_envelopes(): Proof Building for slot {slot}: fetching missing envelopes from Stellar Node..." + ); + self.ask_overlay_for_envelopes(slot, sender).await; + + return; + } + + tracing::info!( + "_get_envelopes(): Proof Building for slot {slot}: fetching from Archive Node..." + ); + + self.get_envelopes_from_horizon_archive(slot).await + } + + /// fetches envelopes from the stellar node + async fn ask_overlay_for_envelopes(&self, slot: Slot, sender: &StellarMessageSender) { + // for this slot to be processed, we must put this in our watch list. + let Ok(slot) = u32::try_from(slot) else { + tracing::error!( + "ask_overlay_for_envelopes(): Proof Building for slot {slot:} failed to convert slot value into u32 datatype" + ); + return; + }; + + if let Err(e) = sender.send(StellarMessage::GetScpState(slot)).await { + tracing::error!( + "ask_overlay_for_envelopes(): Proof Building for slot {slot}: failed to send `GetScpState` message: {e:?}" + ); + return; + } + tracing::info!("ask_overlay_for_envelopes(): Proof Building for slot {slot}: requesting to StellarNode for messages..."); + } + /// Returns a TransactionSet if a txset is found; None if the slot does not have a txset /// /// # Arguments @@ -166,12 +167,9 @@ impl ScpMessageCollector { tracing::info!("get_txset(): FOR SLOT {slot} check_slot_still_recoverable_from_overlay: LAST SLOT INDEX: {}",self.last_slot_index()); // If the current slot is still in the range of 'remembered' slots if check_slot_still_recoverable_from_overlay(self.last_slot_index(), slot) { - self.fetch_missing_txset_from_overlay(slot, sender).await; + self.ask_overlay_for_txset(slot, sender).await; } else { - tokio_spawn( - "txset from archive", - self.get_txset_from_horizon_archive(slot) - ); + self.get_txset_from_horizon_archive(slot).await; } tracing::warn!("get_txset(): Proof Building for slot {slot}: no txset found"); @@ -182,36 +180,16 @@ impl ScpMessageCollector { /// Send message to overlay network to fetch the missing txset _if_ we already have the txset /// hash for it. If we don't have the hash, we can't fetch it from the overlay network. - async fn fetch_missing_txset_from_overlay(&self, slot: Slot, sender: &StellarMessageSender) { + async fn ask_overlay_for_txset(&self, slot: Slot, sender: &StellarMessageSender) { // we need the txset hash to create the message. if let Some(txset_hash) = self.get_txset_hash_by_slot(&slot) { - tracing::debug!("fetch_missing_txset_from_overlay(): Proof Building for slot {slot}: Fetching TxSet from overlay..."); + tracing::debug!("ask_overlay_for_txset(): Proof Building for slot {slot}: Fetching TxSet from overlay..."); if let Err(error) = sender.send(StellarMessage::GetTxSet(txset_hash)).await { - tracing::error!("fetch_missing_txset_from_overlay(): Proof Building for slot {slot}: failed to send GetTxSet message to overlay {:?}", error); + tracing::error!("ask_overlay_for_txset(): Proof Building for slot {slot}: failed to send GetTxSet message to overlay {:?}", error); } } } - /// Returns the Proof - /// - /// # Arguments - /// - /// * `slot` - the slot where the txset is to get. - /// * `sender` - used to send messages to Stellar Node - pub async fn build_proof(&self, slot: Slot, sender: &StellarMessageSender) -> Option { - let envelopes_maybe = self.get_envelopes(slot, sender).await; - // return early if we don't have enough envelopes or the tx_set - if let Some(envelopes) = envelopes_maybe { - let tx_set = self.get_txset(slot, sender).await?; - return Some(Proof { slot, envelopes, tx_set }); - } else { - tracing::warn!( - "build_proof(): Couldn't build proof for slot {slot} due to missing envelopes" - ); - return None; - } - } - /// Insert envelopes fetched from the archive to the map /// /// # Arguments @@ -372,13 +350,44 @@ impl ScpMessageCollector { } } +/// Returns true if the SCP messages for a given slot are still recoverable from the overlay +/// because the slot is not too far back. +fn check_slot_still_recoverable_from_overlay(last_slot_index: Slot, slot: Slot) -> bool { + let recoverable_point = last_slot_index.saturating_sub(MAX_SLOTS_TO_REMEMBER); + log::trace!( + "check_slot_still_recoverable_from_overlay(): Proof Building for slot {slot}: Last Slot to refer to overlay: {recoverable_point}" + ); + last_slot_index != 0 && slot > recoverable_point +} + #[cfg(test)] mod test { use crate::oracle::{ - collector::proof_builder::check_slot_still_recoverable_from_overlay, + collector::{ + proof_builder::check_slot_still_recoverable_from_overlay, ScpMessageCollector, + }, types::constants::MAX_SLOTS_TO_REMEMBER, }; + use stellar_relay_lib::sdk::types::StellarMessage; + use tokio::sync::mpsc; + + fn collector(is_mainnet: bool) -> ScpMessageCollector { + let archives = if is_mainnet { + vec![ + "https://stellar-history-de-fra.satoshipay.io".to_string(), + "https://stellar-history-sg-sin.satoshipay.io".to_string(), + "https://stellar-history-us-iowa.satoshipay.io".to_string(), + ] + } else { + vec![ + "http://history.stellar.org/prd/core-testnet/core_testnet_001".to_string(), + "http://history.stellar.org/prd/core-testnet/core_testnet_002".to_string(), + "http://history.stellar.org/prd/core-testnet/core_testnet_003".to_string(), + ] + }; + ScpMessageCollector::new(is_mainnet, archives) + } #[test] fn test_check_slot_position() { let last_slot = 50_000; @@ -396,4 +405,34 @@ mod test { last_slot - MAX_SLOTS_TO_REMEMBER + 1, )); } + + #[tokio::test] + async fn test_ask_overlay_for_envelopes() { + let (sender, mut receiver) = mpsc::channel::(1024); + let collector = collector(false); + + let expected_slot = 50; + collector.ask_overlay_for_envelopes(expected_slot, &sender).await; + + match receiver.recv().await.expect("should receive message") { + StellarMessage::GetScpState(actual_slot) => { + let actual_slot = u64::from(actual_slot); + assert_eq!(actual_slot, expected_slot); + }, + msg => panic!("Expected GetScpState message, got {:?}", msg), + } + } + + #[tokio::test] + async fn test_get_envelopes_from_horizon_archive() { + env_logger::init(); + let collector = collector(false); + assert_eq!(collector.envelopes_map_len(), 0); + + let expected_slot = 500; + let fut = collector.get_envelopes_from_horizon_archive(expected_slot); + fut.await; + + assert!(collector.envelopes_map_len() > 0); + } } From d5a5adf76a2f606a636593c421a1638aa380ec33 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Fri, 13 Sep 2024 14:03:38 +0800 Subject: [PATCH 24/63] switch to ubuntu-latest --- .github/workflows/ci-main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-main.yml b/.github/workflows/ci-main.yml index cb65e4fb8..2b69a18aa 100644 --- a/.github/workflows/ci-main.yml +++ b/.github/workflows/ci-main.yml @@ -10,7 +10,7 @@ jobs: max-parallel: 2 matrix: rust: [ stable, nightly ] - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest env: RUST_BACKTRACE: full # Make sure CI fails on all warnings, including Clippy lints From b8b43877f6235c77c0d8f41c23be146d7d6c6e85 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Fri, 13 Sep 2024 21:16:36 +0800 Subject: [PATCH 25/63] add ntest to all test cases --- clients/vault/tests/vault_integration_tests.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/clients/vault/tests/vault_integration_tests.rs b/clients/vault/tests/vault_integration_tests.rs index 502534b89..2c349ec19 100644 --- a/clients/vault/tests/vault_integration_tests.rs +++ b/clients/vault/tests/vault_integration_tests.rs @@ -49,6 +49,7 @@ async fn test_register() { #[tokio::test(flavor = "multi_thread")] #[serial] +#[ntest::timeout(180_000)] // timeout at 3 minutes async fn test_redeem_succeeds_on_mainnet() { let is_public_network = true; test_redeem_succeeds_on_network(is_public_network).await; @@ -130,6 +131,7 @@ async fn test_redeem_succeeds_on_network(is_public_network: bool) { #[tokio::test(flavor = "multi_thread")] #[serial] +#[ntest::timeout(180_000)] // timeout at 3 minutes async fn test_replace_succeeds_on_mainnet() { let is_public_network = true; test_replace_succeeds_on_network(is_public_network).await @@ -137,6 +139,7 @@ async fn test_replace_succeeds_on_mainnet() { #[tokio::test(flavor = "multi_thread")] #[serial] +#[ntest::timeout(180_000)] // timeout at 3 minutes async fn test_replace_succeeds_on_testnet() { let is_public_network = false; test_replace_succeeds_on_network(is_public_network).await @@ -260,6 +263,7 @@ async fn test_replace_succeeds_on_network(is_public_network: bool) { #[tokio::test(flavor = "multi_thread")] #[serial] +#[ntest::timeout(180_000)] // timeout at 3 minutes async fn test_withdraw_replace_succeeds() { let is_public_network = false; test_with_vault( @@ -333,6 +337,7 @@ async fn test_withdraw_replace_succeeds() { #[tokio::test(flavor = "multi_thread")] #[serial] +#[ntest::timeout(180_000)] // timeout at 3 minutes async fn test_cancel_scheduler_succeeds() { // tests cancellation of issue, redeem and replace. // issue and replace cancellation is tested through the vault's cancellation service. @@ -516,6 +521,7 @@ async fn test_cancel_scheduler_succeeds() { #[tokio::test(flavor = "multi_thread")] #[serial] +#[ntest::timeout(180_000)] // timeout at 3 minutes async fn test_issue_cancel_succeeds() { test_with_vault( false, @@ -716,6 +722,7 @@ async fn test_issue_execution_succeeds_from_archive_on_network(is_public_network #[tokio::test(flavor = "multi_thread")] #[serial] +#[ntest::timeout(180_000)] // timeout at 3 minutes async fn test_issue_overpayment_succeeds() { let is_public_network = false; test_with_vault( @@ -807,6 +814,7 @@ async fn test_issue_overpayment_succeeds() { #[tokio::test(flavor = "multi_thread")] #[serial] +#[ntest::timeout(180_000)] // timeout at 3 minutes async fn test_automatic_issue_execution_succeeds_on_mainnet() { let is_public_network = true; test_automatic_issue_execution_succeeds_on_network(is_public_network).await; @@ -814,6 +822,7 @@ async fn test_automatic_issue_execution_succeeds_on_mainnet() { #[tokio::test(flavor = "multi_thread")] #[serial] +#[ntest::timeout(180_000)] // timeout at 3 minutes async fn test_automatic_issue_execution_succeeds_on_testnet() { let is_public_network = false; test_automatic_issue_execution_succeeds_on_network(is_public_network).await; @@ -927,6 +936,7 @@ async fn test_automatic_issue_execution_succeeds_on_network(is_public_network: b /// amounts). #[tokio::test(flavor = "multi_thread")] #[serial] +#[ntest::timeout(180_000)] // timeout at 3 minutes async fn test_automatic_issue_execution_succeeds_for_other_vault() { let is_public_network = false; test_with_vault( @@ -1196,6 +1206,7 @@ async fn test_execute_open_requests_succeeds() { #[tokio::test(flavor = "multi_thread")] #[serial] +#[ntest::timeout(180_000)] // timeout at 3 minutes async fn test_off_chain_liquidation() { let is_public_network = false; test_with_vault( @@ -1311,6 +1322,7 @@ async fn test_shutdown() { #[tokio::test(flavor = "multi_thread")] #[serial] +#[ntest::timeout(180_000)] // timeout at 3 minutes async fn test_requests_with_incompatible_amounts_fail() { test_with_vault( false, From 76fa194566d6ec607a8ef6805a190774f2cd5d32 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Fri, 13 Sep 2024 21:54:29 +0800 Subject: [PATCH 26/63] set timeout to 5 minutes --- .../vault/tests/vault_integration_tests.rs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/clients/vault/tests/vault_integration_tests.rs b/clients/vault/tests/vault_integration_tests.rs index 2c349ec19..46e979bb2 100644 --- a/clients/vault/tests/vault_integration_tests.rs +++ b/clients/vault/tests/vault_integration_tests.rs @@ -49,7 +49,7 @@ async fn test_register() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(180_000)] // timeout at 3 minutes +#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_redeem_succeeds_on_mainnet() { let is_public_network = true; test_redeem_succeeds_on_network(is_public_network).await; @@ -131,7 +131,7 @@ async fn test_redeem_succeeds_on_network(is_public_network: bool) { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(180_000)] // timeout at 3 minutes +#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_replace_succeeds_on_mainnet() { let is_public_network = true; test_replace_succeeds_on_network(is_public_network).await @@ -139,7 +139,7 @@ async fn test_replace_succeeds_on_mainnet() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(180_000)] // timeout at 3 minutes +#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_replace_succeeds_on_testnet() { let is_public_network = false; test_replace_succeeds_on_network(is_public_network).await @@ -263,7 +263,7 @@ async fn test_replace_succeeds_on_network(is_public_network: bool) { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(180_000)] // timeout at 3 minutes +#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_withdraw_replace_succeeds() { let is_public_network = false; test_with_vault( @@ -337,7 +337,7 @@ async fn test_withdraw_replace_succeeds() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(180_000)] // timeout at 3 minutes +#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_cancel_scheduler_succeeds() { // tests cancellation of issue, redeem and replace. // issue and replace cancellation is tested through the vault's cancellation service. @@ -521,7 +521,7 @@ async fn test_cancel_scheduler_succeeds() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(180_000)] // timeout at 3 minutes +#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_issue_cancel_succeeds() { test_with_vault( false, @@ -722,7 +722,7 @@ async fn test_issue_execution_succeeds_from_archive_on_network(is_public_network #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(180_000)] // timeout at 3 minutes +#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_issue_overpayment_succeeds() { let is_public_network = false; test_with_vault( @@ -814,7 +814,7 @@ async fn test_issue_overpayment_succeeds() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(180_000)] // timeout at 3 minutes +#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_automatic_issue_execution_succeeds_on_mainnet() { let is_public_network = true; test_automatic_issue_execution_succeeds_on_network(is_public_network).await; @@ -822,7 +822,7 @@ async fn test_automatic_issue_execution_succeeds_on_mainnet() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(180_000)] // timeout at 3 minutes +#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_automatic_issue_execution_succeeds_on_testnet() { let is_public_network = false; test_automatic_issue_execution_succeeds_on_network(is_public_network).await; @@ -936,7 +936,7 @@ async fn test_automatic_issue_execution_succeeds_on_network(is_public_network: b /// amounts). #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(180_000)] // timeout at 3 minutes +#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_automatic_issue_execution_succeeds_for_other_vault() { let is_public_network = false; test_with_vault( @@ -1206,7 +1206,7 @@ async fn test_execute_open_requests_succeeds() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(180_000)] // timeout at 3 minutes +#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_off_chain_liquidation() { let is_public_network = false; test_with_vault( @@ -1322,7 +1322,7 @@ async fn test_shutdown() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(180_000)] // timeout at 3 minutes +#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_requests_with_incompatible_amounts_fail() { test_with_vault( false, From cdb10a47e826e762d46af4956500b2c80d11be34 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Mon, 16 Sep 2024 14:52:25 +0800 Subject: [PATCH 27/63] free up disk space --- .github/workflows/ci-main.yml | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci-main.yml b/.github/workflows/ci-main.yml index 2b69a18aa..b06d9a157 100644 --- a/.github/workflows/ci-main.yml +++ b/.github/workflows/ci-main.yml @@ -17,20 +17,27 @@ jobs: RUSTFLAGS: "-Dwarnings" steps: - - name: Freeing up more disk space - run: | - free -h - sudo rm -rf /usr/local/lib/android # will release about 10 GB if you don't need Android - sudo rm -rf /usr/share/dotnet # will release about 20GB if you don't need .NET - sudo rm -rf /opt/ghc - sudo rm -rf /usr/local/share/boost - sudo rm -rf /opt/hostedtoolcache/CodeQL - sudo rm -rf "$AGENT_TOOLSDIRECTORY" - sudo apt-get remove -y 'php.*' --fix-missing - sudo apt-get remove -y '^mongodb-.*' --fix-missing - sudo apt-get remove -y '^mysql-.*' --fix-missing - sudo apt-get clean - df -h +# - name: Freeing up more disk space +# run: | +# free -h +# sudo rm -rf /usr/local/lib/android # will release about 10 GB if you don't need Android +# sudo rm -rf /usr/share/dotnet # will release about 20GB if you don't need .NET +# sudo rm -rf /opt/ghc +# sudo rm -rf /usr/local/share/boost +# sudo rm -rf /opt/hostedtoolcache/CodeQL +# sudo rm -rf "$AGENT_TOOLSDIRECTORY" +# sudo apt-get remove -y 'php.*' --fix-missing +# sudo apt-get remove -y '^mongodb-.*' --fix-missing +# sudo apt-get remove -y '^mysql-.*' --fix-missing +# sudo apt-get clean +# df -h + # Free GitHub Actions Environment Disk Space + - name: Maximize Build Space + uses: jlumbroso/free-disk-space@main + with: + tool-cache: false + large-packages: false + - uses: actions/checkout@v2 - name: Install package From 59aca69bdf1b171678d3f61bcd447f8dc4a382ee Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Tue, 17 Sep 2024 17:28:11 +0200 Subject: [PATCH 28/63] Use random secret for connecting to overlay in integration tests --- clients/vault/src/oracle/agent.rs | 57 +++++++++++++------------------ 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index c45cd2814..2419d00b0 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -2,9 +2,8 @@ use std::{sync::Arc, time::Duration}; use tokio::{ sync::RwLock, - time::{sleep, timeout}, + time::{sleep, timeout, Instant}, }; -use tokio::time::Instant; use runtime::ShutdownSender; use stellar_relay_lib::{ @@ -12,11 +11,14 @@ use stellar_relay_lib::{ StellarOverlayConfig, }; -use crate::oracle::{ - collector::ScpMessageCollector, errors::Error, types::StellarMessageSender, AddTxSet, Proof, +use crate::{ + oracle::{ + collector::ScpMessageCollector, errors::Error, get_random_secret_key, + types::StellarMessageSender, AddTxSet, Proof, + }, + ArcRwLock, }; use wallet::Slot; -use crate::ArcRwLock; pub struct OracleAgent { pub collector: Arc>, @@ -24,14 +26,11 @@ pub struct OracleAgent { /// sends message directly to Stellar Node message_sender: Option, /// sends an entire Vault shutdown - shutdown_sender: ShutdownSender + shutdown_sender: ShutdownSender, } impl OracleAgent { - pub fn new( - config: &StellarOverlayConfig, - shutdown_sender: ShutdownSender - ) -> Self { + pub fn new(config: &StellarOverlayConfig, shutdown_sender: ShutdownSender) -> Self { let is_public_network = config.is_public_network(); let collector = Arc::new(RwLock::new(ScpMessageCollector::new( @@ -39,12 +38,7 @@ impl OracleAgent { config.stellar_history_archive_urls(), ))); - OracleAgent { - collector, - is_public_network, - message_sender: None, - shutdown_sender, - } + OracleAgent { collector, is_public_network, message_sender: None, shutdown_sender } } pub async fn is_proof_building_ready(&self) -> bool { @@ -84,11 +78,13 @@ async fn handle_message( pub async fn listen_for_stellar_messages( config: StellarOverlayConfig, - oracle_agent:ArcRwLock, + oracle_agent: ArcRwLock, secret_key_as_string: String, shutdown_sender: ShutdownSender, -) -> Result<(),service::Error> { - tracing::info!("listen_for_stellar_messages(): Starting connection to Stellar overlay network..."); +) -> Result<(), service::Error> { + tracing::info!( + "listen_for_stellar_messages(): Starting connection to Stellar overlay network..." + ); let mut overlay_conn = connect_to_stellar_overlay_network(config.clone(), secret_key_as_string) .await.map_err(|e|{ @@ -120,7 +116,7 @@ pub async fn listen_for_stellar_messages( if let Err(e) = handle_message(msg, collector.clone(), &sender).await { tracing::error!("listen_for_stellar_messages(): failed to handle message: {msg_as_str}: {e:?}"); } - } + }, // connection got lost Err(e) => { tracing::error!("listen_for_stellar_messages(): encounter error in overlay: {e:?}"); @@ -129,7 +125,7 @@ pub async fn listen_for_stellar_messages( tracing::error!("listen_for_stellar_messages(): Failed to send shutdown signal in thread: {e:?}"); } break - } + }, } } @@ -141,26 +137,21 @@ pub async fn listen_for_stellar_messages( #[cfg(any(test, feature = "integration"))] pub async fn start_oracle_agent( cfg: StellarOverlayConfig, - vault_stellar_secret: String, - shutdown_sender: ShutdownSender + _vault_stellar_secret: String, + shutdown_sender: ShutdownSender, ) -> ArcRwLock { let oracle_agent = Arc::new(RwLock::new(OracleAgent::new(&cfg, shutdown_sender.clone()))); - tokio::spawn( - listen_for_stellar_messages( - cfg, - oracle_agent.clone(), - vault_stellar_secret, - shutdown_sender - ) - ); + let secret = get_random_secret_key(); + + tokio::spawn(listen_for_stellar_messages(cfg, oracle_agent.clone(), secret, shutdown_sender)); - while !oracle_agent.read().await.is_proof_building_ready().await{ + while !oracle_agent.read().await.is_proof_building_ready().await { + tracing::info!("start_oracle_agent(): waiting for the first slot to be received"); sleep(Duration::from_millis(500)).await; } oracle_agent - } impl OracleAgent { From ae50727b3369e630af955d8c7b9a15e9afdd9b10 Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Tue, 17 Sep 2024 17:30:28 +0200 Subject: [PATCH 29/63] Run `cargo +nightly-2024-02-09 fmt --all` --- clients/service/src/lib.rs | 2 +- clients/stellar-relay-lib/examples/connect.rs | 23 ++-- clients/stellar-relay-lib/src/config.rs | 5 +- .../connection/connector/message_reader.rs | 27 ++-- clients/stellar-relay-lib/src/node/mod.rs | 4 +- clients/stellar-relay-lib/src/overlay.rs | 13 +- clients/stellar-relay-lib/src/tests/mod.rs | 17 ++- clients/vault/src/issue.rs | 4 +- clients/vault/src/lib.rs | 10 +- clients/vault/src/main.rs | 21 +-- clients/vault/src/oracle/errors.rs | 2 +- clients/vault/src/redeem.rs | 2 +- clients/vault/src/replace.rs | 5 +- clients/vault/src/requests/execution.rs | 22 ++-- clients/vault/src/requests/helper.rs | 2 +- clients/vault/src/requests/structs.rs | 7 +- clients/vault/src/system.rs | 122 ++++++++++-------- clients/vault/tests/helper/helper.rs | 7 +- clients/vault/tests/helper/mod.rs | 13 +- .../vault/tests/vault_integration_tests.rs | 20 ++- 20 files changed, 191 insertions(+), 137 deletions(-) diff --git a/clients/service/src/lib.rs b/clients/service/src/lib.rs index f4994a537..0e1aa49e4 100644 --- a/clients/service/src/lib.rs +++ b/clients/service/src/lib.rs @@ -172,7 +172,7 @@ pub async fn wait_or_shutdown( shutdown_tx: ShutdownSender, future2: F, // a consumer that receives a precheck signal to start a task. - precheck_signal: Option> + precheck_signal: Option>, ) -> Result<(), E> where F: Future>, diff --git a/clients/stellar-relay-lib/examples/connect.rs b/clients/stellar-relay-lib/examples/connect.rs index 82c0dca1b..a8e6b8330 100644 --- a/clients/stellar-relay-lib/examples/connect.rs +++ b/clients/stellar-relay-lib/examples/connect.rs @@ -1,4 +1,8 @@ -use stellar_relay_lib::{connect_to_stellar_overlay_network, Error, sdk::types::{ScpStatementPledges, StellarMessage}, StellarOverlayConfig}; +use stellar_relay_lib::{ + connect_to_stellar_overlay_network, + sdk::types::{ScpStatementPledges, StellarMessage}, + Error, StellarOverlayConfig, +}; use wallet::keys::get_source_secret_key_from_env; @@ -36,26 +40,25 @@ async fn main() -> Result<(), Box> { ScpStatementPledges::ScpStNominate(_) => "ScpStNominate ", }; tracing::info!( - "{} sent StellarMessage of type {} for ledger {}", - node_id, - stmt_type, - slot - ); + "{} sent StellarMessage of type {} for ledger {}", + node_id, + stmt_type, + slot + ); }, _ => { let _ = overlay_connection.send_to_node(StellarMessage::GetPeers).await; }, }, - Ok(None) => {} + Ok(None) => {}, Err(Error::Timeout) => { tracing::warn!("took more than a second to respond"); - } + }, Err(e) => { tracing::error!("Error: {:?}", e); break - } + }, } - } tracing::info!("ooops, connection stopped "); diff --git a/clients/stellar-relay-lib/src/config.rs b/clients/stellar-relay-lib/src/config.rs index 7d8210f96..40753c0c7 100644 --- a/clients/stellar-relay-lib/src/config.rs +++ b/clients/stellar-relay-lib/src/config.rs @@ -39,7 +39,10 @@ impl StellarOverlayConfig { } #[allow(dead_code)] - pub(crate) fn connection_info(&self, secret_key_as_string: String) -> Result { + pub(crate) fn connection_info( + &self, + secret_key_as_string: String, + ) -> Result { let cfg = &self.connection_info; let secret_key = SecretKey::from_encoding(secret_key_as_string)?; diff --git a/clients/stellar-relay-lib/src/connection/connector/message_reader.rs b/clients/stellar-relay-lib/src/connection/connector/message_reader.rs index a22b22bf4..a3532e057 100644 --- a/clients/stellar-relay-lib/src/connection/connector/message_reader.rs +++ b/clients/stellar-relay-lib/src/connection/connector/message_reader.rs @@ -46,8 +46,10 @@ pub(crate) async fn poll_messages_from_stellar( // if reading took too much time, flag it as "disconnected" let xdr = match timeout( Duration::from_secs(READ_TIMEOUT_IN_SECS), - read_message_from_stellar(&mut connector) - ).await { + read_message_from_stellar(&mut connector), + ) + .await + { Ok(Ok(xdr)) => xdr, Ok(Err(e)) => { error!("poll_messages_from_stellar(): {e:?}"); @@ -56,7 +58,7 @@ pub(crate) async fn poll_messages_from_stellar( Err(_) => { error!("poll_messages_from_stellar(): timed out"); break - } + }, }; match connector.process_raw_message(xdr).await { @@ -99,10 +101,9 @@ async fn read_message_from_stellar(connector: &mut Connector) -> Result continue, - Ok(_) if lack_bytes_from_prev == 0 => { + Ok(_) if lack_bytes_from_prev == 0 => { // if there are no more bytes lacking from the previous message, // then check the size of next stellar message. let expect_msg_len = get_xdr_message_length(&buff_for_reading); @@ -132,7 +133,7 @@ async fn read_message_from_stellar(connector: &mut Connector) -> Result { // The next few bytes was read. Add it to the readbuf. lack_bytes_from_prev = lack_bytes_from_prev.saturating_sub(size); @@ -141,8 +142,12 @@ async fn read_message_from_stellar(connector: &mut Connector) -> Result continue, Ok(true) => return Ok(readbuf), @@ -151,11 +156,11 @@ async fn read_message_from_stellar(connector: &mut Connector) -> Result { trace!("read_message_from_stellar(): ERROR reading messages: {e:?}"); return Err(Error::ReadFailed(e.to_string())) - } + }, } } } diff --git a/clients/stellar-relay-lib/src/node/mod.rs b/clients/stellar-relay-lib/src/node/mod.rs index b50337b88..c44667c3d 100644 --- a/clients/stellar-relay-lib/src/node/mod.rs +++ b/clients/stellar-relay-lib/src/node/mod.rs @@ -20,7 +20,7 @@ pub struct NodeInfo { } impl NodeInfo { - pub(crate) fn new(cfg:&NodeInfoCfg) -> Self { + pub(crate) fn new(cfg: &NodeInfoCfg) -> Self { let network: &Network = if cfg.is_pub_net { &PUBLIC_NETWORK } else { &TEST_NETWORK }; NodeInfo { ledger_version: cfg.ledger_version, @@ -55,4 +55,4 @@ impl From for NodeInfo { network_id: *network.get_id(), } } -} \ No newline at end of file +} diff --git a/clients/stellar-relay-lib/src/overlay.rs b/clients/stellar-relay-lib/src/overlay.rs index ea5416fcc..e32eb7a9e 100644 --- a/clients/stellar-relay-lib/src/overlay.rs +++ b/clients/stellar-relay-lib/src/overlay.rs @@ -1,10 +1,7 @@ -use substrate_stellar_sdk::types::{StellarMessage}; +use substrate_stellar_sdk::types::StellarMessage; use tokio::sync::{ mpsc, - mpsc::{ - error::{SendError}, - Sender, - }, + mpsc::{error::SendError, Sender}, }; use tracing::{debug, info}; @@ -50,7 +47,8 @@ impl StellarOverlayConnection { connector, send_to_user_sender, send_to_node_receiver, - )).unwrap(); + )) + .unwrap(); #[cfg(not(tokio_unstable))] tokio::spawn(poll_messages_from_stellar( @@ -66,7 +64,8 @@ impl StellarOverlayConnection { } /// Listens for upcoming messages from Stellar Node via a receiver. - /// The sender pair can be found in [fn poll_messages_from_stellar](../src/connection/connector/message_reader.rs) + /// The sender pair can be found in [fn + /// poll_messages_from_stellar](../src/connection/connector/message_reader.rs) pub async fn listen(&mut self) -> Result, Error> { if !self.is_alive() { debug!("listen(): sender half of overlay has closed."); diff --git a/clients/stellar-relay-lib/src/tests/mod.rs b/clients/stellar-relay-lib/src/tests/mod.rs index aedc32cc7..4166068a7 100644 --- a/clients/stellar-relay-lib/src/tests/mod.rs +++ b/clients/stellar-relay-lib/src/tests/mod.rs @@ -31,10 +31,7 @@ fn overlay_infos(is_mainnet: bool) -> (NodeInfo, ConnectionInfo) { let cfg = StellarOverlayConfig::try_from_path(&path).expect("should be able to extract config"); - ( - cfg.node_info(), - cfg.connection_info(secret_key(is_mainnet)).expect("should return conn info"), - ) + (cfg.node_info(), cfg.connection_info(secret_key(is_mainnet)).expect("should return conn info")) } #[tokio::test(flavor = "multi_thread")] @@ -43,7 +40,9 @@ async fn stellar_overlay_should_receive_scp_messages() { let (node_info, conn_info) = overlay_infos(false); let overlay_connection = Arc::new(Mutex::new( - StellarOverlayConnection::connect(node_info, conn_info).await.expect("should connect"), + StellarOverlayConnection::connect(node_info, conn_info) + .await + .expect("should connect"), )); // to check if we receive any scp message from stellar node @@ -52,7 +51,7 @@ async fn stellar_overlay_should_receive_scp_messages() { let scps_vec = Arc::new(Mutex::new(vec![])); let scps_vec_clone = scps_vec.clone(); - tokio::spawn( async move { + tokio::spawn(async move { let mut ov_conn_locked = ov_conn.lock().await; while let Ok(Some(msg)) = ov_conn_locked.listen().await { scps_vec_clone.lock().await.push(msg); @@ -70,9 +69,9 @@ async fn stellar_overlay_should_receive_scp_messages() { //assert //ensure that we receive some scp message from stellar node assert!(!scps_vec.lock().await.is_empty()); - - }).await.expect("time has elapsed"); - + }) + .await + .expect("time has elapsed"); } #[tokio::test(flavor = "multi_thread")] diff --git a/clients/vault/src/issue.rs b/clients/vault/src/issue.rs index cc98ddff5..f8b8f3f1c 100644 --- a/clients/vault/src/issue.rs +++ b/clients/vault/src/issue.rs @@ -14,7 +14,7 @@ use wallet::{ types::FilterWith, LedgerTxEnvMap, Slot, SlotTask, SlotTaskStatus, TransactionResponse, }; -use crate::{oracle::OracleAgent, ArcRwLock, Error, Event, tokio_spawn}; +use crate::{oracle::OracleAgent, tokio_spawn, ArcRwLock, Error, Event}; fn is_vault(p1: &PublicKey, p2_raw: [u8; 32]) -> bool { return *p1.as_binary() == p2_raw; @@ -282,7 +282,7 @@ pub async fn process_issues_requests( oracle_agent.clone(), *slot, sender, - ) + ), ); } diff --git a/clients/vault/src/lib.rs b/clients/vault/src/lib.rs index 0f12e819c..edb0df61b 100644 --- a/clients/vault/src/lib.rs +++ b/clients/vault/src/lib.rs @@ -61,15 +61,15 @@ cfg_if::cfg_if! { } pub fn tokio_spawn(_task_name: &str, future: F) -> tokio::task::JoinHandle - where - F: std::future::Future + Send + 'static, - F::Output: Send + 'static, +where + F: std::future::Future + Send + 'static, + F::Output: Send + 'static, { - cfg_if::cfg_if!{ + cfg_if::cfg_if! { if #[cfg(all(tokio_unstable, feature = "allow-debugger"))] { tokio::task::Builder::new().name(_task_name).spawn(future).unwrap() } else { tokio::spawn(future) } } -} \ No newline at end of file +} diff --git a/clients/vault/src/main.rs b/clients/vault/src/main.rs index 5638af631..a9099fdff 100644 --- a/clients/vault/src/main.rs +++ b/clients/vault/src/main.rs @@ -17,7 +17,11 @@ use service::{ }; use signal_hook::consts::*; use signal_hook_tokio::Signals; -use vault::{metrics::{self, increment_restart_counter}, process::PidFile, Error, VaultService, VaultServiceConfig, ABOUT, AUTHORS, NAME, VERSION, tokio_spawn}; +use vault::{ + metrics::{self, increment_restart_counter}, + process::PidFile, + tokio_spawn, Error, VaultService, VaultServiceConfig, ABOUT, AUTHORS, NAME, VERSION, +}; #[derive(Parser)] #[clap(args_conflicts_with_subcommands = true)] @@ -145,9 +149,10 @@ async fn start() -> Result<(), ServiceError> { #[tokio::main] async fn main() { #[cfg(feature = "allow-debugger")] - console_subscriber::ConsoleLayer::builder().with_default_env() + console_subscriber::ConsoleLayer::builder() + .with_default_env() .publish_interval(std::time::Duration::from_secs(2)) - .event_buffer_capacity(1024*500) + .event_buffer_capacity(1024 * 500) .init(); let exit_code = if let Err(err) = start().await { @@ -171,13 +176,13 @@ mod tests { async fn test_vault_termination_signal() { let termination_signals = &[SIGHUP, SIGTERM, SIGINT, SIGQUIT]; for sig in termination_signals { - let task = - tokio_spawn( - "catch signals", - catch_signals(Signals::new(termination_signals).unwrap(), async { + let task = tokio_spawn( + "catch signals", + catch_signals(Signals::new(termination_signals).unwrap(), async { tokio::time::sleep(Duration::from_millis(100_000)).await; Ok(()) - })); + }), + ); // Wait for the signals iterator to be polled // This `sleep` is based on the test case in `signal-hook-tokio` itself: // https://github.com/vorner/signal-hook/blob/a9e5ca5e46c9c8e6de89ff1b3ce63c5ff89cd708/signal-hook-tokio/tests/tests.rs#L50 diff --git a/clients/vault/src/oracle/errors.rs b/clients/vault/src/oracle/errors.rs index a167f719a..3ec1ea32b 100644 --- a/clients/vault/src/oracle/errors.rs +++ b/clients/vault/src/oracle/errors.rs @@ -56,4 +56,4 @@ impl From for Error { fn from(e: oneshot::error::RecvError) -> Self { Error::ConnError(stellar_relay_lib::Error::SendFailed(e.to_string())) } -} \ No newline at end of file +} diff --git a/clients/vault/src/redeem.rs b/clients/vault/src/redeem.rs index d89fe9363..0be4c8c8c 100644 --- a/clients/vault/src/redeem.rs +++ b/clients/vault/src/redeem.rs @@ -3,7 +3,7 @@ use std::time::Duration; use runtime::{RedeemPallet, RequestRedeemEvent, ShutdownSender, SpacewalkParachain}; use service::{spawn_cancelable, Error as ServiceError}; -use crate::{oracle::OracleAgent, requests::*, system::VaultIdManager, Error, ArcRwLock}; +use crate::{oracle::OracleAgent, requests::*, system::VaultIdManager, ArcRwLock, Error}; /// Listen for RequestRedeemEvent directed at this vault; upon reception, transfer /// the respective Stellar asset and call execute_redeem. diff --git a/clients/vault/src/replace.rs b/clients/vault/src/replace.rs index e5845b920..4dced56cc 100644 --- a/clients/vault/src/replace.rs +++ b/clients/vault/src/replace.rs @@ -3,7 +3,10 @@ use std::{sync::Arc, time::Duration}; use futures::{channel::mpsc::Sender, future::try_join3, SinkExt}; use tokio::sync::RwLock; -use crate::{ArcRwLock, cancellation::Event, error::Error, oracle::OracleAgent, requests::Request, system::VaultIdManager}; +use crate::{ + cancellation::Event, error::Error, oracle::OracleAgent, requests::Request, + system::VaultIdManager, ArcRwLock, +}; use runtime::{ AcceptReplaceEvent, CollateralBalancesPallet, ExecuteReplaceEvent, PrettyPrint, ReplacePallet, RequestReplaceEvent, ShutdownSender, SpacewalkParachain, UtilFuncs, VaultId, diff --git a/clients/vault/src/requests/execution.rs b/clients/vault/src/requests/execution.rs index 79603d0cf..484b3a750 100644 --- a/clients/vault/src/requests/execution.rs +++ b/clients/vault/src/requests/execution.rs @@ -1,11 +1,16 @@ -use crate::{ArcRwLock, error::Error, oracle::OracleAgent, requests::{ - helper::{ - get_all_transactions_of_wallet_async, get_request_for_stellar_tx, - retrieve_open_redeem_replace_requests_async, PayAndExecuteExt, +use crate::{ + error::Error, + oracle::OracleAgent, + requests::{ + helper::{ + get_all_transactions_of_wallet_async, get_request_for_stellar_tx, + retrieve_open_redeem_replace_requests_async, PayAndExecuteExt, + }, + structs::Request, + PayAndExecute, }, - structs::Request, - PayAndExecute, -}, VaultIdManager, YIELD_RATE}; + ArcRwLock, VaultIdManager, YIELD_RATE, +}; use async_trait::async_trait; use governor::{ clock::{Clock, ReasonablyRealtime}, @@ -285,7 +290,7 @@ pub async fn execute_open_requests( wallet: Arc>, oracle_agent: ArcRwLock, payment_margin: Duration, - precheck_signal: tokio::sync::broadcast::Sender<()> + precheck_signal: tokio::sync::broadcast::Sender<()>, ) -> Result<(), ServiceError> { tracing::info!("execute_open_requests(): started"); let parachain_rpc_ref = ¶chain_rpc; @@ -329,7 +334,6 @@ pub async fn execute_open_requests( rate_limiter, ); - if let Err(e) = precheck_signal.send(()) { tracing::error!("execute_open_requests(): Failed to send signal: {e:?}"); } diff --git a/clients/vault/src/requests/helper.rs b/clients/vault/src/requests/helper.rs index eb24dd97b..44b4ab0b8 100644 --- a/clients/vault/src/requests/helper.rs +++ b/clients/vault/src/requests/helper.rs @@ -3,7 +3,7 @@ use futures::try_join; use std::{collections::HashMap, sync::Arc, time::Duration}; use tokio::sync::RwLock; -use crate::{requests::structs::Request, Error, VaultIdManager, ArcRwLock}; +use crate::{requests::structs::Request, ArcRwLock, Error, VaultIdManager}; use crate::oracle::OracleAgent; use primitives::{derive_shortened_request_id, TextMemo, TransactionEnvelopeExt}; diff --git a/clients/vault/src/requests/structs.rs b/clients/vault/src/requests/structs.rs index 84b651aaa..7c4791f61 100644 --- a/clients/vault/src/requests/structs.rs +++ b/clients/vault/src/requests/structs.rs @@ -1,4 +1,9 @@ -use crate::{metrics::update_stellar_metrics, oracle::{OracleAgent, Proof}, system::VaultData, Error, ArcRwLock}; +use crate::{ + metrics::update_stellar_metrics, + oracle::{OracleAgent, Proof}, + system::VaultData, + ArcRwLock, Error, +}; use primitives::{stellar::PublicKey, CurrencyId}; use runtime::{ Error as EnrichedError, OraclePallet, Recoverability, RedeemPallet, ReplacePallet, RetryPolicy, diff --git a/clients/vault/src/system.rs b/clients/vault/src/system.rs index 970a95c43..7fa80428f 100644 --- a/clients/vault/src/system.rs +++ b/clients/vault/src/system.rs @@ -14,8 +14,13 @@ use futures::{ future::{join, join_all}, SinkExt, TryFutureExt, }; -use tokio::sync::broadcast::{self, Receiver as bcReceiver, Sender as bcSender }; -use tokio::{sync::RwLock, time::sleep}; +use tokio::{ + sync::{ + broadcast::{self, Receiver as bcReceiver, Sender as bcSender}, + RwLock, + }, + time::sleep, +}; use runtime::{ cli::parse_duration_minutes, AccountId, BlockNumber, CollateralBalancesPallet, CurrencyId, @@ -27,8 +32,19 @@ use service::{wait_or_shutdown, Error as ServiceError, MonitoringConfig, Service use stellar_relay_lib::{sdk::PublicKey, StellarOverlayConfig}; use wallet::{LedgerTxEnvMap, StellarWallet, RESUBMISSION_INTERVAL_IN_SECS}; -use crate::{cancellation::ReplaceCanceller, error::Error, issue, issue::IssueFilter, metrics::{monitor_bridge_metrics, poll_metrics, publish_tokio_metrics, PerCurrencyMetrics}, oracle::OracleAgent, redeem::listen_for_redeem_requests, replace::{listen_for_accept_replace, listen_for_execute_replace, listen_for_replace_requests}, requests::execution::execute_open_requests, service::{CancellationScheduler, IssueCanceller}, ArcRwLock, Event, CHAIN_HEIGHT_POLLING_INTERVAL, tokio_spawn}; -use crate::oracle::listen_for_stellar_messages; +use crate::{ + cancellation::ReplaceCanceller, + error::Error, + issue, + issue::IssueFilter, + metrics::{monitor_bridge_metrics, poll_metrics, publish_tokio_metrics, PerCurrencyMetrics}, + oracle::{listen_for_stellar_messages, OracleAgent}, + redeem::listen_for_redeem_requests, + replace::{listen_for_accept_replace, listen_for_execute_replace, listen_for_replace_requests}, + requests::execution::execute_open_requests, + service::{CancellationScheduler, IssueCanceller}, + tokio_spawn, ArcRwLock, Event, CHAIN_HEIGHT_POLLING_INTERVAL, +}; pub const VERSION: &str = env!("CARGO_PKG_VERSION"); pub const AUTHORS: &str = env!("CARGO_PKG_AUTHORS"); @@ -302,7 +318,7 @@ async fn run_and_monitor_tasks( shutdown_tx: ShutdownSender, items: Vec<(&str, ServiceTask)>, // Sends a signal to start those tasks requiring a precheck. - mut precheck_signals: Vec> + mut precheck_signals: Vec>, ) -> Result<(), ServiceError> { let (metrics_iterators, tasks): (HashMap, Vec<_>) = items .into_iter() @@ -311,9 +327,9 @@ async fn run_and_monitor_tasks( let metrics_iterator = monitor.intervals(); let task = match task { ServiceTask::Optional(true, t) | ServiceTask::Essential(t) => - Some(wait_or_shutdown(shutdown_tx.clone(), t,None)), + Some(wait_or_shutdown(shutdown_tx.clone(), t, None)), ServiceTask::PrecheckRequired(t) => - Some(wait_or_shutdown(shutdown_tx.clone(),t,precheck_signals.pop())), + Some(wait_or_shutdown(shutdown_tx.clone(), t, precheck_signals.pop())), _ => None, }?; let task = monitor.instrument(task); @@ -325,26 +341,21 @@ async fn run_and_monitor_tasks( let tokio_metrics = tokio_spawn( "tokio metrics publisher", - wait_or_shutdown( - shutdown_tx.clone(), - publish_tokio_metrics(metrics_iterators), - None - ) + wait_or_shutdown(shutdown_tx.clone(), publish_tokio_metrics(metrics_iterators), None), ); tracing::info!("run_and_monitor_tasks(): running all tasks..."); - match join(tokio_metrics, join_all(tasks)).await { (Ok(Err(err)), _) => Err(err), (_, results) => { for result in results { match result { - Ok(_) => {} + Ok(_) => {}, Err(e) => { tracing::error!("run_and_monitor_tasks(): One of the tasks failed: {e:?}"); return Err(ServiceError::TokioError(e)); - } + }, } } Ok(()) @@ -358,11 +369,11 @@ enum ServiceTask { Optional(bool, Task), Essential(Task), // Runs a task after a prequisite check has passed. - PrecheckRequired(Task) + PrecheckRequired(Task), } /// returns a single-producer multi-consumer channel to send a signal to start a task -fn precheck_signals(num_of_signals_required:u8) -> (bcSender<()>, Vec>){ +fn precheck_signals(num_of_signals_required: u8) -> (bcSender<()>, Vec>) { let (sender, receiver) = broadcast::channel(1); let mut subscribers = vec![receiver]; while subscribers.len() < usize::from(num_of_signals_required) { @@ -389,9 +400,9 @@ where } fn run_with_precheck(task: F) -> ServiceTask - where - F: Future> + Send + 'static, - E: Into>, +where + F: Future> + Send + 'static, + E: Into>, { ServiceTask::PrecheckRequired(Box::pin(task.map_err(|x| x.into()))) } @@ -432,12 +443,18 @@ impl VaultService { // Subscribe to an event (any event will do) so that a period of inactivity does not close // the jsonrpsee connection let err_provider = self.spacewalk_parachain.clone(); - let err_listener = wait_or_shutdown(self.shutdown.clone(), async move { - err_provider - .on_event_error(|e| tracing::debug!("Client Service: Received error event: {}", e)) - .await?; - Ok::<_, Error>(()) - },None); + let err_listener = wait_or_shutdown( + self.shutdown.clone(), + async move { + err_provider + .on_event_error(|e| { + tracing::debug!("Client Service: Received error event: {}", e) + }) + .await?; + Ok::<_, Error>(()) + }, + None, + ); tokio_spawn("error listener", err_listener); Ok(()) @@ -455,7 +472,7 @@ impl VaultService { return Err(ServiceError::IncompatibleNetwork); } - Ok(Arc::new(RwLock::new(OracleAgent::new(&stellar_overlay_cfg,shutdown_sender)))) + Ok(Arc::new(RwLock::new(OracleAgent::new(&stellar_overlay_cfg, shutdown_sender)))) } fn create_issue_tasks( @@ -512,12 +529,14 @@ impl VaultService { ), ( "Issue Cancel Scheduler", - run_with_precheck(CancellationScheduler::new( - self.spacewalk_parachain.clone(), - startup_height, - account_id, - ) - .handle_cancellation::(issue_event_rx)), + run_with_precheck( + CancellationScheduler::new( + self.spacewalk_parachain.clone(), + startup_height, + account_id, + ) + .handle_cancellation::(issue_event_rx), + ), ), ] } @@ -556,12 +575,14 @@ impl VaultService { ), ( "Replace Cancellation Scheduler", - run_with_precheck(CancellationScheduler::new( - self.spacewalk_parachain.clone(), - startup_height, - account_id, - ) - .handle_cancellation::(replace_event_rx)), + run_with_precheck( + CancellationScheduler::new( + self.spacewalk_parachain.clone(), + startup_height, + account_id, + ) + .handle_cancellation::(replace_event_rx), + ), ), ] } @@ -740,7 +761,7 @@ impl VaultService { }) } - fn secret_key (&self) -> String { + fn secret_key(&self) -> String { self.secret_key.clone() } @@ -816,24 +837,22 @@ impl VaultService { self.stellar_wallet.clone(), oracle_agent.clone(), self.config.payment_margin_minutes, - precheck_sender - ) + precheck_sender, + ), ); let ledger_env_map: ArcRwLock = Arc::new(RwLock::new(HashMap::new())); tracing::info!("Starting all services..."); - let mut tasks = vec![( + let mut tasks = vec![( "Stellar Messages Listener", - run( - listen_for_stellar_messages( - self.stellar_overlay_cfg()?, - oracle_agent.clone(), - self.secret_key(), - self.shutdown.clone() - ) - ) + run(listen_for_stellar_messages( + self.stellar_overlay_cfg()?, + oracle_agent.clone(), + self.secret_key(), + self.shutdown.clone(), + )), )]; let mut _tasks = self.create_tasks( @@ -980,5 +999,4 @@ impl VaultService { wallet.try_stop_periodic_resubmission_of_transactions().await; drop(wallet); } - } diff --git a/clients/vault/tests/helper/helper.rs b/clients/vault/tests/helper/helper.rs index 178a0c97b..91d900173 100644 --- a/clients/vault/tests/helper/helper.rs +++ b/clients/vault/tests/helper/helper.rs @@ -203,7 +203,12 @@ pub async fn assert_issue( let slot = response.ledger as u64; // Loop pending proofs until it is ready - let proof = oracle_agent.read().await.get_proof(slot).await.expect("Proof should be available"); + let proof = oracle_agent + .read() + .await + .get_proof(slot) + .await + .expect("Proof should be available"); let tx_envelope_xdr_encoded = response.envelope_xdr; let (envelopes_xdr_encoded, tx_set_xdr_encoded) = proof.encode(); diff --git a/clients/vault/tests/helper/mod.rs b/clients/vault/tests/helper/mod.rs index 9f19d47d9..60d430b85 100644 --- a/clients/vault/tests/helper/mod.rs +++ b/clients/vault/tests/helper/mod.rs @@ -19,13 +19,11 @@ use sp_keyring::AccountKeyring; use std::{future::Future, sync::Arc}; use stellar_relay_lib::StellarOverlayConfig; use subxt::utils::AccountId32 as AccountId; -use tokio::sync::RwLock; -use tokio::time::sleep; +use tokio::{sync::RwLock, time::sleep}; use vault::{ - oracle::{random_stellar_relay_config, OracleAgent}, + oracle::{random_stellar_relay_config, start_oracle_agent, OracleAgent}, ArcRwLock, }; -use vault::oracle::{start_oracle_agent}; use wallet::{ keys::{get_dest_secret_key_from_env, get_source_secret_key_from_env}, StellarWallet, @@ -145,14 +143,13 @@ where let vault_stellar_secret = get_source_secret_key_from_env(is_public_network); let shutdown_tx = ShutdownSender::new(); - let oracle_agent = start_oracle_agent( - stellar_config,vault_stellar_secret,shutdown_tx - ).await; + let oracle_agent = start_oracle_agent(stellar_config, vault_stellar_secret, shutdown_tx).await; // continue ONLY if the oracle agent has received the first slot while !oracle_agent.read().await.is_proof_building_ready().await { + tracing::info!("Waiting for the oracle agent to be ready... in helper mod"); sleep(std::time::Duration::from_millis(500)).await; } execute(client, vault_wallet, user_wallet, oracle_agent, vault_id, vault_provider).await -} \ No newline at end of file +} diff --git a/clients/vault/tests/vault_integration_tests.rs b/clients/vault/tests/vault_integration_tests.rs index 46e979bb2..5729931ed 100644 --- a/clients/vault/tests/vault_integration_tests.rs +++ b/clients/vault/tests/vault_integration_tests.rs @@ -687,12 +687,16 @@ async fn test_issue_execution_succeeds_from_archive_on_network(is_public_network let vault_stellar_secret = get_source_secret_key_from_env(is_public_network); // Create new oracle agent with the same configuration as the previous one let oracle_agent = - start_oracle_agent(stellar_config.clone(), vault_stellar_secret, shutdown_tx) - .await; + start_oracle_agent(stellar_config.clone(), vault_stellar_secret, shutdown_tx).await; let oracle_agent = Arc::new(oracle_agent); // Loop pending proofs until it is ready - let proof = oracle_agent.read().await.get_proof(slot).await.expect("Proof should be available"); + let proof = oracle_agent + .read() + .await + .get_proof(slot) + .await + .expect("Proof should be available"); let tx_envelope_xdr_encoded = transaction_response.envelope_xdr; let (envelopes_xdr_encoded, tx_set_xdr_encoded) = proof.encode(); @@ -780,7 +784,12 @@ async fn test_issue_overpayment_succeeds() { let slot = transaction_response.ledger as u64; // Loop pending proofs until it is ready - let proof = oracle_agent.read().await.get_proof(slot).await.expect("Proof should be available"); + let proof = oracle_agent + .read() + .await + .get_proof(slot) + .await + .expect("Proof should be available"); let tx_envelope_xdr_encoded = transaction_response.envelope_xdr; let (envelopes_xdr_encoded, tx_set_xdr_encoded) = proof.encode(); @@ -1176,7 +1185,6 @@ async fn test_execute_open_requests_succeeds() { let (precheck_signal, mut rceiver) = tokio::sync::broadcast::channel(1); let shutdown_tx = ShutdownSender::new(); - join5( vault::service::execute_open_requests( shutdown_tx.clone(), @@ -1185,7 +1193,7 @@ async fn test_execute_open_requests_succeeds() { vault_wallet.clone(), oracle_agent.clone(), Duration::from_secs(0), - precheck_signal + precheck_signal, ) .map(Result::unwrap), async move { From 47778551aa06b009f81a80c0378deaf3bd82dc28 Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Tue, 17 Sep 2024 17:31:49 +0200 Subject: [PATCH 30/63] Remove ntest timeouts --- clients/vault/tests/vault_integration_tests.rs | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/clients/vault/tests/vault_integration_tests.rs b/clients/vault/tests/vault_integration_tests.rs index 5729931ed..bcc9ee049 100644 --- a/clients/vault/tests/vault_integration_tests.rs +++ b/clients/vault/tests/vault_integration_tests.rs @@ -49,7 +49,6 @@ async fn test_register() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_redeem_succeeds_on_mainnet() { let is_public_network = true; test_redeem_succeeds_on_network(is_public_network).await; @@ -131,7 +130,6 @@ async fn test_redeem_succeeds_on_network(is_public_network: bool) { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_replace_succeeds_on_mainnet() { let is_public_network = true; test_replace_succeeds_on_network(is_public_network).await @@ -139,7 +137,6 @@ async fn test_replace_succeeds_on_mainnet() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_replace_succeeds_on_testnet() { let is_public_network = false; test_replace_succeeds_on_network(is_public_network).await @@ -263,7 +260,6 @@ async fn test_replace_succeeds_on_network(is_public_network: bool) { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_withdraw_replace_succeeds() { let is_public_network = false; test_with_vault( @@ -337,7 +333,6 @@ async fn test_withdraw_replace_succeeds() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_cancel_scheduler_succeeds() { // tests cancellation of issue, redeem and replace. // issue and replace cancellation is tested through the vault's cancellation service. @@ -521,7 +516,6 @@ async fn test_cancel_scheduler_succeeds() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_issue_cancel_succeeds() { test_with_vault( false, @@ -611,7 +605,6 @@ async fn test_issue_cancel_succeeds() { } #[tokio::test(flavor = "multi_thread")] -#[ntest::timeout(1_200_000)] // timeout at 20 minutes #[serial] async fn test_issue_execution_succeeds_from_archive_on_mainnet() { let is_public_network = true; @@ -619,7 +612,6 @@ async fn test_issue_execution_succeeds_from_archive_on_mainnet() { } #[tokio::test(flavor = "multi_thread")] -#[ntest::timeout(1_200_000)] // timeout at 20 minutes #[serial] async fn test_issue_execution_succeeds_from_archive_on_testnet() { let is_public_network = false; @@ -726,7 +718,6 @@ async fn test_issue_execution_succeeds_from_archive_on_network(is_public_network #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_issue_overpayment_succeeds() { let is_public_network = false; test_with_vault( @@ -823,7 +814,6 @@ async fn test_issue_overpayment_succeeds() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_automatic_issue_execution_succeeds_on_mainnet() { let is_public_network = true; test_automatic_issue_execution_succeeds_on_network(is_public_network).await; @@ -831,7 +821,6 @@ async fn test_automatic_issue_execution_succeeds_on_mainnet() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_automatic_issue_execution_succeeds_on_testnet() { let is_public_network = false; test_automatic_issue_execution_succeeds_on_network(is_public_network).await; @@ -945,7 +934,6 @@ async fn test_automatic_issue_execution_succeeds_on_network(is_public_network: b /// amounts). #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_automatic_issue_execution_succeeds_for_other_vault() { let is_public_network = false; test_with_vault( @@ -1092,7 +1080,6 @@ async fn test_automatic_issue_execution_succeeds_for_other_vault() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(1_200_000)] // timeout at 20 minutes async fn test_execute_open_requests_succeeds() { let is_public_network = false; test_with_vault( @@ -1214,7 +1201,6 @@ async fn test_execute_open_requests_succeeds() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_off_chain_liquidation() { let is_public_network = false; test_with_vault( @@ -1330,7 +1316,6 @@ async fn test_shutdown() { #[tokio::test(flavor = "multi_thread")] #[serial] -#[ntest::timeout(300_000)] // timeout at 5 minutes async fn test_requests_with_incompatible_amounts_fail() { test_with_vault( false, From 413fda1d74148abdde3683c73085f874e5eee9c3 Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Wed, 18 Sep 2024 11:56:31 +0200 Subject: [PATCH 31/63] Add fallback to default stroop fee --- clients/wallet/src/stellar_wallet.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/clients/wallet/src/stellar_wallet.rs b/clients/wallet/src/stellar_wallet.rs index b0c2ab60a..eee71342e 100644 --- a/clients/wallet/src/stellar_wallet.rs +++ b/clients/wallet/src/stellar_wallet.rs @@ -65,6 +65,9 @@ impl StellarWallet { pub(crate) const DEFAULT_MAX_RETRY_ATTEMPTS_BEFORE_FALLBACK: u8 = 3; pub(crate) const DEFAULT_MAX_BACKOFF_DELAY_IN_SECS: u16 = 60; + + /// We choose a default fee that is quite high to ensure that the transaction is processed + pub(crate) const DEFAULT_STROOP_FEE_PER_OPERATION: u32 = 100_000; } impl StellarWallet { @@ -377,9 +380,15 @@ impl StellarWallet { let _ = self.transaction_submission_lock.lock().await; let stroop_fee_per_operation = - get_fee_stat_for(self.is_public_network, FeeAttribute::default()) - .await - .map_err(|e| Error::FailedToGetFee(e))?; + match get_fee_stat_for(self.is_public_network, FeeAttribute::default()).await { + Ok(fee) => fee, + Err(e) => { + tracing::error!("Failed to get fee stat for Stellar network: {e:?}"); + // Return default fee for the operation. + tracing::info!("Using the default stroop fee for operation: {fee:?}"); + StellarWallet::DEFAULT_STROOP_FEE_PER_OPERATION + }, + }; let account = self.client.get_account(self.public_key(), self.is_public_network).await?; let next_sequence_number = account.sequence + 1; From 6b2905ee6d81147eb6ec3ea629fbc77a0f6f1a3b Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Wed, 18 Sep 2024 11:56:44 +0200 Subject: [PATCH 32/63] Reduce amount in redeem test --- clients/vault/tests/vault_integration_tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/vault/tests/vault_integration_tests.rs b/clients/vault/tests/vault_integration_tests.rs index bcc9ee049..37df02314 100644 --- a/clients/vault/tests/vault_integration_tests.rs +++ b/clients/vault/tests/vault_integration_tests.rs @@ -71,8 +71,8 @@ async fn test_redeem_succeeds_on_network(is_public_network: bool) { let vault_id_manager = VaultIdManager::from_map(vault_provider.clone(), vault_wallet.clone(), vault_ids); - // We issue 1 (spacewalk-chain) unit - let issue_amount = DecimalsLookupImpl::one(CurrencyId::Native) / 100; + // We issue 1/1000 unit + let issue_amount = DecimalsLookupImpl::one(CurrencyId::Native) / 1000; let vault_collateral = get_required_vault_collateral_for_issue( &vault_provider, issue_amount, From 2cf9075c5ab2b7e9ea7232f8279a25ef331d4733 Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Wed, 18 Sep 2024 11:59:13 +0200 Subject: [PATCH 33/63] Fix compilation error --- clients/wallet/src/stellar_wallet.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/clients/wallet/src/stellar_wallet.rs b/clients/wallet/src/stellar_wallet.rs index eee71342e..92d95e361 100644 --- a/clients/wallet/src/stellar_wallet.rs +++ b/clients/wallet/src/stellar_wallet.rs @@ -385,8 +385,9 @@ impl StellarWallet { Err(e) => { tracing::error!("Failed to get fee stat for Stellar network: {e:?}"); // Return default fee for the operation. - tracing::info!("Using the default stroop fee for operation: {fee:?}"); - StellarWallet::DEFAULT_STROOP_FEE_PER_OPERATION + let fallback_fee = StellarWallet::DEFAULT_STROOP_FEE_PER_OPERATION; + tracing::info!("Using the default stroop fee for operation: {fallback_fee:?}"); + fallback_fee }, }; From 1335c984416482766ed285c789949a92217ab7e0 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Thu, 19 Sep 2024 16:43:56 +0800 Subject: [PATCH 34/63] move `is_proof_building_ready` out of oracle agent --- .../connection/connector/message_creation.rs | 13 +++++ .../connection/connector/message_handler.rs | 4 +- .../connection/connector/message_reader.rs | 12 +++- clients/stellar-relay-lib/src/overlay.rs | 4 +- clients/stellar-relay-lib/src/tests/mod.rs | 57 +++++++++---------- clients/vault/src/oracle/agent.rs | 41 ++++++++----- clients/vault/src/oracle/collector/handler.rs | 8 +-- .../src/oracle/collector/proof_builder.rs | 7 +++ clients/vault/src/requests/execution.rs | 4 -- clients/vault/tests/helper/mod.rs | 7 +-- 10 files changed, 93 insertions(+), 64 deletions(-) diff --git a/clients/stellar-relay-lib/src/connection/connector/message_creation.rs b/clients/stellar-relay-lib/src/connection/connector/message_creation.rs index e7473976f..d81ae6974 100644 --- a/clients/stellar-relay-lib/src/connection/connector/message_creation.rs +++ b/clients/stellar-relay-lib/src/connection/connector/message_creation.rs @@ -6,6 +6,8 @@ use substrate_stellar_sdk::{ types::{AuthenticatedMessage, AuthenticatedMessageV0, HmacSha256Mac, StellarMessage}, XdrCodec, }; +use substrate_stellar_sdk::compound_types::LimitedString; +use substrate_stellar_sdk::types::ErrorCode; impl Connector { /// Wraps the stellar message with `AuthenticatedMessage` @@ -75,3 +77,14 @@ impl Connector { ) } } + +/// Create our own error to send over to the user/outsider. +pub(crate) fn crate_specific_error() -> StellarMessage { + let error = "Stellar Relay Error".as_bytes().to_vec(); + let error = substrate_stellar_sdk::types::Error { + code: ErrorCode::ErrMisc, + msg: LimitedString::new(error).expect("should return a valid LimitedString"), + }; + + StellarMessage::ErrorMsg(error) +} \ No newline at end of file diff --git a/clients/stellar-relay-lib/src/connection/connector/message_handler.rs b/clients/stellar-relay-lib/src/connection/connector/message_handler.rs index 3e5289852..ec72d6474 100644 --- a/clients/stellar-relay-lib/src/connection/connector/message_handler.rs +++ b/clients/stellar-relay-lib/src/connection/connector/message_handler.rs @@ -70,7 +70,7 @@ impl Connector { match msg { StellarMessage::Hello(hello) => { // update the node info based on the hello message - self.process_hello_message(hello)?; + self.process_hello_message(hello.clone())?; self.got_hello(); @@ -80,6 +80,8 @@ impl Connector { self.send_auth_message(self.local().node().overlay_version).await?; } info!("process_stellar_message(): Hello message processed successfully"); + // Pass the hello message to the user/outsider. To signal that the Overlay is ready. + return Ok(Some(StellarMessage::Hello(hello))); }, StellarMessage::Auth(_) => { diff --git a/clients/stellar-relay-lib/src/connection/connector/message_reader.rs b/clients/stellar-relay-lib/src/connection/connector/message_reader.rs index a3532e057..c5cb7b640 100644 --- a/clients/stellar-relay-lib/src/connection/connector/message_reader.rs +++ b/clients/stellar-relay-lib/src/connection/connector/message_reader.rs @@ -6,7 +6,8 @@ use tokio::{ sync::{mpsc, mpsc::error::TryRecvError}, time::timeout, }; -use tracing::{debug, error, info, trace, warn}; +use tracing::{error, info, trace, warn}; +use crate::connection::connector::message_creation::crate_specific_error; /// The waiting time for reading messages from stream. static READ_TIMEOUT_IN_SECS: u64 = 60; @@ -73,7 +74,7 @@ pub(crate) async fn poll_messages_from_stellar( } tokio::task::yield_now().await; }, - Ok(None) => {}, + Ok(None) => tokio::task::yield_now().await, Err(e) => { error!("poll_messages_from_stellar(): Error occurred during processing xdr message: {e:?}"); break; @@ -81,12 +82,17 @@ pub(crate) async fn poll_messages_from_stellar( } } + // push error to user + if let Err(e) = send_to_user_sender.send(crate_specific_error()).await { + warn!("poll_messages_from_stellar(): Error occurred during sending message {} to user: {e:?}",e); + } + // make sure to shutdown the connector connector.stop(); send_to_node_receiver.close(); drop(send_to_user_sender); - debug!("poll_messages_from_stellar(): stopped."); + info!("poll_messages_from_stellar(): stopped."); } /// Returns Xdr format of the `StellarMessage` sent from the Stellar Node diff --git a/clients/stellar-relay-lib/src/overlay.rs b/clients/stellar-relay-lib/src/overlay.rs index e32eb7a9e..d011bf716 100644 --- a/clients/stellar-relay-lib/src/overlay.rs +++ b/clients/stellar-relay-lib/src/overlay.rs @@ -3,7 +3,7 @@ use tokio::sync::{ mpsc, mpsc::{error::SendError, Sender}, }; -use tracing::{debug, info}; +use tracing::{debug, error, info}; use crate::{ connection::{poll_messages_from_stellar, ConnectionInfo, Connector}, @@ -68,7 +68,7 @@ impl StellarOverlayConnection { /// poll_messages_from_stellar](../src/connection/connector/message_reader.rs) pub async fn listen(&mut self) -> Result, Error> { if !self.is_alive() { - debug!("listen(): sender half of overlay has closed."); + error!("listen(): sender half of overlay has closed."); return Err(Error::Disconnected) } diff --git a/clients/stellar-relay-lib/src/tests/mod.rs b/clients/stellar-relay-lib/src/tests/mod.rs index 4166068a7..2d5adc8e9 100644 --- a/clients/stellar-relay-lib/src/tests/mod.rs +++ b/clients/stellar-relay-lib/src/tests/mod.rs @@ -76,6 +76,7 @@ async fn stellar_overlay_should_receive_scp_messages() { #[tokio::test(flavor = "multi_thread")] #[serial] +#[ntest::timeout(300_000)] // timeout at 5 minutes async fn stellar_overlay_should_receive_tx_set() { //arrange fn get_tx_set_hash(x: &ScpStatementExternalize) -> Hash { @@ -94,37 +95,33 @@ async fn stellar_overlay_should_receive_tx_set() { let tx_set_hashes_clone = tx_set_hashes.clone(); let actual_tx_set_hashes_clone = actual_tx_set_hashes.clone(); - timeout(Duration::from_secs(500), async move { - let mut ov_conn_locked = ov_conn.lock().await; - - while let Ok(Some(msg)) = ov_conn_locked.listen().await { - match msg { - StellarMessage::ScpMessage(msg) => { - if let ScpStatementPledges::ScpStExternalize(stmt) = &msg.statement.pledges { - let tx_set_hash = get_tx_set_hash(stmt); - tx_set_hashes_clone.lock().await.push(tx_set_hash.clone()); - ov_conn_locked - .send_to_node(StellarMessage::GetTxSet(tx_set_hash)) - .await - .unwrap(); - } - }, - StellarMessage::TxSet(set) => { - let tx_set_hash = set.into_hash().expect("should return a hash"); - actual_tx_set_hashes_clone.lock().await.push(tx_set_hash); - break; - }, - StellarMessage::GeneralizedTxSet(set) => { - let tx_set_hash = set.into_hash().expect("should return a hash"); - actual_tx_set_hashes_clone.lock().await.push(tx_set_hash); - break; - }, - _ => {}, - } + let mut ov_conn_locked = ov_conn.lock().await; + + while let Ok(Some(msg)) = ov_conn_locked.listen().await { + match msg { + StellarMessage::ScpMessage(msg) => { + if let ScpStatementPledges::ScpStExternalize(stmt) = &msg.statement.pledges { + let tx_set_hash = get_tx_set_hash(stmt); + tx_set_hashes_clone.lock().await.push(tx_set_hash.clone()); + ov_conn_locked + .send_to_node(StellarMessage::GetTxSet(tx_set_hash)) + .await + .unwrap(); + } + }, + StellarMessage::TxSet(set) => { + let tx_set_hash = set.into_hash().expect("should return a hash"); + actual_tx_set_hashes_clone.lock().await.push(tx_set_hash); + break; + }, + StellarMessage::GeneralizedTxSet(set) => { + let tx_set_hash = set.into_hash().expect("should return a hash"); + actual_tx_set_hashes_clone.lock().await.push(tx_set_hash); + break; + }, + _ => {}, } - }) - .await - .expect("time has elapsed"); + } //ensure that we receive some tx set from stellar node let expected_hashes = tx_set_hashes.lock().await; diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index 2419d00b0..d68ed9570 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -41,9 +41,6 @@ impl OracleAgent { OracleAgent { collector, is_public_network, message_sender: None, shutdown_sender } } - pub async fn is_proof_building_ready(&self) -> bool { - self.collector.read().await.last_slot_index() > 0 - } } /// listens to data to collect the scp messages and txsets. @@ -52,14 +49,22 @@ impl OracleAgent { /// * `message` - A message from the StellarRelay /// * `collector` - used to collect envelopes and transaction sets /// * `message_sender` - used to send messages to Stellar Node +/// * `is_proof_building_ready` - set a signal to ready if a slot was saved async fn handle_message( message: StellarMessage, collector: Arc>, message_sender: &StellarMessageSender, + is_proof_building_ready: &mut Option, ) -> Result<(), Error> { match message { StellarMessage::ScpMessage(env) => { - collector.write().await.handle_envelope(env, message_sender).await?; + // if the first slot was saved, it means proof building is ready. + if let Some(slot) = collector.write().await.handle_envelope(env, message_sender).await? { + if let Some(true) = is_proof_building_ready { + tracing::info!("handle_message(): First slot saved: {slot}. Ready to build proofs "); + } + *is_proof_building_ready = None; + } }, StellarMessage::TxSet(set) => if let Err(e) = collector.read().await.add_txset(set) { @@ -101,11 +106,20 @@ pub async fn listen_for_stellar_messages( // log a new message received, every 1 minute. let interval = Duration::from_secs(60); let mut next_time = Instant::now() + interval; + let mut is_proof_building_ready:Option = Some(false); loop { let collector = oracle_agent.read().await.collector.clone(); match overlay_conn.listen().await { Ok(None) => {}, + Ok(Some(StellarMessage::Hello(_))) => { + tracing::info!("listen_for_stellar_messages(): received hello message from Stellar"); + is_proof_building_ready = Some(true); + } + Ok(Some(StellarMessage::ErrorMsg(e))) => { + tracing::error!("listen_for_stellar_messages(): received error message from Stellar: {e:?}"); + break + }, Ok(Some(msg)) => { let msg_as_str = to_base64_xdr_string(&msg); if Instant::now() >= next_time { @@ -113,22 +127,26 @@ pub async fn listen_for_stellar_messages( next_time += interval; } - if let Err(e) = handle_message(msg, collector.clone(), &sender).await { + if let Some(true) = is_proof_building_ready { + tracing::info!("listen_for_stellar_messages(): received message from Stellar: {msg_as_str}"); + }; + + if let Err(e) = handle_message(msg, collector.clone(), &sender, &mut is_proof_building_ready).await { tracing::error!("listen_for_stellar_messages(): failed to handle message: {msg_as_str}: {e:?}"); } }, // connection got lost Err(e) => { tracing::error!("listen_for_stellar_messages(): encounter error in overlay: {e:?}"); - - if let Err(e) = shutdown_sender.send(()) { - tracing::error!("listen_for_stellar_messages(): Failed to send shutdown signal in thread: {e:?}"); - } break }, } } + if let Err(e) = shutdown_sender.send(()) { + tracing::error!("listen_for_stellar_messages(): Failed to send shutdown signal in thread: {e:?}"); + } + tracing::info!("listen_for_stellar_messages(): shutting down overlay connection"); overlay_conn.stop(); @@ -146,11 +164,6 @@ pub async fn start_oracle_agent( tokio::spawn(listen_for_stellar_messages(cfg, oracle_agent.clone(), secret, shutdown_sender)); - while !oracle_agent.read().await.is_proof_building_ready().await { - tracing::info!("start_oracle_agent(): waiting for the first slot to be received"); - sleep(Duration::from_millis(500)).await; - } - oracle_agent } diff --git a/clients/vault/src/oracle/collector/handler.rs b/clients/vault/src/oracle/collector/handler.rs index feb889455..61fd6be03 100644 --- a/clients/vault/src/oracle/collector/handler.rs +++ b/clients/vault/src/oracle/collector/handler.rs @@ -10,7 +10,7 @@ use stellar_relay_lib::{ // Handling SCPEnvelopes impl ScpMessageCollector { - /// handles incoming ScpEnvelope. + /// Handles incoming ScpEnvelope. Return slot if it was saved /// /// # Arguments /// @@ -20,7 +20,7 @@ impl ScpMessageCollector { &mut self, env: ScpEnvelope, message_sender: &StellarMessageSender, - ) -> Result<(), Error> { + ) -> Result, Error> { let slot = env.statement.slot_index; // we are only interested with `ScpStExternalize`. Other messages are ignored. @@ -48,10 +48,10 @@ impl ScpMessageCollector { // insert/add the externalized message to map. self.add_scp_envelope(slot, env); + Ok(Some(slot)) } else { self.remove_data(&slot); + Ok(None) } - - Ok(()) } } diff --git a/clients/vault/src/oracle/collector/proof_builder.rs b/clients/vault/src/oracle/collector/proof_builder.rs index d8aa52042..b4dc21203 100644 --- a/clients/vault/src/oracle/collector/proof_builder.rs +++ b/clients/vault/src/oracle/collector/proof_builder.rs @@ -63,6 +63,13 @@ impl ScpMessageCollector { /// * `slot` - the slot where the txset is to get. /// * `sender` - used to send messages to Stellar Node pub async fn build_proof(&self, slot: Slot, sender: &StellarMessageSender) -> Option { + if self.last_slot_index() == 0 { + tracing::warn!( + "build_proof(): Proof Building for slot {slot}: last_slot_index is still 0, not yet ready to build proofs." + ); + return None; + } + let Some(envelopes) = self.get_envelopes(slot, sender).await else { // return early if we don't have enough envelopes tracing::warn!( diff --git a/clients/vault/src/requests/execution.rs b/clients/vault/src/requests/execution.rs index 484b3a750..f9fbaab88 100644 --- a/clients/vault/src/requests/execution.rs +++ b/clients/vault/src/requests/execution.rs @@ -305,10 +305,6 @@ pub async fn execute_open_requests( let rate_limiter = Arc::new(RateLimiter::direct(YIELD_RATE)); - while !oracle_agent.read().await.is_proof_building_ready().await { - tracing::debug!("execute_open_requests(): agent is not yet ready. Waiting..."); - } - tracing::info!("execute_open_requests(): Oracle agent is ready."); // Check if the open requests have a corresponding payment on Stellar diff --git a/clients/vault/tests/helper/mod.rs b/clients/vault/tests/helper/mod.rs index 60d430b85..37abe7c0c 100644 --- a/clients/vault/tests/helper/mod.rs +++ b/clients/vault/tests/helper/mod.rs @@ -19,7 +19,7 @@ use sp_keyring::AccountKeyring; use std::{future::Future, sync::Arc}; use stellar_relay_lib::StellarOverlayConfig; use subxt::utils::AccountId32 as AccountId; -use tokio::{sync::RwLock, time::sleep}; +use tokio::sync::RwLock; use vault::{ oracle::{random_stellar_relay_config, start_oracle_agent, OracleAgent}, ArcRwLock, @@ -145,11 +145,6 @@ where let shutdown_tx = ShutdownSender::new(); let oracle_agent = start_oracle_agent(stellar_config, vault_stellar_secret, shutdown_tx).await; - // continue ONLY if the oracle agent has received the first slot - while !oracle_agent.read().await.is_proof_building_ready().await { - tracing::info!("Waiting for the oracle agent to be ready... in helper mod"); - sleep(std::time::Duration::from_millis(500)).await; - } execute(client, vault_wallet, user_wallet, oracle_agent, vault_id, vault_provider).await } From 5b4307ced3821859d20420c76945901954f1bbc3 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 1 Oct 2024 14:43:21 +0800 Subject: [PATCH 35/63] run release --- .github/workflows/ci-main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-main.yml b/.github/workflows/ci-main.yml index b06d9a157..9ae63459c 100644 --- a/.github/workflows/ci-main.yml +++ b/.github/workflows/ci-main.yml @@ -92,7 +92,7 @@ jobs: - name: Check Build if: matrix.rust == 'stable' run: | - bash ./scripts/cmd-all build check + bash ./scripts/cmd-all build check "--release" - name: Test if: matrix.rust == 'nightly' @@ -105,7 +105,7 @@ jobs: with: toolchain: nightly-2024-02-09 command: test - args: --all --all-features + args: --release --all --all-features - name: Rustfmt if: matrix.rust == 'nightly' @@ -118,7 +118,7 @@ jobs: - name: Clippy -- Libraries and Binaries if: matrix.rust == 'stable' run: | - bash ./scripts/cmd-all clippy "clippy --lib --bins" "-- -W clippy::all -A clippy::style -A forgetting_copy_types -A forgetting_references" + bash ./scripts/cmd-all clippy "clippy --lib --bins" "--release -- -W clippy::all -A clippy::style -A forgetting_copy_types -A forgetting_references" - name: Clippy -- Tests and Examples if: matrix.rust == 'nightly' @@ -126,4 +126,4 @@ jobs: with: toolchain: nightly-2024-02-09 command: clippy - args: --all-features --tests --benches --examples -- -A clippy::all -W clippy::correctness -A forgetting_copy_types -A forgetting_references \ No newline at end of file + args: --release --all-features --tests --benches --examples -- -A clippy::all -W clippy::correctness -A forgetting_copy_types -A forgetting_references \ No newline at end of file From 01046afd083e798d402822c40de793cae3ae1018 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:43:57 +0800 Subject: [PATCH 36/63] use `try_recv` instead https://github.com/pendulum-chain/spacewalk/pull/545#discussion_r1761456867 https://github.com/pendulum-chain/spacewalk/pull/545#discussion_r1761489738 https://github.com/pendulum-chain/spacewalk/pull/545#discussion_r1761547893 https://github.com/pendulum-chain/spacewalk/pull/545#discussion_r1761548974 --- clients/service/src/lib.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/clients/service/src/lib.rs b/clients/service/src/lib.rs index 0e1aa49e4..ea7d2ea81 100644 --- a/clients/service/src/lib.rs +++ b/clients/service/src/lib.rs @@ -8,6 +8,7 @@ use async_trait::async_trait; use futures::{future::Either, Future, FutureExt}; use governor::{Quota, RateLimiter}; use nonzero_ext::*; +use tokio::sync::broadcast::error::TryRecvError; use tokio::{sync::RwLock, time::sleep}; pub use warp; @@ -178,19 +179,28 @@ where F: Future>, { if let Some(mut precheck_signal) = precheck_signal { - if let Err(e) = precheck_signal.recv().await { - tracing::error!("Error receiving precheck signal: {:?}", e); - return Ok(()) + loop { + match precheck_signal.try_recv() { + // Received a signal to start the task + Ok(_) => break, + Err(TryRecvError::Empty) => + tracing::trace!("wait_or_shutdown precheck signal: waiting..."), + // Precheck signal failed. Cannot start the task. + Err(e) => { + tracing::error!("Error receiving precheck signal: {:?}", e); + return Ok(()); + } + } } } match run_cancelable(shutdown_tx.subscribe(), future2).await { TerminationStatus::Cancelled => { - tracing::trace!("Received shutdown signal"); + tracing::trace!("wait_or_shutdown(): Received shutdown signal"); Ok(()) }, TerminationStatus::Completed(res) => { - tracing::trace!("Sending shutdown signal"); + tracing::trace!("wait_or_shutdown(): Sending shutdown signal"); let _ = shutdown_tx.send(()); res }, From be7ba9e1fe17e8f936c50cd17e9c7f7237d8b39c Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:44:05 +0800 Subject: [PATCH 37/63] use `try_recv` instead https://github.com/pendulum-chain/spacewalk/pull/545#discussion_r1761456867 https://github.com/pendulum-chain/spacewalk/pull/545#discussion_r1761489738 https://github.com/pendulum-chain/spacewalk/pull/545#discussion_r1761547893 https://github.com/pendulum-chain/spacewalk/pull/545#discussion_r1761548974 --- clients/vault/src/oracle/collector/proof_builder.rs | 6 +++--- clients/vault/src/system.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clients/vault/src/oracle/collector/proof_builder.rs b/clients/vault/src/oracle/collector/proof_builder.rs index b4dc21203..85b5c95ac 100644 --- a/clients/vault/src/oracle/collector/proof_builder.rs +++ b/clients/vault/src/oracle/collector/proof_builder.rs @@ -381,9 +381,9 @@ mod test { fn collector(is_mainnet: bool) -> ScpMessageCollector { let archives = if is_mainnet { vec![ - "https://stellar-history-de-fra.satoshipay.io".to_string(), - "https://stellar-history-sg-sin.satoshipay.io".to_string(), - "https://stellar-history-us-iowa.satoshipay.io".to_string(), + "http://history.stellar.org/prd/core-live/core_live_001".to_string(), + "http://history.stellar.org/prd/core-live/core_live_002".to_string(), + "http://history.stellar.org/prd/core-live/core_live_003".to_string(), ] } else { vec![ diff --git a/clients/vault/src/system.rs b/clients/vault/src/system.rs index 7fa80428f..a2e2ce957 100644 --- a/clients/vault/src/system.rs +++ b/clients/vault/src/system.rs @@ -51,7 +51,7 @@ pub const AUTHORS: &str = env!("CARGO_PKG_AUTHORS"); pub const NAME: &str = env!("CARGO_PKG_NAME"); pub const ABOUT: &str = env!("CARGO_PKG_DESCRIPTION"); -const RESTART_INTERVAL: Duration = Duration::from_secs(7200); // restart every 3 hours +const RESTART_INTERVAL: Duration = Duration::from_secs(7200); // restart every 2 hours #[derive(Clone, Debug)] pub struct VaultData { @@ -629,7 +629,7 @@ impl VaultService { ( "Restart Timer", run(async move { - tracing::info!("Periodic restart in 3 hours."); + tracing::info!("Periodic restart in {RESTART_INTERVAL} minutes."); tokio::time::sleep(RESTART_INTERVAL).await; tracing::info!("Initiating periodic restart..."); Err(ServiceError::ClientShutdown) From 2eecdaefceee7b804639f2e739d1bb79fa4227ad Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 1 Oct 2024 22:34:56 +0800 Subject: [PATCH 38/63] https://github.com/pendulum-chain/spacewalk/actions/runs/11120883420/job/30898768243?pr=545 --- clients/runtime/src/extrinsic_params.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/clients/runtime/src/extrinsic_params.rs b/clients/runtime/src/extrinsic_params.rs index a447bb45b..8078ef0db 100644 --- a/clients/runtime/src/extrinsic_params.rs +++ b/clients/runtime/src/extrinsic_params.rs @@ -17,6 +17,7 @@ cfg_if::cfg_if! { } } +#[cfg(feature = "standalone-metadata")] pub type CustomExtrinsicParams = signed_extensions::AnyOf< T, ( From 37bc3198ac7d9eb82753ccb8a953a05ea61edab6 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 1 Oct 2024 23:16:46 +0800 Subject: [PATCH 39/63] https://github.com/pendulum-chain/spacewalk/pull/545#discussion_r1761484283, https://github.com/pendulum-chain/spacewalk/actions/runs/11127602452/job/30920300244?pr=545 --- clients/runtime/src/extrinsic_params.rs | 2 +- clients/vault/src/oracle/collector/proof_builder.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/runtime/src/extrinsic_params.rs b/clients/runtime/src/extrinsic_params.rs index 8078ef0db..552a788a3 100644 --- a/clients/runtime/src/extrinsic_params.rs +++ b/clients/runtime/src/extrinsic_params.rs @@ -17,7 +17,7 @@ cfg_if::cfg_if! { } } -#[cfg(feature = "standalone-metadata")] +#[cfg(not(feature = "standalone-metadata"))] pub type CustomExtrinsicParams = signed_extensions::AnyOf< T, ( diff --git a/clients/vault/src/oracle/collector/proof_builder.rs b/clients/vault/src/oracle/collector/proof_builder.rs index 85b5c95ac..e46af0335 100644 --- a/clients/vault/src/oracle/collector/proof_builder.rs +++ b/clients/vault/src/oracle/collector/proof_builder.rs @@ -222,7 +222,7 @@ impl ScpMessageCollector { let scp_archive_result = scp_archive_storage.get_archive(slot).await; if let Err(e) = scp_archive_result { tracing::error!( - "get_envelopes_from_horizon_archive(): Could not get SCPArchive for slot {slot} from Horizon Archive: {e:?}" + "get_envelopes_from_horizon_archive(): Could not get SCPArchive for slot {slot} from Horizon Archive {archive_url}: {e:?}" ); continue; } @@ -290,7 +290,7 @@ impl ScpMessageCollector { } } } else { - tracing::warn!("get_envelopes_from_horizon_archive(): Could not get ScpHistory entry from archive for slot {slot}"); + tracing::warn!("get_envelopes_from_horizon_archive(): Could not get ScpHistory entry from archive {archive_url} for slot {slot}"); } } } From 5f833d38c5a06f9892d633ea052cf9a3911261fd Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Wed, 2 Oct 2024 13:45:15 +0800 Subject: [PATCH 40/63] clean testing issues --- clients/runtime/src/extrinsic_params.rs | 5 ++++- clients/vault/src/oracle/collector/proof_builder.rs | 2 +- clients/vault/src/system.rs | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/clients/runtime/src/extrinsic_params.rs b/clients/runtime/src/extrinsic_params.rs index 552a788a3..f96cf322c 100644 --- a/clients/runtime/src/extrinsic_params.rs +++ b/clients/runtime/src/extrinsic_params.rs @@ -2,12 +2,15 @@ use codec::Encode; use subxt::{ client::OfflineClientT, config::{ - signed_extensions, ExtrinsicParamsEncoder, ExtrinsicParamsError, PolkadotExtrinsicParams, + ExtrinsicParamsEncoder, ExtrinsicParamsError, PolkadotExtrinsicParams, SignedExtension, }, Config, }; +#[cfg(not(feature = "standalone-metadata"))] +use subxt::config::signed_extensions; + // Check features to decide which extrinsic params to use cfg_if::cfg_if! { if #[cfg(feature = "standalone-metadata")] { diff --git a/clients/vault/src/oracle/collector/proof_builder.rs b/clients/vault/src/oracle/collector/proof_builder.rs index e46af0335..335cd0d92 100644 --- a/clients/vault/src/oracle/collector/proof_builder.rs +++ b/clients/vault/src/oracle/collector/proof_builder.rs @@ -218,7 +218,7 @@ impl ScpMessageCollector { // We try to get the SCPArchive from each archive URL until we succeed or run out of // URLs for archive_url in archive_urls { - let scp_archive_storage = ScpArchiveStorage(archive_url); + let scp_archive_storage = ScpArchiveStorage(archive_url.clone()); let scp_archive_result = scp_archive_storage.get_archive(slot).await; if let Err(e) = scp_archive_result { tracing::error!( diff --git a/clients/vault/src/system.rs b/clients/vault/src/system.rs index a2e2ce957..b7289637a 100644 --- a/clients/vault/src/system.rs +++ b/clients/vault/src/system.rs @@ -629,7 +629,7 @@ impl VaultService { ( "Restart Timer", run(async move { - tracing::info!("Periodic restart in {RESTART_INTERVAL} minutes."); + tracing::info!("Periodic restart in {RESTART_INTERVAL:?} minutes."); tokio::time::sleep(RESTART_INTERVAL).await; tracing::info!("Initiating periodic restart..."); Err(ServiceError::ClientShutdown) From c44bac8318012c3a96827fef1c2a27b3249b162f Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:06:40 +0800 Subject: [PATCH 41/63] fix issues --- clients/stellar-relay-lib/examples/connect.rs | 2 +- .../config/testnet/stellar_relay_config_sdftest1.json | 6 +++--- .../config/testnet/stellar_relay_config_sdftest2.json | 6 +++--- .../config/testnet/stellar_relay_config_sdftest3.json | 6 +++--- clients/vault/src/oracle/agent.rs | 9 +++++++++ 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/clients/stellar-relay-lib/examples/connect.rs b/clients/stellar-relay-lib/examples/connect.rs index a8e6b8330..84f2d15f4 100644 --- a/clients/stellar-relay-lib/examples/connect.rs +++ b/clients/stellar-relay-lib/examples/connect.rs @@ -15,7 +15,7 @@ async fn main() -> Result<(), Box> { let arg_network = if args.len() > 1 { &args[1] } else { "testnet" }; let cfg_file_path = if arg_network == "mainnet" { - "./clients/stellar-relay-lib/resources/config/mainnet/stellar_relay_config_singapore.json" + "./clients/stellar-relay-lib/resources/config/mainnet/stellar_relay_config_mainnet_iowa.json" } else { "./clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest1.json" }; diff --git a/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest1.json b/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest1.json index 070253e8c..44e908d25 100644 --- a/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest1.json +++ b/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest1.json @@ -5,9 +5,9 @@ }, "node_info": { "ledger_version": 21, - "overlay_version": 35, - "overlay_min_version": 33, - "version_str": "stellar-core 21.3.1 (4ede19620438bcd136276cdc8d4ed1f2c3b64624)", + "overlay_version": 34, + "overlay_min_version": 32, + "version_str": "stellar-core 21.2.0 (d78f48eacabb51753e34443de7618b956e61c59f)", "is_pub_net": false }, "stellar_history_archive_urls": [ diff --git a/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest2.json b/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest2.json index 003d98e12..3b431ef78 100644 --- a/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest2.json +++ b/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest2.json @@ -5,9 +5,9 @@ }, "node_info": { "ledger_version": 21, - "overlay_version": 35, - "overlay_min_version": 33, - "version_str": "stellar-core 21.3.1 (4ede19620438bcd136276cdc8d4ed1f2c3b64624)", + "overlay_version": 34, + "overlay_min_version": 32, + "version_str": "stellar-core 21.2.0 (d78f48eacabb51753e34443de7618b956e61c59f)", "is_pub_net": false }, "stellar_history_archive_urls": [ diff --git a/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest3.json b/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest3.json index 9e6cbaf2d..404ded3bb 100644 --- a/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest3.json +++ b/clients/stellar-relay-lib/resources/config/testnet/stellar_relay_config_sdftest3.json @@ -5,9 +5,9 @@ }, "node_info": { "ledger_version": 21, - "overlay_version": 35, - "overlay_min_version": 33, - "version_str": "stellar-core 21.3.1 (4ede19620438bcd136276cdc8d4ed1f2c3b64624)", + "overlay_version": 34, + "overlay_min_version": 32, + "version_str": "stellar-core 21.2.0 (d78f48eacabb51753e34443de7618b956e61c59f)", "is_pub_net": false }, "stellar_history_archive_urls": [ diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index d68ed9570..9ec4c76d8 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -41,6 +41,10 @@ impl OracleAgent { OracleAgent { collector, is_public_network, message_sender: None, shutdown_sender } } + #[cfg(any(test, feature = "integration"))] + pub fn is_stellar_running(&self) -> bool { + self.message_sender.is_some() + } } /// listens to data to collect the scp messages and txsets. @@ -164,6 +168,11 @@ pub async fn start_oracle_agent( tokio::spawn(listen_for_stellar_messages(cfg, oracle_agent.clone(), secret, shutdown_sender)); + while !oracle_agent.read().await.is_stellar_running() { + sleep(Duration::from_millis(500)).await; + } + + tracing::info!("start_oracle_agent(): Stellar overlay network is running"); oracle_agent } From 3f03be8b4493e928034bd260cfb2022bdc1f6474 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Thu, 3 Oct 2024 17:14:54 +0800 Subject: [PATCH 42/63] https://github.com/pendulum-chain/spacewalk/actions/runs/11139347479/job/30962886547?pr=545#step:13:565 --- clients/vault/src/oracle/agent.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index 9ec4c76d8..7c55002de 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -234,6 +234,7 @@ mod tests { #[ntest::timeout(600_000)] // timeout at 10 minutes #[serial] async fn test_get_proof_for_current_slot() { + env_logger::init(); // let it run for a few seconds, making sure that the other tests have successfully shutdown // their connection to Stellar Node sleep(Duration::from_secs(2)).await; @@ -248,7 +249,13 @@ mod tests { ) .await; - let latest_slot = agent.read().await.collector.read().await.last_slot_index(); + let latest_slot = loop { + let slot = agent.read().await.collector.read().await.last_slot_index(); + if slot > 0 { + break slot + } + sleep(Duration::from_millis(500)).await; + }; let proof_result = agent.read().await.get_proof(latest_slot).await; assert!(proof_result.is_ok(), "Failed to get proof for slot: {}", latest_slot); From 6cc05d760d8bdd6419a2e364c3064de9e3c38377 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:12:05 +0800 Subject: [PATCH 43/63] remove env_logger --- clients/vault/src/oracle/agent.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index 7c55002de..8a4ba9ac4 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -234,7 +234,6 @@ mod tests { #[ntest::timeout(600_000)] // timeout at 10 minutes #[serial] async fn test_get_proof_for_current_slot() { - env_logger::init(); // let it run for a few seconds, making sure that the other tests have successfully shutdown // their connection to Stellar Node sleep(Duration::from_secs(2)).await; From 9cc31b5a78dc5bd968758a9ec4ef0aecbb5ef44e Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Thu, 3 Oct 2024 22:07:48 +0800 Subject: [PATCH 44/63] fix fmt and clippy issues --- Cargo.lock | 1 - clients/service/Cargo.toml | 1 - clients/service/src/lib.rs | 8 ++++-- .../connection/connector/message_creation.rs | 9 +++--- .../connection/connector/message_reader.rs | 11 ++++++-- clients/vault/src/oracle/agent.rs | 28 +++++++++++++------ clients/vault/tests/helper/mod.rs | 1 - 7 files changed, 38 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f547ef2eb..b346fea6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9870,7 +9870,6 @@ dependencies = [ "thiserror", "tokio", "tracing", - "tracing-futures", "tracing-subscriber 0.2.25", "wallet", "warp", diff --git a/clients/service/Cargo.toml b/clients/service/Cargo.toml index 859c9e5ce..4deebc7df 100644 --- a/clients/service/Cargo.toml +++ b/clients/service/Cargo.toml @@ -16,7 +16,6 @@ warp = "0.3.2" serde_json = "1.0.71" tracing = { version = "0.1", features = ["log"] } -tracing-futures = { version = "0.2.5" } tracing-subscriber = { version = "0.2.12", features = ["registry", "env-filter", "fmt"] } governor = "0.5.0" diff --git a/clients/service/src/lib.rs b/clients/service/src/lib.rs index 46e17d422..5df74e54c 100644 --- a/clients/service/src/lib.rs +++ b/clients/service/src/lib.rs @@ -10,8 +10,10 @@ use async_trait::async_trait; use futures::{future::Either, Future, FutureExt}; use governor::{Quota, RateLimiter}; use nonzero_ext::*; -use tokio::sync::broadcast::error::TryRecvError; -use tokio::{sync::RwLock, time::sleep}; +use tokio::{ + sync::{broadcast::error::TryRecvError, RwLock}, + time::sleep, +}; pub use warp; pub use cli::{LoggingFormat, MonitoringConfig, RestartPolicy, ServiceConfig}; @@ -191,7 +193,7 @@ where Err(e) => { tracing::error!("Error receiving precheck signal: {:?}", e); return Ok(()); - } + }, } } } diff --git a/clients/stellar-relay-lib/src/connection/connector/message_creation.rs b/clients/stellar-relay-lib/src/connection/connector/message_creation.rs index d81ae6974..0bb1ce5d1 100644 --- a/clients/stellar-relay-lib/src/connection/connector/message_creation.rs +++ b/clients/stellar-relay-lib/src/connection/connector/message_creation.rs @@ -3,11 +3,12 @@ use crate::connection::{ Connector, Error, }; use substrate_stellar_sdk::{ - types::{AuthenticatedMessage, AuthenticatedMessageV0, HmacSha256Mac, StellarMessage}, + compound_types::LimitedString, + types::{ + AuthenticatedMessage, AuthenticatedMessageV0, ErrorCode, HmacSha256Mac, StellarMessage, + }, XdrCodec, }; -use substrate_stellar_sdk::compound_types::LimitedString; -use substrate_stellar_sdk::types::ErrorCode; impl Connector { /// Wraps the stellar message with `AuthenticatedMessage` @@ -87,4 +88,4 @@ pub(crate) fn crate_specific_error() -> StellarMessage { }; StellarMessage::ErrorMsg(error) -} \ No newline at end of file +} diff --git a/clients/stellar-relay-lib/src/connection/connector/message_reader.rs b/clients/stellar-relay-lib/src/connection/connector/message_reader.rs index c5cb7b640..a2ee5e16d 100644 --- a/clients/stellar-relay-lib/src/connection/connector/message_reader.rs +++ b/clients/stellar-relay-lib/src/connection/connector/message_reader.rs @@ -1,4 +1,7 @@ -use crate::connection::{xdr_converter::get_xdr_message_length, Connector, Error, Xdr}; +use crate::connection::{ + connector::message_creation::crate_specific_error, xdr_converter::get_xdr_message_length, + Connector, Error, Xdr, +}; use async_std::io::ReadExt; use std::time::Duration; use substrate_stellar_sdk::{types::StellarMessage, XdrCodec}; @@ -7,7 +10,6 @@ use tokio::{ time::timeout, }; use tracing::{error, info, trace, warn}; -use crate::connection::connector::message_creation::crate_specific_error; /// The waiting time for reading messages from stream. static READ_TIMEOUT_IN_SECS: u64 = 60; @@ -84,7 +86,10 @@ pub(crate) async fn poll_messages_from_stellar( // push error to user if let Err(e) = send_to_user_sender.send(crate_specific_error()).await { - warn!("poll_messages_from_stellar(): Error occurred during sending message {} to user: {e:?}",e); + warn!( + "poll_messages_from_stellar(): Error occurred during sending message {} to user: {e:?}", + e + ); } // make sure to shutdown the connector diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index 8a4ba9ac4..84dd53c7e 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -63,9 +63,12 @@ async fn handle_message( match message { StellarMessage::ScpMessage(env) => { // if the first slot was saved, it means proof building is ready. - if let Some(slot) = collector.write().await.handle_envelope(env, message_sender).await? { + if let Some(slot) = collector.write().await.handle_envelope(env, message_sender).await? + { if let Some(true) = is_proof_building_ready { - tracing::info!("handle_message(): First slot saved: {slot}. Ready to build proofs "); + tracing::info!( + "handle_message(): First slot saved: {slot}. Ready to build proofs " + ); } *is_proof_building_ready = None; } @@ -110,18 +113,22 @@ pub async fn listen_for_stellar_messages( // log a new message received, every 1 minute. let interval = Duration::from_secs(60); let mut next_time = Instant::now() + interval; - let mut is_proof_building_ready:Option = Some(false); + let mut is_proof_building_ready: Option = Some(false); loop { let collector = oracle_agent.read().await.collector.clone(); match overlay_conn.listen().await { Ok(None) => {}, Ok(Some(StellarMessage::Hello(_))) => { - tracing::info!("listen_for_stellar_messages(): received hello message from Stellar"); + tracing::info!( + "listen_for_stellar_messages(): received hello message from Stellar" + ); is_proof_building_ready = Some(true); - } + }, Ok(Some(StellarMessage::ErrorMsg(e))) => { - tracing::error!("listen_for_stellar_messages(): received error message from Stellar: {e:?}"); + tracing::error!( + "listen_for_stellar_messages(): received error message from Stellar: {e:?}" + ); break }, Ok(Some(msg)) => { @@ -135,7 +142,10 @@ pub async fn listen_for_stellar_messages( tracing::info!("listen_for_stellar_messages(): received message from Stellar: {msg_as_str}"); }; - if let Err(e) = handle_message(msg, collector.clone(), &sender, &mut is_proof_building_ready).await { + if let Err(e) = + handle_message(msg, collector.clone(), &sender, &mut is_proof_building_ready) + .await + { tracing::error!("listen_for_stellar_messages(): failed to handle message: {msg_as_str}: {e:?}"); } }, @@ -148,7 +158,9 @@ pub async fn listen_for_stellar_messages( } if let Err(e) = shutdown_sender.send(()) { - tracing::error!("listen_for_stellar_messages(): Failed to send shutdown signal in thread: {e:?}"); + tracing::error!( + "listen_for_stellar_messages(): Failed to send shutdown signal in thread: {e:?}" + ); } tracing::info!("listen_for_stellar_messages(): shutting down overlay connection"); diff --git a/clients/vault/tests/helper/mod.rs b/clients/vault/tests/helper/mod.rs index 37abe7c0c..dae417d49 100644 --- a/clients/vault/tests/helper/mod.rs +++ b/clients/vault/tests/helper/mod.rs @@ -145,6 +145,5 @@ where let shutdown_tx = ShutdownSender::new(); let oracle_agent = start_oracle_agent(stellar_config, vault_stellar_secret, shutdown_tx).await; - execute(client, vault_wallet, user_wallet, oracle_agent, vault_id, vault_provider).await } From 9d6fe305642c503244e3f070db66afc47138132b Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Thu, 3 Oct 2024 23:39:21 +0800 Subject: [PATCH 45/63] fix nightly issues --- clients/stellar-relay-lib/src/tests/mod.rs | 58 ++++++++++++---------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/clients/stellar-relay-lib/src/tests/mod.rs b/clients/stellar-relay-lib/src/tests/mod.rs index 2d5adc8e9..e40b25407 100644 --- a/clients/stellar-relay-lib/src/tests/mod.rs +++ b/clients/stellar-relay-lib/src/tests/mod.rs @@ -53,10 +53,12 @@ async fn stellar_overlay_should_receive_scp_messages() { let scps_vec_clone = scps_vec.clone(); tokio::spawn(async move { let mut ov_conn_locked = ov_conn.lock().await; - while let Ok(Some(msg)) = ov_conn_locked.listen().await { - scps_vec_clone.lock().await.push(msg); - sender.send(()).unwrap(); - break; + loop { + if let Some(msg) = ov_conn_locked.listen().await.expect("should return a message") { + scps_vec_clone.lock().await.push(msg); + sender.send(()).unwrap(); + break; + } } ov_conn_locked.stop(); @@ -97,29 +99,31 @@ async fn stellar_overlay_should_receive_tx_set() { let mut ov_conn_locked = ov_conn.lock().await; - while let Ok(Some(msg)) = ov_conn_locked.listen().await { - match msg { - StellarMessage::ScpMessage(msg) => { - if let ScpStatementPledges::ScpStExternalize(stmt) = &msg.statement.pledges { - let tx_set_hash = get_tx_set_hash(stmt); - tx_set_hashes_clone.lock().await.push(tx_set_hash.clone()); - ov_conn_locked - .send_to_node(StellarMessage::GetTxSet(tx_set_hash)) - .await - .unwrap(); - } - }, - StellarMessage::TxSet(set) => { - let tx_set_hash = set.into_hash().expect("should return a hash"); - actual_tx_set_hashes_clone.lock().await.push(tx_set_hash); - break; - }, - StellarMessage::GeneralizedTxSet(set) => { - let tx_set_hash = set.into_hash().expect("should return a hash"); - actual_tx_set_hashes_clone.lock().await.push(tx_set_hash); - break; - }, - _ => {}, + loop { + if let Ok(Some(msg)) = ov_conn_locked.listen().await { + match msg { + StellarMessage::ScpMessage(msg) => { + if let ScpStatementPledges::ScpStExternalize(stmt) = &msg.statement.pledges { + let tx_set_hash = get_tx_set_hash(stmt); + tx_set_hashes_clone.lock().await.push(tx_set_hash.clone()); + ov_conn_locked + .send_to_node(StellarMessage::GetTxSet(tx_set_hash)) + .await + .unwrap(); + } + }, + StellarMessage::TxSet(set) => { + let tx_set_hash = set.into_hash().expect("should return a hash"); + actual_tx_set_hashes_clone.lock().await.push(tx_set_hash); + break; + }, + StellarMessage::GeneralizedTxSet(set) => { + let tx_set_hash = set.into_hash().expect("should return a hash"); + actual_tx_set_hashes_clone.lock().await.push(tx_set_hash); + break; + }, + _ => {}, + } } } From 23a1f9b63ea3756edd5a81b4a683639f9c30dc11 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Fri, 4 Oct 2024 14:53:03 +0800 Subject: [PATCH 46/63] remove 2nd declaration of agent --- clients/vault/tests/vault_integration_tests.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/clients/vault/tests/vault_integration_tests.rs b/clients/vault/tests/vault_integration_tests.rs index 37df02314..b9919f21c 100644 --- a/clients/vault/tests/vault_integration_tests.rs +++ b/clients/vault/tests/vault_integration_tests.rs @@ -621,7 +621,7 @@ async fn test_issue_execution_succeeds_from_archive_on_testnet() { async fn test_issue_execution_succeeds_from_archive_on_network(is_public_network: bool) { test_with_vault( is_public_network, - |client, _vault_wallet, user_wallet, _oracle_agent, vault_id, vault_provider| async move { + |client, _vault_wallet, user_wallet, oracle_agent, vault_id, vault_provider| async move { let user_provider = setup_provider(client.clone(), AccountKeyring::Dave).await; let public_key = default_vault_stellar_address_as_binary(is_public_network); @@ -673,15 +673,6 @@ async fn test_issue_execution_succeeds_from_archive_on_network(is_public_network // We sleep here in order to wait for the fallback to the archive to be necessary sleep(Duration::from_secs(5 * 60)).await; - let shutdown_tx = ShutdownSender::new(); - let stellar_config = random_stellar_relay_config(is_public_network); - - let vault_stellar_secret = get_source_secret_key_from_env(is_public_network); - // Create new oracle agent with the same configuration as the previous one - let oracle_agent = - start_oracle_agent(stellar_config.clone(), vault_stellar_secret, shutdown_tx).await; - let oracle_agent = Arc::new(oracle_agent); - // Loop pending proofs until it is ready let proof = oracle_agent .read() From 524342efd2b9a4d3a33e2ecbf8d679dbc547c883 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Fri, 4 Oct 2024 15:45:09 +0800 Subject: [PATCH 47/63] https://github.com/pendulum-chain/spacewalk/actions/runs/11175397072/job/31066682184?pr=545 --- clients/vault/tests/vault_integration_tests.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/clients/vault/tests/vault_integration_tests.rs b/clients/vault/tests/vault_integration_tests.rs index b9919f21c..116a45331 100644 --- a/clients/vault/tests/vault_integration_tests.rs +++ b/clients/vault/tests/vault_integration_tests.rs @@ -24,8 +24,6 @@ mod helper; use helper::*; use primitives::DecimalsLookup; use subxt::utils::AccountId32 as AccountId; -use vault::oracle::{random_stellar_relay_config, start_oracle_agent}; -use wallet::keys::get_source_secret_key_from_env; #[tokio::test(flavor = "multi_thread")] #[serial] From 9b9dfd3ef1de8eaf3daf7dfbbb85b0a7e842955d Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Mon, 7 Oct 2024 22:02:43 +0800 Subject: [PATCH 48/63] fix timeout issue https://github.com/pendulum-chain/spacewalk/actions/runs/11176052005/job/31071234041?pr=545#step:4:5765 --- clients/vault/src/oracle/agent.rs | 6 +- .../src/oracle/collector/proof_builder.rs | 107 +++++++++--------- .../vault/tests/vault_integration_tests.rs | 5 +- 3 files changed, 62 insertions(+), 56 deletions(-) diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index 84dd53c7e..d65dc30a3 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -42,8 +42,8 @@ impl OracleAgent { } #[cfg(any(test, feature = "integration"))] - pub fn is_stellar_running(&self) -> bool { - self.message_sender.is_some() + pub async fn is_stellar_running(&self) -> bool { + self.message_sender.is_some() && self.collector.read().await.last_slot_index() > 0 } } @@ -180,7 +180,7 @@ pub async fn start_oracle_agent( tokio::spawn(listen_for_stellar_messages(cfg, oracle_agent.clone(), secret, shutdown_sender)); - while !oracle_agent.read().await.is_stellar_running() { + while !oracle_agent.read().await.is_stellar_running().await { sleep(Duration::from_millis(500)).await; } diff --git a/clients/vault/src/oracle/collector/proof_builder.rs b/clients/vault/src/oracle/collector/proof_builder.rs index 335cd0d92..baf6e0cac 100644 --- a/clients/vault/src/oracle/collector/proof_builder.rs +++ b/clients/vault/src/oracle/collector/proof_builder.rs @@ -237,61 +237,66 @@ impl ScpMessageCollector { } }); - if let Some(i) = value { - if let ScpHistoryEntry::V0(scp_entry_v0) = i { - let slot_scp_envelopes = scp_entry_v0.clone().ledger_messages.messages; - let vec_scp = slot_scp_envelopes.get_vec().clone(); - - // Filter out any envelopes that are not externalize or confirm statements - let relevant_envelopes = vec_scp - .into_iter() - .filter(|scp| match scp.statement.pledges { - ScpStatementPledges::ScpStExternalize(_) | - ScpStatementPledges::ScpStConfirm(_) => true, - _ => false, - }) - .collect::>(); - - let externalized_envelopes_count = relevant_envelopes - .iter() - .filter(|scp| match scp.statement.pledges { - ScpStatementPledges::ScpStExternalize(_) => true, - _ => false, - }) - .count(); - - // Ensure that at least one envelope is externalized - if externalized_envelopes_count == 0 { - tracing::error!( + let Some(ScpHistoryEntry::V0(scp_entry_v0)) = value else { + tracing::warn!("get_envelopes_from_horizon_archive(): Could not get ScpHistory entry from archive {archive_url} for slot {slot}"); + continue; + }; + + let slot_scp_envelopes = scp_entry_v0.clone().ledger_messages.messages; + let vec_scp = slot_scp_envelopes.get_vec().clone(); + + // Filter out any envelopes that are not externalize or confirm statements + let mut relevant_envelopes = vec_scp + .into_iter() + .filter(|scp| match scp.statement.pledges { + ScpStatementPledges::ScpStExternalize(_) | + ScpStatementPledges::ScpStConfirm(_) => true, + _ => false, + }) + .collect::>(); + + let externalized_envelopes_count = relevant_envelopes + .iter() + .filter(|scp| match scp.statement.pledges { + ScpStatementPledges::ScpStExternalize(_) => true, + _ => false, + }) + .count(); + + // Ensure that at least one envelope is externalized + if externalized_envelopes_count == 0 { + tracing::error!( "get_envelopes_from_horizon_archive(): The contained archive entry fetched from {} for slot {slot} is invalid because it does not contain any externalized envelopes.", scp_archive_storage.0 ); - // remove the file since it's invalid. - scp_archive_storage.remove_file(slot); - continue; - } - - let mut envelopes_map = envelopes_map_arc.write(); - let mut from_archive_map = env_from_archive_map.write(); - - if envelopes_map.get(&slot).is_none() { - tracing::info!( - "get_envelopes_from_horizon_archive(): Adding {} archived SCP envelopes for slot {slot} to envelopes map. {} are externalized", - relevant_envelopes.len(), - externalized_envelopes_count - ); - envelopes_map.insert(slot, relevant_envelopes); - // indicates that the data was taken from the archive - from_archive_map.insert(slot, ()); - - // remove the archive file after successfully retrieving envelopes - scp_archive_storage.remove_file(slot); - break; - } - } - } else { - tracing::warn!("get_envelopes_from_horizon_archive(): Could not get ScpHistory entry from archive {archive_url} for slot {slot}"); + // remove the file since it's invalid. + scp_archive_storage.remove_file(slot); + continue; + } + + let mut envelopes_map = envelopes_map_arc.write(); + let mut from_archive_map = env_from_archive_map.write(); + + tracing::info!( + "get_envelopes_from_horizon_archive(): Adding {} archived SCP envelopes for slot {slot} to envelopes map. {} are externalized", + relevant_envelopes.len(), + externalized_envelopes_count + ); + let mut envs = envelopes_map.get(&slot).map(|envs| envs.clone()).unwrap_or(vec![]); + + if envs.len() > 0 { + tracing::info!("get_envelopes_from_horizon_archive(): {} envelopes already exist for slot {slot}", envs.len()); } + + relevant_envelopes.append(&mut envs); + envelopes_map.insert(slot, relevant_envelopes); + + // indicates that the data was taken from the archive + from_archive_map.insert(slot, ()); + + // remove the archive file after successfully retrieving envelopes + scp_archive_storage.remove_file(slot); + break; } } } diff --git a/clients/vault/tests/vault_integration_tests.rs b/clients/vault/tests/vault_integration_tests.rs index 116a45331..918832ebc 100644 --- a/clients/vault/tests/vault_integration_tests.rs +++ b/clients/vault/tests/vault_integration_tests.rs @@ -69,8 +69,8 @@ async fn test_redeem_succeeds_on_network(is_public_network: bool) { let vault_id_manager = VaultIdManager::from_map(vault_provider.clone(), vault_wallet.clone(), vault_ids); - // We issue 1/1000 unit - let issue_amount = DecimalsLookupImpl::one(CurrencyId::Native) / 1000; + // We issue 1 (spacewalk-chain) unit + let issue_amount = DecimalsLookupImpl::one(CurrencyId::Native) / 100; let vault_collateral = get_required_vault_collateral_for_issue( &vault_provider, issue_amount, @@ -605,6 +605,7 @@ async fn test_issue_cancel_succeeds() { #[tokio::test(flavor = "multi_thread")] #[serial] async fn test_issue_execution_succeeds_from_archive_on_mainnet() { + env_logger::init(); let is_public_network = true; test_issue_execution_succeeds_from_archive_on_network(is_public_network).await; } From 7b9dddad33a1fcc23af5a2e6ed1b458a993f2daa Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:44:12 +0800 Subject: [PATCH 49/63] remove env_logger --- clients/vault/src/oracle/collector/proof_builder.rs | 1 - clients/vault/tests/vault_integration_tests.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/clients/vault/src/oracle/collector/proof_builder.rs b/clients/vault/src/oracle/collector/proof_builder.rs index baf6e0cac..664be6b1d 100644 --- a/clients/vault/src/oracle/collector/proof_builder.rs +++ b/clients/vault/src/oracle/collector/proof_builder.rs @@ -437,7 +437,6 @@ mod test { #[tokio::test] async fn test_get_envelopes_from_horizon_archive() { - env_logger::init(); let collector = collector(false); assert_eq!(collector.envelopes_map_len(), 0); diff --git a/clients/vault/tests/vault_integration_tests.rs b/clients/vault/tests/vault_integration_tests.rs index 918832ebc..54e7d2084 100644 --- a/clients/vault/tests/vault_integration_tests.rs +++ b/clients/vault/tests/vault_integration_tests.rs @@ -605,7 +605,6 @@ async fn test_issue_cancel_succeeds() { #[tokio::test(flavor = "multi_thread")] #[serial] async fn test_issue_execution_succeeds_from_archive_on_mainnet() { - env_logger::init(); let is_public_network = true; test_issue_execution_succeeds_from_archive_on_network(is_public_network).await; } From 6e3f7c320dfc8528c35b1846ee1afed197713a63 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 8 Oct 2024 18:59:34 +0800 Subject: [PATCH 50/63] remove env_logger; move console-subscribe to dev-dependencies; remove useless script --- Cargo.lock | 1 - clients/stellar-relay-lib/Cargo.toml | 3 +-- clients/stellar-relay-lib/examples/connect.rs | 5 ++++- scripts/cmd-list | 22 ------------------- 4 files changed, 5 insertions(+), 26 deletions(-) delete mode 100755 scripts/cmd-list diff --git a/Cargo.lock b/Cargo.lock index b346fea6c..10dace292 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11577,7 +11577,6 @@ dependencies = [ "async-std", "base64 0.13.1", "console-subscriber 0.3.0", - "env_logger 0.9.3", "err-derive", "hex", "hmac 0.12.1", diff --git a/clients/stellar-relay-lib/Cargo.toml b/clients/stellar-relay-lib/Cargo.toml index e3add0dd6..c483b22c9 100644 --- a/clients/stellar-relay-lib/Cargo.toml +++ b/clients/stellar-relay-lib/Cargo.toml @@ -10,13 +10,12 @@ name = "stellar_relay_lib" path = "src/lib.rs" [dev-dependencies] -env_logger = "0.9.0" ntest = "0.9.0" serial_test = "0.9.0" wallet = { path = "../wallet", features = ["testing-utils"] } +console-subscriber = { version = "0.3.0" } [dependencies] -console-subscriber = { version = "0.3.0" } hex = "0.4.3" tracing = { version = "0.1", features = ["log"] } diff --git a/clients/stellar-relay-lib/examples/connect.rs b/clients/stellar-relay-lib/examples/connect.rs index 84f2d15f4..ed2a489be 100644 --- a/clients/stellar-relay-lib/examples/connect.rs +++ b/clients/stellar-relay-lib/examples/connect.rs @@ -8,7 +8,6 @@ use wallet::keys::get_source_secret_key_from_env; #[tokio::main] async fn main() -> Result<(), Box> { - env_logger::init(); console_subscriber::init(); let args: Vec = std::env::args().collect(); @@ -28,6 +27,10 @@ async fn main() -> Result<(), Box> { loop { match overlay_connection.listen().await { Ok(Some(msg)) => match msg { + StellarMessage::Hello(_) => { + tracing::info!("received Hello message"); + }, + StellarMessage::ScpMessage(msg) => { let node_id = msg.statement.node_id.to_encoding(); let node_id = base64::encode(&node_id); diff --git a/scripts/cmd-list b/scripts/cmd-list deleted file mode 100755 index f849d3215..000000000 --- a/scripts/cmd-list +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - - -echo "save to file" -if test -f temp.txt; then - rm temp.txt -fi - -cargo t -p &> temp.txt - -result=$(cat temp.txt) -echo "hello it's me" - -var=$(echo $result | grep -ob "workspace members") -pos="${var%:*}" -echo "the pos: " $pos -pos2=$(($pos + 20)) -wee=$(echo $result | cut -c$pos2-) - -IFS=' ' read -r -a array <<< "$wee" - -echo "${array[5]}" \ No newline at end of file From 71222e1889a9f4e5d7da2954948adb6030967d41 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 8 Oct 2024 19:34:30 +0800 Subject: [PATCH 51/63] reduce changes --- clients/stellar-relay-lib/Cargo.toml | 1 - clients/stellar-relay-lib/src/overlay.rs | 1 - clients/vault/src/cancellation.rs | 1 - clients/vault/src/oracle/agent.rs | 4 ++-- clients/vault/src/oracle/collector/collector.rs | 3 ++- clients/vault/src/oracle/collector/handler.rs | 2 +- clients/vault/src/replace.rs | 1 - clients/wallet/src/horizon/horizon.rs | 1 - 8 files changed, 5 insertions(+), 9 deletions(-) diff --git a/clients/stellar-relay-lib/Cargo.toml b/clients/stellar-relay-lib/Cargo.toml index c483b22c9..f223d30cb 100644 --- a/clients/stellar-relay-lib/Cargo.toml +++ b/clients/stellar-relay-lib/Cargo.toml @@ -16,7 +16,6 @@ wallet = { path = "../wallet", features = ["testing-utils"] } console-subscriber = { version = "0.3.0" } [dependencies] - hex = "0.4.3" tracing = { version = "0.1", features = ["log"] } diff --git a/clients/stellar-relay-lib/src/overlay.rs b/clients/stellar-relay-lib/src/overlay.rs index d011bf716..989d9c16d 100644 --- a/clients/stellar-relay-lib/src/overlay.rs +++ b/clients/stellar-relay-lib/src/overlay.rs @@ -93,7 +93,6 @@ impl StellarOverlayConnection { impl Drop for StellarOverlayConnection { fn drop(&mut self) { - debug!("drop(): shutting down StellarOverlayConnection"); self.stop(); } } diff --git a/clients/vault/src/cancellation.rs b/clients/vault/src/cancellation.rs index 64f829226..246922b81 100644 --- a/clients/vault/src/cancellation.rs +++ b/clients/vault/src/cancellation.rs @@ -204,7 +204,6 @@ impl Cancel mut self, mut event_listener: Receiver, ) -> Result<(), RuntimeError> { - tracing::info!("handle_cancellation(): started"); let mut list_state = ListState::Invalid; let mut active_requests: Vec = vec![]; diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index d65dc30a3..58fbfc5ec 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -13,7 +13,7 @@ use stellar_relay_lib::{ use crate::{ oracle::{ - collector::ScpMessageCollector, errors::Error, get_random_secret_key, + collector::ScpMessageCollector, errors::Error, types::StellarMessageSender, AddTxSet, Proof, }, ArcRwLock, @@ -176,7 +176,7 @@ pub async fn start_oracle_agent( ) -> ArcRwLock { let oracle_agent = Arc::new(RwLock::new(OracleAgent::new(&cfg, shutdown_sender.clone()))); - let secret = get_random_secret_key(); + let secret = crate::oracle::get_random_secret_key(); tokio::spawn(listen_for_stellar_messages(cfg, oracle_agent.clone(), secret, shutdown_sender)); diff --git a/clients/vault/src/oracle/collector/collector.rs b/clients/vault/src/oracle/collector/collector.rs index 507554125..b8b57bb66 100644 --- a/clients/vault/src/oracle/collector/collector.rs +++ b/clients/vault/src/oracle/collector/collector.rs @@ -69,6 +69,7 @@ impl ScpMessageCollector { stellar_history_archive_urls, } } + pub fn envelopes_map_len(&self) -> usize { self.envelopes_map.read().len() } @@ -120,7 +121,7 @@ impl ScpMessageCollector { self.txset_and_slot_map.read().get_txset_hash_by_slot(slot).cloned() } - pub fn last_slot_index(&self) -> u64 { + pub(crate) fn last_slot_index(&self) -> u64 { self.last_slot_index } } diff --git a/clients/vault/src/oracle/collector/handler.rs b/clients/vault/src/oracle/collector/handler.rs index 61fd6be03..4225b59e1 100644 --- a/clients/vault/src/oracle/collector/handler.rs +++ b/clients/vault/src/oracle/collector/handler.rs @@ -25,7 +25,7 @@ impl ScpMessageCollector { // we are only interested with `ScpStExternalize`. Other messages are ignored. if let ScpStatementPledges::ScpStExternalize(stmt) = &env.statement.pledges { - tracing::debug!( + tracing::trace!( "Handling Incoming ScpEnvelopes for slot {slot}: SCPStExternalize found: {}", to_base64_xdr_string(stmt) ); diff --git a/clients/vault/src/replace.rs b/clients/vault/src/replace.rs index 4dced56cc..3dc96703a 100644 --- a/clients/vault/src/replace.rs +++ b/clients/vault/src/replace.rs @@ -28,7 +28,6 @@ pub async fn listen_for_accept_replace( payment_margin: Duration, oracle_agent: ArcRwLock, ) -> Result<(), ServiceError> { - tracing::info!("listen_for_accept_replace(): started"); let parachain_rpc = ¶chain_rpc; let vault_id_manager = &vault_id_manager; let shutdown_tx = &shutdown_tx; diff --git a/clients/wallet/src/horizon/horizon.rs b/clients/wallet/src/horizon/horizon.rs index f2adf2719..5e54de558 100644 --- a/clients/wallet/src/horizon/horizon.rs +++ b/clients/wallet/src/horizon/horizon.rs @@ -320,7 +320,6 @@ where U: Clone + IsEmptyExt, Filter: FilterWith + Clone, { - tracing::info!("listen_for_new_transactions(): started"); let horizon_client = reqwest::Client::new(); let mut fetcher = HorizonFetcher::new(horizon_client, vault_account_public_key, is_public_network); From 458ba4fb7fff7318de77ec99f9ffeb717a9effbb Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 8 Oct 2024 20:52:04 +0800 Subject: [PATCH 52/63] cargo fmt and clippy --- clients/stellar-relay-lib/src/overlay.rs | 2 +- clients/vault/src/oracle/agent.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/clients/stellar-relay-lib/src/overlay.rs b/clients/stellar-relay-lib/src/overlay.rs index 989d9c16d..7de9f5226 100644 --- a/clients/stellar-relay-lib/src/overlay.rs +++ b/clients/stellar-relay-lib/src/overlay.rs @@ -3,7 +3,7 @@ use tokio::sync::{ mpsc, mpsc::{error::SendError, Sender}, }; -use tracing::{debug, error, info}; +use tracing::{error, info}; use crate::{ connection::{poll_messages_from_stellar, ConnectionInfo, Connector}, diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index 58fbfc5ec..0b16d72a6 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -13,8 +13,7 @@ use stellar_relay_lib::{ use crate::{ oracle::{ - collector::ScpMessageCollector, errors::Error, - types::StellarMessageSender, AddTxSet, Proof, + collector::ScpMessageCollector, errors::Error, types::StellarMessageSender, AddTxSet, Proof, }, ArcRwLock, }; From 3bd0100cff44cb4b08a4783e1602edced9d1ec15 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 8 Oct 2024 23:09:33 +0800 Subject: [PATCH 53/63] https://github.com/pendulum-chain/spacewalk/pull/545#discussion_r1791591783 --- clients/vault/src/oracle/collector/proof_builder.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/clients/vault/src/oracle/collector/proof_builder.rs b/clients/vault/src/oracle/collector/proof_builder.rs index 664be6b1d..e23a53c5f 100644 --- a/clients/vault/src/oracle/collector/proof_builder.rs +++ b/clients/vault/src/oracle/collector/proof_builder.rs @@ -246,7 +246,7 @@ impl ScpMessageCollector { let vec_scp = slot_scp_envelopes.get_vec().clone(); // Filter out any envelopes that are not externalize or confirm statements - let mut relevant_envelopes = vec_scp + let relevant_envelopes = vec_scp .into_iter() .filter(|scp| match scp.statement.pledges { ScpStatementPledges::ScpStExternalize(_) | @@ -282,13 +282,7 @@ impl ScpMessageCollector { relevant_envelopes.len(), externalized_envelopes_count ); - let mut envs = envelopes_map.get(&slot).map(|envs| envs.clone()).unwrap_or(vec![]); - if envs.len() > 0 { - tracing::info!("get_envelopes_from_horizon_archive(): {} envelopes already exist for slot {slot}", envs.len()); - } - - relevant_envelopes.append(&mut envs); envelopes_map.insert(slot, relevant_envelopes); // indicates that the data was taken from the archive From e557b44acb4f0ae459629f6b4364c1d5582fbb87 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 8 Oct 2024 23:22:41 +0800 Subject: [PATCH 54/63] remove unnecessary dependencies --- Cargo.lock | 4 ---- clients/wallet/Cargo.toml | 4 ---- 2 files changed, 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 10dace292..08b65999e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13001,11 +13001,7 @@ dependencies = [ "spacewalk-primitives", "thiserror", "tokio", - "tokio-metrics", - "tokio-stream", "tracing", - "tracing-futures", - "tracing-subscriber 0.2.25", ] [[package]] diff --git a/clients/wallet/Cargo.toml b/clients/wallet/Cargo.toml index 23e17515b..3d4f835c7 100644 --- a/clients/wallet/Cargo.toml +++ b/clients/wallet/Cargo.toml @@ -19,11 +19,7 @@ serde = "1.0.136" serde_json = { version = '1.0.45', default-features = false, features = ['alloc'] } thiserror = "1.0" tokio = { version = "1.37", features = ["full", "tracing"] } -tokio-metrics = { version = "0.1.0", default-features = false } -tokio-stream = { version = "0.1.9", features = ["sync"] } tracing = { version = "0.1", features = ["log"] } -tracing-futures = { version = "0.2.5" } -tracing-subscriber = { version = "0.2.12", features = ["registry", "env-filter", "fmt"] } dotenv = "0.15.0" primitives = { package = "spacewalk-primitives", path = "../../primitives"} From 9cad8e4893182ab90cd2483d121df98f048eb402 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Wed, 9 Oct 2024 13:55:37 +0800 Subject: [PATCH 55/63] fix "the `set-output` command is deprecated and will be disabled soon. Please upgrade to using Environment Files." --- .github/actions/prerequisite-nightly/action.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/actions/prerequisite-nightly/action.yml b/.github/actions/prerequisite-nightly/action.yml index dd1985141..d6cf3b7a3 100644 --- a/.github/actions/prerequisite-nightly/action.yml +++ b/.github/actions/prerequisite-nightly/action.yml @@ -18,6 +18,8 @@ runs: token: ${{ inputs.token }} - name: Install Rust Nightly - uses: ./.github/actions/install-rust-nightly + uses: dtolnay/rust-toolchain@nightly with: - version: ${{ inputs.version }} \ No newline at end of file + toolchain: ${{ inputs.version }} + components: rustfmt, clippy + target: wasm32-unknown-unknown From e7f3e263d98f6e88f815b3659590b7c18ac50ace Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Fri, 11 Oct 2024 15:00:52 +0800 Subject: [PATCH 56/63] https://github.com/pendulum-chain/spacewalk/pull/545#discussion_r1795738055 --- clients/vault/src/oracle/agent.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index 0b16d72a6..e709bd012 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -19,6 +19,9 @@ use crate::{ }; use wallet::Slot; +/// The interval to check if we are still receiving messages from Stellar Relay +const STELLAR_RELAY_HEALTH_CHECK_IN_SECS:u64 = 600; + pub struct OracleAgent { pub collector: Arc>, pub is_public_network: bool, @@ -109,9 +112,10 @@ pub async fn listen_for_stellar_messages( oracle_agent.write().await.message_sender = Some(sender.clone()); }; - // log a new message received, every 1 minute. - let interval = Duration::from_secs(60); - let mut next_time = Instant::now() + interval; + // log a new message received. + let health_check_interval = Duration::from_secs(STELLAR_RELAY_HEALTH_CHECK_IN_SECS); + + let mut next_time = Instant::now() + health_check_interval; let mut is_proof_building_ready: Option = Some(false); loop { let collector = oracle_agent.read().await.collector.clone(); @@ -134,7 +138,7 @@ pub async fn listen_for_stellar_messages( let msg_as_str = to_base64_xdr_string(&msg); if Instant::now() >= next_time { tracing::info!("listen_for_stellar_messages(): health check: received message from Stellar"); - next_time += interval; + next_time += health_check_interval; } if let Some(true) = is_proof_building_ready { @@ -188,6 +192,9 @@ pub async fn start_oracle_agent( } impl OracleAgent { + // the interval for every build_proof retry + const BUILD_PROOF_INTERVAL:u64 = 10; + /// This method returns the proof for a given slot or an error if the proof cannot be provided. /// The agent will try every possible way to get the proof before returning an error. pub async fn get_proof(&self, slot: Slot) -> Result { @@ -212,8 +219,8 @@ impl OracleAgent { match collector.build_proof(slot, &stellar_sender).await { None => { drop(collector); - // give 10 seconds interval for every retry - sleep(Duration::from_secs(10)).await; + // give enough interval for every retry + sleep(Duration::from_secs(OracleAgent::BUILD_PROOF_INTERVAL)).await; continue }, Some(proof) => { From 0aa969e4342ad02d19541fd97543d53eb21b568a Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Tue, 15 Oct 2024 23:49:39 +0800 Subject: [PATCH 57/63] address major comments --- clients/runtime/Cargo.toml | 1 - clients/runtime/src/types.rs | 15 +- .../connection/connector/message_sender.rs | 15 +- .../src/connection/helper.rs | 5 - clients/vault/src/issue.rs | 10 +- clients/vault/src/oracle/agent.rs | 192 ++++++++---------- .../vault/src/oracle/collector/collector.rs | 4 +- clients/vault/src/oracle/collector/handler.rs | 14 +- .../src/oracle/collector/proof_builder.rs | 6 +- clients/vault/src/redeem.rs | 6 +- clients/vault/src/replace.rs | 6 +- clients/vault/src/requests/execution.rs | 18 +- clients/vault/src/requests/helper.rs | 6 +- clients/vault/src/requests/structs.rs | 6 +- clients/vault/src/system.rs | 32 +-- clients/vault/tests/helper/helper.rs | 11 +- clients/vault/tests/helper/mod.rs | 2 +- .../vault/tests/vault_integration_tests.rs | 18 +- 18 files changed, 165 insertions(+), 202 deletions(-) diff --git a/clients/runtime/Cargo.toml b/clients/runtime/Cargo.toml index c5391eb4f..5cc6506ab 100644 --- a/clients/runtime/Cargo.toml +++ b/clients/runtime/Cargo.toml @@ -64,7 +64,6 @@ testchain-runtime = { package = "spacewalk-runtime-standalone-testnet", path = " mainnet-runtime = { package = "spacewalk-runtime-standalone-mainnet", path = "../../testchain/runtime/mainnet", optional = true } # Substrate Stellar Dependencies -substrate-stellar-sdk = { git = "https://github.com/pendulum-chain/substrate-stellar-sdk", branch = "polkadot-v1.1.0" } wallet = { path = "../wallet" } diff --git a/clients/runtime/src/types.rs b/clients/runtime/src/types.rs index 966609cb9..b9308e30f 100644 --- a/clients/runtime/src/types.rs +++ b/clients/runtime/src/types.rs @@ -6,6 +6,7 @@ pub use subxt::ext::sp_core::sr25519::Pair as KeyPair; use subxt::utils::Static; use crate::{metadata, Config, SpacewalkRuntime, SS58_PREFIX}; +use primitives::stellar::PublicKey; pub type AccountId = subxt::utils::AccountId32; pub type Address = subxt::ext::sp_runtime::MultiAddress; @@ -17,8 +18,6 @@ pub type H256 = subxt::ext::sp_core::H256; pub type SpacewalkSigner = subxt::tx::PairSigner; pub type FixedU128 = sp_arithmetic::FixedU128; -pub use substrate_stellar_sdk as stellar; - pub type IssueId = H256; pub type StellarPublicKeyRaw = [u8; 32]; @@ -139,19 +138,15 @@ pub mod currency_id { Asset::AlphaNum4 { code, issuer } => Ok(format!( "Stellar({:?}:{:?})", from_utf8(code).unwrap_or_default(), - from_utf8( - stellar::PublicKey::from_binary(*issuer).to_encoding().as_slice() - ) - .unwrap_or_default() + from_utf8(PublicKey::from_binary(*issuer).to_encoding().as_slice()) + .unwrap_or_default() ) .replace('\"', "")), Asset::AlphaNum12 { code, issuer } => Ok(format!( "Stellar({:?}:{:?})", from_utf8(code).unwrap_or_default(), - from_utf8( - stellar::PublicKey::from_binary(*issuer).to_encoding().as_slice() - ) - .unwrap_or_default() + from_utf8(PublicKey::from_binary(*issuer).to_encoding().as_slice()) + .unwrap_or_default() ) .replace('\"', "")), }, diff --git a/clients/stellar-relay-lib/src/connection/connector/message_sender.rs b/clients/stellar-relay-lib/src/connection/connector/message_sender.rs index 70cc1f4cc..8b676342f 100644 --- a/clients/stellar-relay-lib/src/connection/connector/message_sender.rs +++ b/clients/stellar-relay-lib/src/connection/connector/message_sender.rs @@ -1,14 +1,13 @@ use async_std::io::WriteExt; use std::time::Duration; -use substrate_stellar_sdk::types::{MessageType, StellarMessage}; +use substrate_stellar_sdk::{ + types::{MessageType, StellarMessage}, + StellarTypeToBase64String, +}; use tokio::time::timeout; use tracing::debug; -use crate::connection::{ - handshake::create_auth_message, - helper::{time_now, to_base64_xdr_string}, - Connector, Error, -}; +use crate::connection::{handshake::create_auth_message, helper::time_now, Connector, Error}; impl Connector { pub async fn send_to_node(&mut self, msg: StellarMessage) -> Result<(), Error> { @@ -28,7 +27,7 @@ impl Connector { pub async fn send_hello_message(&mut self) -> Result<(), Error> { let msg = self.create_hello_message(time_now())?; - debug!("send_hello_message(): Sending Hello Message: {}", to_base64_xdr_string(&msg)); + debug!("send_hello_message(): Sending Hello Message: {}", msg.as_base64_encoded_string()); self.send_to_node(msg).await } @@ -38,7 +37,7 @@ impl Connector { local_overlay_version: u32, ) -> Result<(), Error> { let msg = create_auth_message(local_overlay_version); - debug!("send_auth_message(): Sending Auth Message: {}", to_base64_xdr_string(&msg)); + debug!("send_auth_message(): Sending Auth Message: {}", msg.as_base64_encoded_string()); return self.send_to_node(create_auth_message(local_overlay_version)).await; } diff --git a/clients/stellar-relay-lib/src/connection/helper.rs b/clients/stellar-relay-lib/src/connection/helper.rs index 6c049cd0f..0bffe0f6f 100644 --- a/clients/stellar-relay-lib/src/connection/helper.rs +++ b/clients/stellar-relay-lib/src/connection/helper.rs @@ -35,8 +35,3 @@ pub fn error_to_string(e: Error) -> String { format!("Error{{ code:{:?} message:{msg} }}", e.code) } - -pub fn to_base64_xdr_string(msg: &T) -> String { - let xdr = msg.to_base64_xdr(); - String::from_utf8(xdr.clone()).unwrap_or(format!("{:?}", xdr)) -} diff --git a/clients/vault/src/issue.rs b/clients/vault/src/issue.rs index f8b8f3f1c..e1c445aa3 100644 --- a/clients/vault/src/issue.rs +++ b/clients/vault/src/issue.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, time::Duration}; +use std::{collections::HashMap, sync::Arc, time::Duration}; use futures::{channel::mpsc::Sender, future, SinkExt}; use sp_runtime::traits::StaticLookup; @@ -26,7 +26,7 @@ pub(crate) async fn initialize_issue_set( issue_set: &ArcRwLock, memos_to_issue_ids: &ArcRwLock, ) -> Result<(), Error> { - tracing::info!("initialize_issue_set(): started"); + tracing::debug!("initialize_issue_set(): started"); let (mut issue_set, mut memos_to_issue_ids, requests) = future::join3( issue_set.write(), memos_to_issue_ids.write(), @@ -252,7 +252,7 @@ async fn cleanup_ledger_env_map( /// * `issues` - a map of all issue requests pub async fn process_issues_requests( parachain_rpc: SpacewalkParachain, - oracle_agent: ArcRwLock, + oracle_agent: Arc, ledger_env_map: ArcRwLock, issues: ArcRwLock, memos_to_issue_ids: ArcRwLock, @@ -308,13 +308,13 @@ pub async fn execute_issue( tx_env: TransactionEnvelope, issues: ArcRwLock, memos_to_issue_ids: ArcRwLock, - oracle_agent: ArcRwLock, + oracle_agent: Arc, slot: Slot, sender: tokio::sync::oneshot::Sender, ) { // Get the proof of the given slot let proof = - match oracle_agent.read().await.get_proof(slot).await { + match oracle_agent.get_proof(slot).await { Ok(proof) => proof, Err(e) => { tracing::error!("Could not execute Issue for slot {slot} due to error with proof building: {e:?}"); diff --git a/clients/vault/src/oracle/agent.rs b/clients/vault/src/oracle/agent.rs index e709bd012..366086f78 100644 --- a/clients/vault/src/oracle/agent.rs +++ b/clients/vault/src/oracle/agent.rs @@ -1,5 +1,6 @@ use std::{sync::Arc, time::Duration}; +use primitives::stellar::StellarTypeToBase64String; use tokio::{ sync::RwLock, time::{sleep, timeout, Instant}, @@ -7,8 +8,8 @@ use tokio::{ use runtime::ShutdownSender; use stellar_relay_lib::{ - connect_to_stellar_overlay_network, helper::to_base64_xdr_string, sdk::types::StellarMessage, - StellarOverlayConfig, + connect_to_stellar_overlay_network, sdk::types::StellarMessage, StellarOverlayConfig, + StellarOverlayConnection, }; use crate::{ @@ -20,19 +21,27 @@ use crate::{ use wallet::Slot; /// The interval to check if we are still receiving messages from Stellar Relay -const STELLAR_RELAY_HEALTH_CHECK_IN_SECS:u64 = 600; +const STELLAR_RELAY_HEALTH_CHECK_IN_SECS: u64 = 600; pub struct OracleAgent { - pub collector: Arc>, + pub collector: ArcRwLock, pub is_public_network: bool, /// sends message directly to Stellar Node - message_sender: Option, + message_sender: StellarMessageSender, + overlay_conn: ArcRwLock, /// sends an entire Vault shutdown shutdown_sender: ShutdownSender, } impl OracleAgent { - pub fn new(config: &StellarOverlayConfig, shutdown_sender: ShutdownSender) -> Self { + // the interval for every build_proof retry + const BUILD_PROOF_INTERVAL: u64 = 10; + + pub async fn new( + config: &StellarOverlayConfig, + secret_key_as_string: String, + shutdown_sender: ShutdownSender, + ) -> Result { let is_public_network = config.is_public_network(); let collector = Arc::new(RwLock::new(ScpMessageCollector::new( @@ -40,12 +49,60 @@ impl OracleAgent { config.stellar_history_archive_urls(), ))); - OracleAgent { collector, is_public_network, message_sender: None, shutdown_sender } + let overlay_conn = + connect_to_stellar_overlay_network(config.clone(), secret_key_as_string).await?; + let message_sender = overlay_conn.sender(); + + let overlay_conn = Arc::new(RwLock::new(overlay_conn)); + + Ok(OracleAgent { + collector, + is_public_network, + message_sender, + overlay_conn, + shutdown_sender, + }) + } + + /// This method returns the proof for a given slot or an error if the proof cannot be provided. + /// The agent will try every possible way to get the proof before returning an error. + pub async fn get_proof(&self, slot: Slot) -> Result { + let collector = self.collector.clone(); + + #[cfg(test)] + let timeout_seconds = 180; + + #[cfg(not(test))] + let timeout_seconds = 60; + + timeout(Duration::from_secs(timeout_seconds), async move { + loop { + tracing::debug!("get_proof(): attempt to build proof for slot {slot}"); + let collector = collector.read().await; + match collector.build_proof(slot, &self.message_sender).await { + None => { + drop(collector); + // give enough interval for every retry + sleep(Duration::from_secs(OracleAgent::BUILD_PROOF_INTERVAL)).await; + continue + }, + Some(proof) => { + tracing::info!("get_proof(): Successfully build proof for slot {slot}"); + tracing::trace!(" with proof: {proof:?}"); + return Ok(proof) + }, + } + } + }) + .await + .map_err(|_| { + Error::ProofTimeout(format!("Timeout elapsed for building proof of slot {slot}")) + })? } #[cfg(any(test, feature = "integration"))] pub async fn is_stellar_running(&self) -> bool { - self.message_sender.is_some() && self.collector.read().await.last_slot_index() > 0 + self.collector.read().await.last_slot_index() > 0 } } @@ -55,25 +112,14 @@ impl OracleAgent { /// * `message` - A message from the StellarRelay /// * `collector` - used to collect envelopes and transaction sets /// * `message_sender` - used to send messages to Stellar Node -/// * `is_proof_building_ready` - set a signal to ready if a slot was saved async fn handle_message( message: StellarMessage, collector: Arc>, message_sender: &StellarMessageSender, - is_proof_building_ready: &mut Option, ) -> Result<(), Error> { match message { StellarMessage::ScpMessage(env) => { - // if the first slot was saved, it means proof building is ready. - if let Some(slot) = collector.write().await.handle_envelope(env, message_sender).await? - { - if let Some(true) = is_proof_building_ready { - tracing::info!( - "handle_message(): First slot saved: {slot}. Ready to build proofs " - ); - } - *is_proof_building_ready = None; - } + collector.write().await.handle_envelope(env, message_sender).await?; }, StellarMessage::TxSet(set) => if let Err(e) = collector.read().await.add_txset(set) { @@ -91,43 +137,24 @@ async fn handle_message( } pub async fn listen_for_stellar_messages( - config: StellarOverlayConfig, - oracle_agent: ArcRwLock, - secret_key_as_string: String, + oracle_agent: Arc, shutdown_sender: ShutdownSender, ) -> Result<(), service::Error> { tracing::info!( "listen_for_stellar_messages(): Starting connection to Stellar overlay network..." ); - let mut overlay_conn = connect_to_stellar_overlay_network(config.clone(), secret_key_as_string) - .await.map_err(|e|{ - tracing::error!("listen_for_stellar_messages(): Failed to connect to Stellar overlay network: {e:?}"); - service::Error::StartOracleAgentError - })?; - - // use StellarOverlayConnection's sender to send message to Stellar - let sender = overlay_conn.sender(); - { - oracle_agent.write().await.message_sender = Some(sender.clone()); - }; + let mut overlay_conn = oracle_agent.overlay_conn.write().await; // log a new message received. let health_check_interval = Duration::from_secs(STELLAR_RELAY_HEALTH_CHECK_IN_SECS); let mut next_time = Instant::now() + health_check_interval; - let mut is_proof_building_ready: Option = Some(false); loop { - let collector = oracle_agent.read().await.collector.clone(); + let collector = oracle_agent.collector.clone(); match overlay_conn.listen().await { Ok(None) => {}, - Ok(Some(StellarMessage::Hello(_))) => { - tracing::info!( - "listen_for_stellar_messages(): received hello message from Stellar" - ); - is_proof_building_ready = Some(true); - }, Ok(Some(StellarMessage::ErrorMsg(e))) => { tracing::error!( "listen_for_stellar_messages(): received error message from Stellar: {e:?}" @@ -135,20 +162,16 @@ pub async fn listen_for_stellar_messages( break }, Ok(Some(msg)) => { - let msg_as_str = to_base64_xdr_string(&msg); if Instant::now() >= next_time { tracing::info!("listen_for_stellar_messages(): health check: received message from Stellar"); next_time += health_check_interval; } - if let Some(true) = is_proof_building_ready { - tracing::info!("listen_for_stellar_messages(): received message from Stellar: {msg_as_str}"); - }; - if let Err(e) = - handle_message(msg, collector.clone(), &sender, &mut is_proof_building_ready) + handle_message(msg.clone(), collector.clone(), &oracle_agent.message_sender) .await { + let msg_as_str = msg.as_base64_encoded_string(); tracing::error!("listen_for_stellar_messages(): failed to handle message: {msg_as_str}: {e:?}"); } }, @@ -174,16 +197,18 @@ pub async fn listen_for_stellar_messages( #[cfg(any(test, feature = "integration"))] pub async fn start_oracle_agent( cfg: StellarOverlayConfig, - _vault_stellar_secret: String, + vault_stellar_secret: String, shutdown_sender: ShutdownSender, -) -> ArcRwLock { - let oracle_agent = Arc::new(RwLock::new(OracleAgent::new(&cfg, shutdown_sender.clone()))); - - let secret = crate::oracle::get_random_secret_key(); +) -> Arc { + let oracle_agent = Arc::new( + OracleAgent::new(&cfg, vault_stellar_secret, shutdown_sender.clone()) + .await + .expect("should work"), + ); - tokio::spawn(listen_for_stellar_messages(cfg, oracle_agent.clone(), secret, shutdown_sender)); + tokio::spawn(listen_for_stellar_messages(oracle_agent.clone(), shutdown_sender)); - while !oracle_agent.read().await.is_stellar_running().await { + while !oracle_agent.is_stellar_running().await { sleep(Duration::from_millis(500)).await; } @@ -191,53 +216,6 @@ pub async fn start_oracle_agent( oracle_agent } -impl OracleAgent { - // the interval for every build_proof retry - const BUILD_PROOF_INTERVAL:u64 = 10; - - /// This method returns the proof for a given slot or an error if the proof cannot be provided. - /// The agent will try every possible way to get the proof before returning an error. - pub async fn get_proof(&self, slot: Slot) -> Result { - let sender = self - .message_sender - .clone() - .ok_or_else(|| Error::Uninitialized("MessageSender".to_string()))?; - - let collector = self.collector.clone(); - - #[cfg(test)] - let timeout_seconds = 180; - - #[cfg(not(test))] - let timeout_seconds = 60; - - timeout(Duration::from_secs(timeout_seconds), async move { - loop { - tracing::info!("get_proof(): attempt to build proof for slot {slot}"); - let stellar_sender = sender.clone(); - let collector = collector.read().await; - match collector.build_proof(slot, &stellar_sender).await { - None => { - drop(collector); - // give enough interval for every retry - sleep(Duration::from_secs(OracleAgent::BUILD_PROOF_INTERVAL)).await; - continue - }, - Some(proof) => { - tracing::info!("get_proof(): Successfully build proof for slot {slot}"); - tracing::trace!(" with proof: {proof:?}"); - return Ok(proof) - }, - } - } - }) - .await - .map_err(|_| { - Error::ProofTimeout(format!("Timeout elapsed for building proof of slot {slot}")) - })? - } -} - #[cfg(test)] mod tests { use super::*; @@ -267,14 +245,14 @@ mod tests { .await; let latest_slot = loop { - let slot = agent.read().await.collector.read().await.last_slot_index(); + let slot = agent.collector.read().await.last_slot_index(); if slot > 0 { break slot } sleep(Duration::from_millis(500)).await; }; - let proof_result = agent.read().await.get_proof(latest_slot).await; + let proof_result = agent.get_proof(latest_slot).await; assert!(proof_result.is_ok(), "Failed to get proof for slot: {}", latest_slot); } @@ -298,7 +276,7 @@ mod tests { // This slot should be archived on the public network let target_slot = 44041116; - let proof = agent.read().await.get_proof(target_slot).await.expect("should return a proof"); + let proof = agent.get_proof(target_slot).await.expect("should return a proof"); assert_eq!(proof.slot(), 44041116); @@ -337,7 +315,7 @@ mod tests { // This slot should be archived on the public network let target_slot = 44041116; - let proof = agent.read().await.get_proof(target_slot).await.expect("should return a proof"); + let proof = agent.get_proof(target_slot).await.expect("should return a proof"); assert_eq!(proof.slot(), 44041116); @@ -368,7 +346,7 @@ mod tests { // This slot should be archived on the public network let target_slot = 44041116; - let proof_result = agent.read().await.get_proof(target_slot).await; + let proof_result = agent.get_proof(target_slot).await; assert!(matches!(proof_result, Err(Error::ProofTimeout(_)))); diff --git a/clients/vault/src/oracle/collector/collector.rs b/clients/vault/src/oracle/collector/collector.rs index b8b57bb66..7cb1b399d 100644 --- a/clients/vault/src/oracle/collector/collector.rs +++ b/clients/vault/src/oracle/collector/collector.rs @@ -1,7 +1,7 @@ use std::{default::Default, sync::Arc}; use parking_lot::{lock_api::RwLockReadGuard, RawRwLock, RwLock}; -use stellar_relay_lib::helper::to_base64_xdr_string; +use primitives::stellar::StellarTypeToBase64String; use stellar_relay_lib::sdk::{ network::{Network, PUBLIC_NETWORK, TEST_NETWORK}, @@ -158,7 +158,7 @@ impl ScpMessageCollector { tracing::debug!("Collecting SCPEnvelopes for slot {slot}: success"); tracing::trace!( "Collecting SCPEnvelopes for slot {slot}: the scp envelope: {}", - to_base64_xdr_string(&scp_envelope.statement) + scp_envelope.statement.as_base64_encoded_string() ); envelopes_map.insert(slot, vec![scp_envelope]); } diff --git a/clients/vault/src/oracle/collector/handler.rs b/clients/vault/src/oracle/collector/handler.rs index 4225b59e1..9e437c985 100644 --- a/clients/vault/src/oracle/collector/handler.rs +++ b/clients/vault/src/oracle/collector/handler.rs @@ -3,9 +3,9 @@ use crate::oracle::{ errors::Error, types::StellarMessageSender, }; -use stellar_relay_lib::{ - helper::to_base64_xdr_string, - sdk::types::{ScpEnvelope, ScpStatementPledges, StellarMessage}, +use primitives::stellar::{ + types::{ScpEnvelope, ScpStatementPledges, StellarMessage}, + StellarTypeToBase64String, }; // Handling SCPEnvelopes @@ -27,8 +27,14 @@ impl ScpMessageCollector { if let ScpStatementPledges::ScpStExternalize(stmt) = &env.statement.pledges { tracing::trace!( "Handling Incoming ScpEnvelopes for slot {slot}: SCPStExternalize found: {}", - to_base64_xdr_string(stmt) + stmt.as_base64_encoded_string() ); + + if self.last_slot_index() == 0 { + tracing::info!( + "handle_envelope(): for slot {slot}: first SCPStExternalize found" + ); + } // set the last scpenvenvelope with ScpStExternalize message self.set_last_slot_index(slot); diff --git a/clients/vault/src/oracle/collector/proof_builder.rs b/clients/vault/src/oracle/collector/proof_builder.rs index e23a53c5f..7e3551e17 100644 --- a/clients/vault/src/oracle/collector/proof_builder.rs +++ b/clients/vault/src/oracle/collector/proof_builder.rs @@ -116,7 +116,7 @@ impl ScpMessageCollector { /// fetch envelopes not found in the collector async fn _get_envelopes(&self, slot: Slot, sender: &StellarMessageSender) { - tracing::info!("_get_envelopes(): FOR SLOT {slot} check_slot_still_recoverable_from_overlay: LAST SLOT INDEX: {}",self.last_slot_index()); + tracing::debug!("_get_envelopes(): FOR SLOT {slot} check_slot_still_recoverable_from_overlay: LAST SLOT INDEX: {}",self.last_slot_index()); // If the current slot is still in the range of 'remembered' slots, retrieve the envelopes // from the overlay network if check_slot_still_recoverable_from_overlay(self.last_slot_index(), slot) { @@ -171,7 +171,7 @@ impl ScpMessageCollector { match tx_set { Some(res) => Some(res), None => { - tracing::info!("get_txset(): FOR SLOT {slot} check_slot_still_recoverable_from_overlay: LAST SLOT INDEX: {}",self.last_slot_index()); + tracing::debug!("get_txset(): FOR SLOT {slot} check_slot_still_recoverable_from_overlay: LAST SLOT INDEX: {}",self.last_slot_index()); // If the current slot is still in the range of 'remembered' slots if check_slot_still_recoverable_from_overlay(self.last_slot_index(), slot) { self.ask_overlay_for_txset(slot, sender).await; @@ -204,7 +204,7 @@ impl ScpMessageCollector { /// * `envelopes_map_lock` - the map to insert the envelopes to. /// * `slot` - the slot where the envelopes belong to fn get_envelopes_from_horizon_archive(&self, slot: Slot) -> impl Future { - tracing::info!("get_envelopes_from_horizon_archive(): Fetching SCP envelopes from horizon archive for slot {slot}..."); + tracing::debug!("get_envelopes_from_horizon_archive(): Fetching SCP envelopes from horizon archive for slot {slot}..."); let envelopes_map_arc = self.envelopes_map_clone(); let env_from_archive_map = self.env_from_archive_map_clone(); diff --git a/clients/vault/src/redeem.rs b/clients/vault/src/redeem.rs index 0be4c8c8c..9359b76d2 100644 --- a/clients/vault/src/redeem.rs +++ b/clients/vault/src/redeem.rs @@ -1,9 +1,9 @@ -use std::time::Duration; +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, ArcRwLock, Error}; +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. @@ -18,7 +18,7 @@ pub async fn listen_for_redeem_requests( parachain_rpc: SpacewalkParachain, vault_id_manager: VaultIdManager, payment_margin: Duration, - oracle_agent: ArcRwLock, + oracle_agent: Arc, ) -> Result<(), ServiceError> { parachain_rpc .on_event::( diff --git a/clients/vault/src/replace.rs b/clients/vault/src/replace.rs index 3dc96703a..524a48240 100644 --- a/clients/vault/src/replace.rs +++ b/clients/vault/src/replace.rs @@ -5,7 +5,7 @@ use tokio::sync::RwLock; use crate::{ cancellation::Event, error::Error, oracle::OracleAgent, requests::Request, - system::VaultIdManager, ArcRwLock, + system::VaultIdManager, }; use runtime::{ AcceptReplaceEvent, CollateralBalancesPallet, ExecuteReplaceEvent, PrettyPrint, ReplacePallet, @@ -26,7 +26,7 @@ pub async fn listen_for_accept_replace( parachain_rpc: SpacewalkParachain, vault_id_manager: VaultIdManager, payment_margin: Duration, - oracle_agent: ArcRwLock, + oracle_agent: Arc, ) -> Result<(), ServiceError> { let parachain_rpc = ¶chain_rpc; let vault_id_manager = &vault_id_manager; @@ -96,7 +96,7 @@ pub async fn listen_for_replace_requests( event_channel: Sender, accept_replace_requests: bool, ) -> Result<(), ServiceError> { - tracing::info!("listen_for_replace_requests(): started"); + tracing::debug!("listen_for_replace_requests(): started"); let parachain_rpc = ¶chain_rpc; let vault_id_manager = &vault_id_manager; diff --git a/clients/vault/src/requests/execution.rs b/clients/vault/src/requests/execution.rs index f9fbaab88..2e5c988d5 100644 --- a/clients/vault/src/requests/execution.rs +++ b/clients/vault/src/requests/execution.rs @@ -44,7 +44,7 @@ async fn spawn_tasks_to_execute_open_requests_async( wallet: ArcRwLock, shutdown_tx: ShutdownSender, parachain_rpc: &SpacewalkParachain, - oracle_agent: ArcRwLock, + oracle_agent: Arc, rate_limiter: Arc>, ) where S: DirectStateStore, @@ -96,7 +96,7 @@ fn spawn_task_to_execute_open_request( transaction: TransactionResponse, shutdown_tx: ShutdownSender, parachain_rpc: SpacewalkParachain, - oracle_agent: ArcRwLock, + oracle_agent: Arc, ) -> TextMemo { let hash_as_memo = derive_shortened_request_id(&request.hash_inner()); @@ -147,7 +147,7 @@ async fn execute_open_request_async( tx_envelope: TransactionEnvelope, slot: Slot, parachain_rpc: SpacewalkParachain, - oracle_agent: ArcRwLock, + oracle_agent: Arc, ) { let mut retry_count = 0; // A counter for every execution retry @@ -156,7 +156,7 @@ async fn execute_open_request_async( tracing::info!("Performing retry #{retry_count} out of {MAX_EXECUTION_RETRIES} retries for {:?} request #{}",request.request_type(),request.hash()); } - match oracle_agent.read().await.get_proof(slot).await { + match oracle_agent.get_proof(slot).await { Ok(proof) => { let Err(e) = request.execute(parachain_rpc.clone(), tx_envelope.clone(), proof).await @@ -211,7 +211,7 @@ where vault_id_manager: VaultIdManager, shutdown_tx: ShutdownSender, parachain_rpc: &SpacewalkParachain, - oracle_agent: ArcRwLock, + oracle_agent: Arc, rate_limiter: Arc>, ) { for (_, request) in requests { @@ -236,7 +236,7 @@ where request: Request, vault_id_manager: VaultIdManager, parachain_rpc: SpacewalkParachain, - oracle_agent: ArcRwLock, + oracle_agent: Arc, rate_limiter: Arc>, ) { let Some(vault) = vault_id_manager.get_vault(request.vault_id()).await else { @@ -280,7 +280,9 @@ where /// * `vault_id_manager` - contains all the vault ids and their data. /// * `wallet` - the vault's wallet; used to retrieve a list of stellar transactions /// * `oracle_agent` - the agent used to get the proofs -/// * `payment_margin` - minimum time to the the redeem execution deadline to make the stellar +/// * `payment_margin` - minimum time to the redeem execution deadline to make the stellar +/// * `precheck_signal` - a signal sender to notify the caller that this process is done +/// and pending tasks can be started /// payment. #[allow(clippy::too_many_arguments)] pub async fn execute_open_requests( @@ -288,7 +290,7 @@ pub async fn execute_open_requests( parachain_rpc: SpacewalkParachain, vault_id_manager: VaultIdManager, wallet: Arc>, - oracle_agent: ArcRwLock, + oracle_agent: Arc, payment_margin: Duration, precheck_signal: tokio::sync::broadcast::Sender<()>, ) -> Result<(), ServiceError> { diff --git a/clients/vault/src/requests/helper.rs b/clients/vault/src/requests/helper.rs index 44b4ab0b8..f5f2a62bc 100644 --- a/clients/vault/src/requests/helper.rs +++ b/clients/vault/src/requests/helper.rs @@ -3,7 +3,7 @@ use futures::try_join; use std::{collections::HashMap, sync::Arc, time::Duration}; use tokio::sync::RwLock; -use crate::{requests::structs::Request, ArcRwLock, Error, VaultIdManager}; +use crate::{requests::structs::Request, Error, VaultIdManager}; use crate::oracle::OracleAgent; use primitives::{derive_shortened_request_id, TextMemo, TransactionEnvelopeExt}; @@ -32,7 +32,7 @@ pub(crate) trait PayAndExecuteExt { vault_id_manager: VaultIdManager, shutdown_tx: ShutdownSender, parachain_rpc: &SpacewalkParachain, - oracle_agent: ArcRwLock, + oracle_agent: Arc, rate_limiter: Arc, ); @@ -52,7 +52,7 @@ pub(crate) trait PayAndExecuteExt { request: Request, vault_id_manager: VaultIdManager, parachain_rpc: SpacewalkParachain, - oracle_agent: ArcRwLock, + oracle_agent: Arc, rate_limiter: Arc, ); } diff --git a/clients/vault/src/requests/structs.rs b/clients/vault/src/requests/structs.rs index 7c4791f61..3b657ea1b 100644 --- a/clients/vault/src/requests/structs.rs +++ b/clients/vault/src/requests/structs.rs @@ -2,7 +2,7 @@ use crate::{ metrics::update_stellar_metrics, oracle::{OracleAgent, Proof}, system::VaultData, - ArcRwLock, Error, + Error, }; use primitives::{stellar::PublicKey, CurrencyId}; use runtime::{ @@ -147,7 +147,7 @@ impl Request { &self, parachain_rpc: P, vault: VaultData, - oracle_agent: ArcRwLock, + oracle_agent: Arc, ) -> Result<(), Error> { // ensure the deadline has not expired yet if let Some(ref deadline) = self.deadline { @@ -159,7 +159,7 @@ impl Request { let response = self.transfer_stellar_asset(vault.stellar_wallet.clone()).await?; let tx_env = response.to_envelope()?; - let proof = oracle_agent.read().await.get_proof(response.ledger as Slot).await?; + let proof = oracle_agent.get_proof(response.ledger as Slot).await?; let _ = update_stellar_metrics(&vault, ¶chain_rpc).await; self.execute(parachain_rpc, tx_env, proof).await diff --git a/clients/vault/src/system.rs b/clients/vault/src/system.rs index b7289637a..28f438826 100644 --- a/clients/vault/src/system.rs +++ b/clients/vault/src/system.rs @@ -282,7 +282,7 @@ pub struct VaultService { shutdown: ShutdownSender, vault_id_manager: VaultIdManager, secret_key: String, - agent: Option>, + agent: Option>, } #[async_trait] @@ -460,11 +460,11 @@ impl VaultService { Ok(()) } - fn create_oracle_agent( + async fn create_oracle_agent( &self, is_public_network: bool, shutdown_sender: ShutdownSender, - ) -> Result, ServiceError> { + ) -> Result, ServiceError> { let stellar_overlay_cfg = self.stellar_overlay_cfg()?; // check if both the config file and the wallet are the same. @@ -472,7 +472,15 @@ impl VaultService { return Err(ServiceError::IncompatibleNetwork); } - Ok(Arc::new(RwLock::new(OracleAgent::new(&stellar_overlay_cfg, shutdown_sender)))) + let oracle_agent = + OracleAgent::new(&stellar_overlay_cfg, self.secret_key(), shutdown_sender) + .await + .map_err(|e| { + tracing::error!("Failed to create OracleAgent: {e:?}"); + ServiceError::OracleError(Error::OracleError(e)) + })?; + + Ok(Arc::new(oracle_agent)) } fn create_issue_tasks( @@ -482,7 +490,7 @@ impl VaultService { startup_height: BlockNumber, account_id: AccountId, vault_public_key: PublicKey, - oracle_agent: ArcRwLock, + oracle_agent: Arc, issue_map: ArcRwLock, ledger_env_map: ArcRwLock, memos_to_issue_ids: ArcRwLock, @@ -547,7 +555,7 @@ impl VaultService { replace_event_rx: mpscReceiver, startup_height: BlockNumber, account_id: AccountId, - oracle_agent: ArcRwLock, + oracle_agent: Arc, ) -> Vec<(&str, ServiceTask)> { vec![ ( @@ -663,7 +671,7 @@ impl VaultService { account_id: AccountId, is_public_network: bool, vault_public_key: PublicKey, - oracle_agent: ArcRwLock, + oracle_agent: Arc, issue_map: ArcRwLock, ledger_env_map: ArcRwLock, memos_to_issue_ids: ArcRwLock, @@ -813,7 +821,8 @@ impl VaultService { .await; drop(wallet); - let oracle_agent = self.create_oracle_agent(is_public_network, self.shutdown.clone())?; + let oracle_agent = + self.create_oracle_agent(is_public_network, self.shutdown.clone()).await?; self.agent = Some(oracle_agent.clone()); // issue handling @@ -847,12 +856,7 @@ impl VaultService { let mut tasks = vec![( "Stellar Messages Listener", - run(listen_for_stellar_messages( - self.stellar_overlay_cfg()?, - oracle_agent.clone(), - self.secret_key(), - self.shutdown.clone(), - )), + run(listen_for_stellar_messages(oracle_agent.clone(), self.shutdown.clone())), )]; let mut _tasks = self.create_tasks( diff --git a/clients/vault/tests/helper/helper.rs b/clients/vault/tests/helper/helper.rs index 91d900173..fb8d947c1 100644 --- a/clients/vault/tests/helper/helper.rs +++ b/clients/vault/tests/helper/helper.rs @@ -13,7 +13,7 @@ use runtime::{ }; use sp_keyring::AccountKeyring; use sp_runtime::traits::StaticLookup; -use std::time::Duration; +use std::{sync::Arc, time::Duration}; use stellar_relay_lib::sdk::{PublicKey, SecretKey}; use subxt::utils::AccountId32 as AccountId; use vault::{oracle::OracleAgent, ArcRwLock}; @@ -177,7 +177,7 @@ pub async fn assert_issue( wallet: ArcRwLock, vault_id: &VaultId, amount: u128, - oracle_agent: ArcRwLock, + oracle_agent: Arc, ) { let issue = parachain_rpc .request_issue(amount, vault_id) @@ -203,12 +203,7 @@ pub async fn assert_issue( let slot = response.ledger as u64; // Loop pending proofs until it is ready - let proof = oracle_agent - .read() - .await - .get_proof(slot) - .await - .expect("Proof should be available"); + let proof = oracle_agent.get_proof(slot).await.expect("Proof should be available"); let tx_envelope_xdr_encoded = response.envelope_xdr; let (envelopes_xdr_encoded, tx_set_xdr_encoded) = proof.encode(); diff --git a/clients/vault/tests/helper/mod.rs b/clients/vault/tests/helper/mod.rs index dae417d49..0537eab03 100644 --- a/clients/vault/tests/helper/mod.rs +++ b/clients/vault/tests/helper/mod.rs @@ -114,7 +114,7 @@ pub async fn test_with_vault( SubxtClient, ArcRwLock, ArcRwLock, - ArcRwLock, + Arc, VaultId, SpacewalkParachain, ) -> F, diff --git a/clients/vault/tests/vault_integration_tests.rs b/clients/vault/tests/vault_integration_tests.rs index 54e7d2084..c9b2d4052 100644 --- a/clients/vault/tests/vault_integration_tests.rs +++ b/clients/vault/tests/vault_integration_tests.rs @@ -672,12 +672,7 @@ async fn test_issue_execution_succeeds_from_archive_on_network(is_public_network sleep(Duration::from_secs(5 * 60)).await; // Loop pending proofs until it is ready - let proof = oracle_agent - .read() - .await - .get_proof(slot) - .await - .expect("Proof should be available"); + let proof = oracle_agent.get_proof(slot).await.expect("Proof should be available"); let tx_envelope_xdr_encoded = transaction_response.envelope_xdr; let (envelopes_xdr_encoded, tx_set_xdr_encoded) = proof.encode(); @@ -764,12 +759,7 @@ async fn test_issue_overpayment_succeeds() { let slot = transaction_response.ledger as u64; // Loop pending proofs until it is ready - let proof = oracle_agent - .read() - .await - .get_proof(slot) - .await - .expect("Proof should be available"); + let proof = oracle_agent.get_proof(slot).await.expect("Proof should be available"); let tx_envelope_xdr_encoded = transaction_response.envelope_xdr; let (envelopes_xdr_encoded, tx_set_xdr_encoded) = proof.encode(); @@ -1158,7 +1148,7 @@ async fn test_execute_open_requests_succeeds() { // add it to the set sleep(Duration::from_secs(5)).await; - let (precheck_signal, mut rceiver) = tokio::sync::broadcast::channel(1); + let (precheck_signal, mut receiver) = tokio::sync::broadcast::channel(1); let shutdown_tx = ShutdownSender::new(); join5( @@ -1173,7 +1163,7 @@ async fn test_execute_open_requests_succeeds() { ) .map(Result::unwrap), async move { - assert_ok!(rceiver.recv().await); + assert_ok!(receiver.recv().await); }, // Redeem 0 should be executed without creating an extra payment since we already // sent one just before From e2b3f0236ba617e1fd71b022a741cb254681a414 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Wed, 16 Oct 2024 00:05:03 +0800 Subject: [PATCH 58/63] run cargo fmt --- .../src/connection/connector/message_reader.rs | 5 ++++- clients/stellar-relay-lib/src/overlay.rs | 2 +- clients/vault/src/oracle/collector/handler.rs | 4 +--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/clients/stellar-relay-lib/src/connection/connector/message_reader.rs b/clients/stellar-relay-lib/src/connection/connector/message_reader.rs index a2ee5e16d..07694e157 100644 --- a/clients/stellar-relay-lib/src/connection/connector/message_reader.rs +++ b/clients/stellar-relay-lib/src/connection/connector/message_reader.rs @@ -42,7 +42,10 @@ pub(crate) async fn poll_messages_from_stellar( error!("poll_messages_from_stellar(): Error occurred during sending message to node: {e:?}"); }, Err(TryRecvError::Disconnected) => break, - Err(TryRecvError::Empty) => {}, + Err(TryRecvError::Empty) => { + // there's no message from user; wait for the next iteration + tokio::task::yield_now().await; + }, } // check for messages from Stellar Node. diff --git a/clients/stellar-relay-lib/src/overlay.rs b/clients/stellar-relay-lib/src/overlay.rs index 7de9f5226..4f1f6bad8 100644 --- a/clients/stellar-relay-lib/src/overlay.rs +++ b/clients/stellar-relay-lib/src/overlay.rs @@ -48,7 +48,7 @@ impl StellarOverlayConnection { send_to_user_sender, send_to_node_receiver, )) - .unwrap(); + .expect("Failed to spawn poll_messages_from_stellar"); #[cfg(not(tokio_unstable))] tokio::spawn(poll_messages_from_stellar( diff --git a/clients/vault/src/oracle/collector/handler.rs b/clients/vault/src/oracle/collector/handler.rs index 9e437c985..493ca7de9 100644 --- a/clients/vault/src/oracle/collector/handler.rs +++ b/clients/vault/src/oracle/collector/handler.rs @@ -31,9 +31,7 @@ impl ScpMessageCollector { ); if self.last_slot_index() == 0 { - tracing::info!( - "handle_envelope(): for slot {slot}: first SCPStExternalize found" - ); + tracing::info!("handle_envelope(): for slot {slot}: first SCPStExternalize found"); } // set the last scpenvenvelope with ScpStExternalize message self.set_last_slot_index(slot); From c88e3175a1c0124018dfb77e281ad393efd783b8 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Wed, 16 Oct 2024 16:49:28 +0800 Subject: [PATCH 59/63] remove `unwrap()`s --- clients/runtime/src/rpc.rs | 53 ++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/clients/runtime/src/rpc.rs b/clients/runtime/src/rpc.rs index fb64f02a9..6bb5e3328 100644 --- a/clients/runtime/src/rpc.rs +++ b/clients/runtime/src/rpc.rs @@ -11,7 +11,7 @@ use subxt::{ client::OnlineClient, events::StaticEvent, rpc_params, - storage::{address::Yes, StorageAddress}, + storage::{address::Yes, Storage, StorageAddress}, tx::TxPayload, utils::Static, Error as BasicError, @@ -163,7 +163,7 @@ impl SpacewalkParachain { pub aux: ImportedAux, } - let _head = self.get_finalized_block_hash().await.unwrap(); + let _head = self.get_finalized_block_hash().await.expect("failed to get head"); let _: CreatedBlock = self .rpc @@ -175,7 +175,7 @@ impl SpacewalkParachain { /// This function is used in tests to finalize the current block. #[cfg(feature = "testing-utils")] pub async fn manual_finalize(&self) { - let head = self.get_finalized_block_hash().await.unwrap(); + let head = self.get_finalized_block_hash().await.expect("failed to get head"); let _: bool = self .rpc @@ -271,11 +271,8 @@ impl SpacewalkParachain { // For getting the nonce, use latest, possibly non-finalized block. let storage_key = metadata::storage().system().account(&self.account_id); let on_chain_nonce = self - .api - .storage() - .at_latest() + .get_latest_storage() .await - .unwrap() .fetch(&storage_key) .await .transpose() @@ -293,7 +290,7 @@ impl SpacewalkParachain { where Address: StorageAddress, { - Ok(self.api.storage().at_latest().await.unwrap().fetch(&address).await?) + Ok(self.get_latest_storage().await.fetch(&address).await?) } async fn query_finalized_or_error
( @@ -313,13 +310,19 @@ impl SpacewalkParachain { where Address: StorageAddress, { - Ok(self.api.storage().at_latest().await.unwrap().fetch_or_default(&address).await?) + Ok(self.get_latest_storage().await.fetch_or_default(&address).await?) } pub async fn get_finalized_block_hash(&self) -> Result, Error> { Ok(Some(self.api.backend().latest_finalized_block_ref().await?.hash())) } + async fn get_latest_storage( + &self, + ) -> Storage> { + self.api.storage().at_latest().await.expect("failed to get latest storage") + } + /// Subscribe to new parachain blocks. pub async fn on_block(&self, on_block: F) -> Result<(), Error> where @@ -427,17 +430,17 @@ impl SpacewalkParachain { self.api .tx() .create_signed_with_nonce(&call, &signer, nonce.into(), Default::default()) - .unwrap() + .expect("failed to create a signed extrinsic") .submit_and_watch() .await - .unwrap(); + .expect("failed to submit extrinsic to chain"); // now call with outdated nonce let result = self .api .tx() .create_signed_with_nonce(&call, &signer, 0, Default::default()) - .unwrap() + .expect("failed to create a signed extrinsic") .submit_and_watch() .await; @@ -462,17 +465,17 @@ impl SpacewalkParachain { self.api .tx() .create_signed_with_nonce(&call, &signer, nonce.into(), Default::default()) - .unwrap() + .expect("failed to create a signed extrinsic") .submit() .await - .unwrap(); + .expect("failed to submit extrinsic to chain"); // should call with the same nonce let result = self .api .tx() .create_signed_with_nonce(&call, &signer, nonce.into(), Default::default()) - .unwrap() + .expect("failed to create a signed extrinsic") .submit_and_watch() .await; @@ -499,7 +502,7 @@ pub trait UtilFuncs { impl UtilFuncs for SpacewalkParachain { async fn get_current_chain_height(&self) -> Result { let height_query = metadata::storage().system().number(); - let height = self.api.storage().at_latest().await.unwrap().fetch(&height_query).await?; + let height = self.get_latest_storage().await.fetch(&height_query).await?; match height { Some(height) => Ok(height), None => Err(Error::BlockNotFound), @@ -510,13 +513,13 @@ impl UtilFuncs for SpacewalkParachain { self.native_currency_id } - fn is_this_vault(&self, vault_id: &VaultId) -> bool { - &vault_id.account_id == self.get_account_id() - } - fn get_account_id(&self) -> &AccountId { &self.account_id } + + fn is_this_vault(&self, vault_id: &VaultId) -> bool { + &vault_id.account_id == self.get_account_id() + } } #[async_trait] @@ -594,7 +597,7 @@ impl VaultRegistryPallet for SpacewalkParachain { async fn get_all_vaults(&self) -> Result, Error> { let mut vaults = Vec::new(); let key_addr = metadata::storage().vault_registry().vaults_iter(); - let mut iter = self.api.storage().at_latest().await.unwrap().iter(key_addr).await?; + let mut iter = self.get_latest_storage().await.iter(key_addr).await?; while let Ok((_, account)) = iter.next().await.ok_or(Error::VaultNotFound)? { if let VaultStatus::Active(..) = account.status { vaults.push(account); @@ -779,7 +782,7 @@ impl CollateralBalancesPallet for SpacewalkParachain { async fn get_native_balance_for_id(&self, id: &AccountId) -> Result { let query = metadata::storage().system().account(id); - let result = self.api.storage().at_latest().await.unwrap().fetch(&query).await?; + let result = self.get_latest_storage().await.fetch(&query).await?; Ok(result.map(|x| x.data.free).unwrap_or_default()) } @@ -790,7 +793,7 @@ impl CollateralBalancesPallet for SpacewalkParachain { ) -> Result { let query = metadata::storage().tokens().accounts(&id, &Static(currency_id)); - let result = self.api.storage().at_latest().await.unwrap().fetch(&query).await?; + let result = self.get_latest_storage().await.fetch(&query).await?; Ok(result.map(|x| x.free).unwrap_or_default()) } @@ -805,7 +808,7 @@ impl CollateralBalancesPallet for SpacewalkParachain { ) -> Result { let query = metadata::storage().tokens().accounts(&id, &Static(currency_id)); - let result = self.api.storage().at_latest().await.unwrap().fetch(&query).await?; + let result = self.get_latest_storage().await.fetch(&query).await?; Ok(result.map(|x| x.reserved).unwrap_or_default()) } @@ -1074,7 +1077,7 @@ impl IssuePallet for SpacewalkParachain { let mut issue_requests = Vec::new(); let key_addr = metadata::storage().issue().issue_requests_iter(); - let mut iter = self.api.storage().at_latest().await.unwrap().iter(key_addr).await?; + let mut iter = self.get_latest_storage().await.iter(key_addr).await?; while let Some(result) = iter.next().await { let (issue_id, request) = result?; From 8c07a3d38ca15531ba805f36d48c833d3da920aa Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Wed, 16 Oct 2024 19:43:05 +0800 Subject: [PATCH 60/63] https://github.com/pendulum-chain/spacewalk/pull/545#discussion_r1802855387, https://github.com/pendulum-chain/spacewalk/pull/545/files#r1794072004 --- clients/runtime/src/rpc.rs | 25 ++++++++++++---------- clients/stellar-relay-lib/src/tests/mod.rs | 19 +++++++--------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/clients/runtime/src/rpc.rs b/clients/runtime/src/rpc.rs index 6bb5e3328..b6eb9fd6e 100644 --- a/clients/runtime/src/rpc.rs +++ b/clients/runtime/src/rpc.rs @@ -272,7 +272,7 @@ impl SpacewalkParachain { let storage_key = metadata::storage().system().account(&self.account_id); let on_chain_nonce = self .get_latest_storage() - .await + .await? .fetch(&storage_key) .await .transpose() @@ -290,7 +290,7 @@ impl SpacewalkParachain { where Address: StorageAddress, { - Ok(self.get_latest_storage().await.fetch(&address).await?) + Ok(self.get_latest_storage().await?.fetch(&address).await?) } async fn query_finalized_or_error
( @@ -310,7 +310,7 @@ impl SpacewalkParachain { where Address: StorageAddress, { - Ok(self.get_latest_storage().await.fetch_or_default(&address).await?) + Ok(self.get_latest_storage().await?.fetch_or_default(&address).await?) } pub async fn get_finalized_block_hash(&self) -> Result, Error> { @@ -319,8 +319,11 @@ impl SpacewalkParachain { async fn get_latest_storage( &self, - ) -> Storage> { - self.api.storage().at_latest().await.expect("failed to get latest storage") + ) -> Result>, Error> { + self.api.storage().at_latest().await.map_err(|e| { + log::error!("Failed to get storage from the latest block hash"); + Error::SubxtRuntimeError(e) + }) } /// Subscribe to new parachain blocks. @@ -502,7 +505,7 @@ pub trait UtilFuncs { impl UtilFuncs for SpacewalkParachain { async fn get_current_chain_height(&self) -> Result { let height_query = metadata::storage().system().number(); - let height = self.get_latest_storage().await.fetch(&height_query).await?; + let height = self.get_latest_storage().await?.fetch(&height_query).await?; match height { Some(height) => Ok(height), None => Err(Error::BlockNotFound), @@ -597,7 +600,7 @@ impl VaultRegistryPallet for SpacewalkParachain { async fn get_all_vaults(&self) -> Result, Error> { let mut vaults = Vec::new(); let key_addr = metadata::storage().vault_registry().vaults_iter(); - let mut iter = self.get_latest_storage().await.iter(key_addr).await?; + let mut iter = self.get_latest_storage().await?.iter(key_addr).await?; while let Ok((_, account)) = iter.next().await.ok_or(Error::VaultNotFound)? { if let VaultStatus::Active(..) = account.status { vaults.push(account); @@ -782,7 +785,7 @@ impl CollateralBalancesPallet for SpacewalkParachain { async fn get_native_balance_for_id(&self, id: &AccountId) -> Result { let query = metadata::storage().system().account(id); - let result = self.get_latest_storage().await.fetch(&query).await?; + let result = self.get_latest_storage().await?.fetch(&query).await?; Ok(result.map(|x| x.data.free).unwrap_or_default()) } @@ -793,7 +796,7 @@ impl CollateralBalancesPallet for SpacewalkParachain { ) -> Result { let query = metadata::storage().tokens().accounts(&id, &Static(currency_id)); - let result = self.get_latest_storage().await.fetch(&query).await?; + let result = self.get_latest_storage().await?.fetch(&query).await?; Ok(result.map(|x| x.free).unwrap_or_default()) } @@ -808,7 +811,7 @@ impl CollateralBalancesPallet for SpacewalkParachain { ) -> Result { let query = metadata::storage().tokens().accounts(&id, &Static(currency_id)); - let result = self.get_latest_storage().await.fetch(&query).await?; + let result = self.get_latest_storage().await?.fetch(&query).await?; Ok(result.map(|x| x.reserved).unwrap_or_default()) } @@ -1077,7 +1080,7 @@ impl IssuePallet for SpacewalkParachain { let mut issue_requests = Vec::new(); let key_addr = metadata::storage().issue().issue_requests_iter(); - let mut iter = self.get_latest_storage().await.iter(key_addr).await?; + let mut iter = self.get_latest_storage().await?.iter(key_addr).await?; while let Some(result) = iter.next().await { let (issue_id, request) = result?; diff --git a/clients/stellar-relay-lib/src/tests/mod.rs b/clients/stellar-relay-lib/src/tests/mod.rs index e40b25407..b9402f54e 100644 --- a/clients/stellar-relay-lib/src/tests/mod.rs +++ b/clients/stellar-relay-lib/src/tests/mod.rs @@ -1,7 +1,7 @@ use crate::{ connection::ConnectionInfo, node::NodeInfo, StellarOverlayConfig, StellarOverlayConnection, }; -use async_std::{future::timeout, sync::Mutex}; +use async_std::sync::Mutex; use serial_test::serial; use std::{sync::Arc, thread::sleep, time::Duration}; use substrate_stellar_sdk::{ @@ -62,18 +62,15 @@ async fn stellar_overlay_should_receive_scp_messages() { } ov_conn_locked.stop(); - }); - - // wait for the spawned thread to finish - timeout(Duration::from_secs(200), async move { - let _ = receiver.await.expect("should receive a message"); - - //assert - //ensure that we receive some scp message from stellar node - assert!(!scps_vec.lock().await.is_empty()); }) .await - .expect("time has elapsed"); + .expect("should finish"); + + let _ = receiver.await.expect("should receive a message"); + + //assert + //ensure that we receive some scp message from stellar node + assert!(!scps_vec.lock().await.is_empty()); } #[tokio::test(flavor = "multi_thread")] From 4d40c33b5a04bd0dc9a89b63d360262b46dbdad0 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Mon, 21 Oct 2024 17:10:30 +0800 Subject: [PATCH 61/63] https://github.com/pendulum-chain/spacewalk/actions/runs/11364931112/job/31813445329?pr=545 --- Cargo.lock | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 08b65999e..0ba8968ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8160,7 +8160,6 @@ dependencies = [ "spacewalk-runtime-standalone-mainnet", "spacewalk-runtime-standalone-testnet", "spacewalk-standalone", - "substrate-stellar-sdk", "subxt", "subxt-client", "tempdir", @@ -11699,7 +11698,7 @@ dependencies = [ [[package]] name = "substrate-stellar-sdk" version = "0.3.0" -source = "git+https://github.com/pendulum-chain/substrate-stellar-sdk?branch=polkadot-v1.1.0#9b8e2b77b6c6a63e8e837d1e8f2b42b09d49a943" +source = "git+https://github.com/pendulum-chain/substrate-stellar-sdk?branch=polkadot-v1.1.0#80cd93dc1f9d029a4ddd055aa36636e23134aa58" dependencies = [ "base64 0.13.1", "hex", From 636b60896e6e88b2fb75865ac3f37dfd22801ad1 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Mon, 21 Oct 2024 17:47:19 +0800 Subject: [PATCH 62/63] use latest commit version --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 0ba8968ae..4bf487d47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11698,7 +11698,7 @@ dependencies = [ [[package]] name = "substrate-stellar-sdk" version = "0.3.0" -source = "git+https://github.com/pendulum-chain/substrate-stellar-sdk?branch=polkadot-v1.1.0#80cd93dc1f9d029a4ddd055aa36636e23134aa58" +source = "git+https://github.com/pendulum-chain/substrate-stellar-sdk?branch=polkadot-v1.1.0#6ff899abd7127d59261d7a5d06283a2e5913c6d2" dependencies = [ "base64 0.13.1", "hex", From ebb96c442b93888d993d6bef145d13d069326884 Mon Sep 17 00:00:00 2001 From: b-yap <2826165+b-yap@users.noreply.github.com> Date: Mon, 21 Oct 2024 19:19:29 +0800 Subject: [PATCH 63/63] use `.expect()` since this is only for test feature --- clients/runtime/src/rpc.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clients/runtime/src/rpc.rs b/clients/runtime/src/rpc.rs index b6eb9fd6e..807002eb8 100644 --- a/clients/runtime/src/rpc.rs +++ b/clients/runtime/src/rpc.rs @@ -272,7 +272,8 @@ impl SpacewalkParachain { let storage_key = metadata::storage().system().account(&self.account_id); let on_chain_nonce = self .get_latest_storage() - .await? + .await + .expect("Failed to get storage from the latest block hash") .fetch(&storage_key) .await .transpose()