diff --git a/substrate/serai/client/src/serai/mod.rs b/substrate/serai/client/src/serai/mod.rs index 067d314f..d55acd55 100644 --- a/substrate/serai/client/src/serai/mod.rs +++ b/substrate/serai/client/src/serai/mod.rs @@ -7,6 +7,7 @@ use subxt::ext::scale_value::Value; use sp_core::{Pair as PairTrait, sr25519::Pair}; use subxt::{ + error::Error as SubxtError, utils::Encoded, config::{ substrate::{BlakeTwo256, SubstrateHeader}, @@ -52,10 +53,10 @@ impl SubxtConfig for SeraiConfig { type ExtrinsicParams = BaseExtrinsicParams; } -#[derive(Clone, Error, Debug)] +#[derive(Error, Debug)] pub enum SeraiError { - #[error("failed to connect to serai")] - RpcError, + #[error("failed to communicate with serai: {0}")] + RpcError(SubxtError), #[error("serai-client library was intended for a different runtime version")] InvalidRuntime, } @@ -65,7 +66,7 @@ pub struct Serai(OnlineClient); impl Serai { pub async fn new(url: &str) -> Result { - Ok(Serai(OnlineClient::::from_url(url).await.map_err(|_| SeraiError::RpcError)?)) + Ok(Serai(OnlineClient::::from_url(url).await.map_err(SeraiError::RpcError)?)) } async fn storage( @@ -82,10 +83,10 @@ impl Serai { storage .at(Some(block.into())) .await - .map_err(|_| SeraiError::RpcError)? + .map_err(SeraiError::RpcError)? .fetch(&address) .await - .map_err(|_| SeraiError::RpcError)? + .map_err(SeraiError::RpcError)? .map(|res| R::decode(&mut res.encoded()).map_err(|_| SeraiError::InvalidRuntime)) .transpose() } @@ -96,8 +97,7 @@ impl Serai { filter: impl Fn(&E) -> bool, ) -> Result, SeraiError> { let mut res = vec![]; - for event in - self.0.events().at(Some(block.into())).await.map_err(|_| SeraiError::RpcError)?.iter() + for event in self.0.events().at(Some(block.into())).await.map_err(SeraiError::RpcError)?.iter() { let event = event.map_err(|_| SeraiError::InvalidRuntime)?; if PalletInfo::index::

().unwrap() == usize::from(event.pallet_index()) { @@ -113,7 +113,7 @@ impl Serai { } pub async fn get_latest_block_hash(&self) -> Result<[u8; 32], SeraiError> { - Ok(self.0.rpc().finalized_head().await.map_err(|_| SeraiError::RpcError)?.into()) + Ok(self.0.rpc().finalized_head().await.map_err(SeraiError::RpcError)?.into()) } pub fn sign>( @@ -130,7 +130,7 @@ impl Serai { } pub async fn publish(&self, tx: &Encoded) -> Result<[u8; 32], SeraiError> { - self.0.rpc().submit_extrinsic(tx).await.map(Into::into).map_err(|_| SeraiError::RpcError) + self.0.rpc().submit_extrinsic(tx).await.map(Into::into).map_err(SeraiError::RpcError) } } diff --git a/substrate/serai/client/tests/runner.rs b/substrate/serai/client/tests/runner.rs index 1e90315b..046a682a 100644 --- a/substrate/serai/client/tests/runner.rs +++ b/substrate/serai/client/tests/runner.rs @@ -43,7 +43,7 @@ pub async fn provide_updates(updates: Updates) -> [u8; 32] { } }) .unwrap(); - let _handle = jsonrpsee_server::ServerBuilder::default() + let handle = jsonrpsee_server::ServerBuilder::default() .build("127.0.0.1:5134") .await .unwrap() @@ -82,6 +82,9 @@ pub async fn provide_updates(updates: Updates) -> [u8; 32] { // This will fail if there were more batch events than expected assert!(batches.is_empty()); + handle.stop().unwrap(); + handle.stopped().await; + return latest; } } @@ -92,12 +95,21 @@ macro_rules! serai_test { $( #[tokio::test] async fn $name() { + use std::process::Command; + let guard = runner::SEQUENTIAL.lock().await; + let is_running = || { + !Command::new("pidof").arg("serai-node").output().unwrap().stdout.is_empty() + }; + // Spawn a fresh Serai node let mut command = { use core::time::Duration; - use std::{path::Path, process::Command}; + use std::path::Path; + + // Make sure a node isn't already running + assert!(!is_running()); let node = { let this_crate = Path::new(env!("CARGO_MANIFEST_DIR")); @@ -116,6 +128,10 @@ macro_rules! serai_test { if std::env::var("GITHUB_CI") == Ok("true".to_string()) { tokio::time::sleep(Duration::from_secs(60)).await; } + + // Sanity check the pidof command is well-formed + assert!(is_running()); + command }; @@ -128,6 +144,7 @@ macro_rules! serai_test { } else { command.kill().unwrap(); } + assert!(!is_running()); }).await; } )*