Have SeraiError::RpcError include the subxt Error

Part of debugging #262.
This commit is contained in:
Luke Parker 2023-03-19 22:02:30 -04:00
parent 59891594aa
commit 60ca3a9599
No known key found for this signature in database
2 changed files with 29 additions and 12 deletions

View file

@ -7,6 +7,7 @@ use subxt::ext::scale_value::Value;
use sp_core::{Pair as PairTrait, sr25519::Pair}; use sp_core::{Pair as PairTrait, sr25519::Pair};
use subxt::{ use subxt::{
error::Error as SubxtError,
utils::Encoded, utils::Encoded,
config::{ config::{
substrate::{BlakeTwo256, SubstrateHeader}, substrate::{BlakeTwo256, SubstrateHeader},
@ -52,10 +53,10 @@ impl SubxtConfig for SeraiConfig {
type ExtrinsicParams = BaseExtrinsicParams<SeraiConfig, Tip>; type ExtrinsicParams = BaseExtrinsicParams<SeraiConfig, Tip>;
} }
#[derive(Clone, Error, Debug)] #[derive(Error, Debug)]
pub enum SeraiError { pub enum SeraiError {
#[error("failed to connect to serai")] #[error("failed to communicate with serai: {0}")]
RpcError, RpcError(SubxtError),
#[error("serai-client library was intended for a different runtime version")] #[error("serai-client library was intended for a different runtime version")]
InvalidRuntime, InvalidRuntime,
} }
@ -65,7 +66,7 @@ pub struct Serai(OnlineClient<SeraiConfig>);
impl Serai { impl Serai {
pub async fn new(url: &str) -> Result<Self, SeraiError> { pub async fn new(url: &str) -> Result<Self, SeraiError> {
Ok(Serai(OnlineClient::<SeraiConfig>::from_url(url).await.map_err(|_| SeraiError::RpcError)?)) Ok(Serai(OnlineClient::<SeraiConfig>::from_url(url).await.map_err(SeraiError::RpcError)?))
} }
async fn storage<R: Decode>( async fn storage<R: Decode>(
@ -82,10 +83,10 @@ impl Serai {
storage storage
.at(Some(block.into())) .at(Some(block.into()))
.await .await
.map_err(|_| SeraiError::RpcError)? .map_err(SeraiError::RpcError)?
.fetch(&address) .fetch(&address)
.await .await
.map_err(|_| SeraiError::RpcError)? .map_err(SeraiError::RpcError)?
.map(|res| R::decode(&mut res.encoded()).map_err(|_| SeraiError::InvalidRuntime)) .map(|res| R::decode(&mut res.encoded()).map_err(|_| SeraiError::InvalidRuntime))
.transpose() .transpose()
} }
@ -96,8 +97,7 @@ impl Serai {
filter: impl Fn(&E) -> bool, filter: impl Fn(&E) -> bool,
) -> Result<Vec<E>, SeraiError> { ) -> Result<Vec<E>, SeraiError> {
let mut res = vec![]; let mut res = vec![];
for event in for event in self.0.events().at(Some(block.into())).await.map_err(SeraiError::RpcError)?.iter()
self.0.events().at(Some(block.into())).await.map_err(|_| SeraiError::RpcError)?.iter()
{ {
let event = event.map_err(|_| SeraiError::InvalidRuntime)?; let event = event.map_err(|_| SeraiError::InvalidRuntime)?;
if PalletInfo::index::<P>().unwrap() == usize::from(event.pallet_index()) { if PalletInfo::index::<P>().unwrap() == usize::from(event.pallet_index()) {
@ -113,7 +113,7 @@ impl Serai {
} }
pub async fn get_latest_block_hash(&self) -> Result<[u8; 32], SeraiError> { 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<S: Send + Sync + Signer<SeraiConfig>>( pub fn sign<S: Send + Sync + Signer<SeraiConfig>>(
@ -130,7 +130,7 @@ impl Serai {
} }
pub async fn publish(&self, tx: &Encoded) -> Result<[u8; 32], SeraiError> { 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)
} }
} }

View file

@ -43,7 +43,7 @@ pub async fn provide_updates(updates: Updates) -> [u8; 32] {
} }
}) })
.unwrap(); .unwrap();
let _handle = jsonrpsee_server::ServerBuilder::default() let handle = jsonrpsee_server::ServerBuilder::default()
.build("127.0.0.1:5134") .build("127.0.0.1:5134")
.await .await
.unwrap() .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 // This will fail if there were more batch events than expected
assert!(batches.is_empty()); assert!(batches.is_empty());
handle.stop().unwrap();
handle.stopped().await;
return latest; return latest;
} }
} }
@ -92,12 +95,21 @@ macro_rules! serai_test {
$( $(
#[tokio::test] #[tokio::test]
async fn $name() { async fn $name() {
use std::process::Command;
let guard = runner::SEQUENTIAL.lock().await; 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 // Spawn a fresh Serai node
let mut command = { let mut command = {
use core::time::Duration; 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 node = {
let this_crate = Path::new(env!("CARGO_MANIFEST_DIR")); 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()) { if std::env::var("GITHUB_CI") == Ok("true".to_string()) {
tokio::time::sleep(Duration::from_secs(60)).await; tokio::time::sleep(Duration::from_secs(60)).await;
} }
// Sanity check the pidof command is well-formed
assert!(is_running());
command command
}; };
@ -128,6 +144,7 @@ macro_rules! serai_test {
} else { } else {
command.kill().unwrap(); command.kill().unwrap();
} }
assert!(!is_running());
}).await; }).await;
} }
)* )*