Skip to content

Commit

Permalink
Improve some relay errors readability (paritytech#1930)
Browse files Browse the repository at this point in the history
* improve some relay errors readability

* clippy
  • Loading branch information
svyatonik authored Mar 3, 2023
1 parent f6b192a commit 480978e
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 6 deletions.
28 changes: 26 additions & 2 deletions bridges/relays/client-substrate/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,10 @@ impl<C: Chain> Client<C> {
Ok(SubstrateChainClient::<C>::finalized_head(&*client).await?)
})
.await
.map_err(|e| Error::FailedToReadBestFinalizedHeaderHash {
chain: C::NAME.into(),
error: e.boxed(),
})
}

/// Return number of the best finalized block.
Expand All @@ -292,6 +296,7 @@ impl<C: Chain> Client<C> {
Ok(SubstrateChainClient::<C>::header(&*client, None).await?)
})
.await
.map_err(|e| Error::FailedToReadBestHeader { chain: C::NAME.into(), error: e.boxed() })
}

/// Get a Substrate block from its hash.
Expand All @@ -311,6 +316,11 @@ impl<C: Chain> Client<C> {
Ok(SubstrateChainClient::<C>::header(&*client, Some(block_hash)).await?)
})
.await
.map_err(|e| Error::FailedToReadHeaderByHash {
chain: C::NAME.into(),
hash: format!("{block_hash}"),
error: e.boxed(),
})
}

/// Get a Substrate block hash by its number.
Expand Down Expand Up @@ -394,10 +404,17 @@ impl<C: Chain> Client<C> {
storage_key: StorageKey,
block_hash: Option<C::Hash>,
) -> Result<Option<StorageData>> {
let cloned_storage_key = storage_key.clone();
self.jsonrpsee_execute(move |client| async move {
Ok(SubstrateStateClient::<C>::storage(&*client, storage_key, block_hash).await?)
Ok(SubstrateStateClient::<C>::storage(&*client, storage_key.clone(), block_hash)
.await?)
})
.await
.map_err(|e| Error::FailedToReadRuntimeStorageValue {
chain: C::NAME.into(),
key: cloned_storage_key,
error: e.boxed(),
})
}

/// Return native tokens balance of the account.
Expand Down Expand Up @@ -640,7 +657,14 @@ impl<C: Chain> Client<C> {
input: Input,
at_block: Option<C::Hash>,
) -> Result<Output> {
let encoded_output = self.state_call(method_name, Bytes(input.encode()), at_block).await?;
let encoded_output = self
.state_call(method_name.clone(), Bytes(input.encode()), at_block)
.await
.map_err(|e| Error::ErrorExecutingRuntimeCall {
chain: C::NAME.into(),
method: method_name,
error: e.boxed(),
})?;
Output::decode(&mut &encoded_output.0[..]).map_err(Error::ResponseParseFailed)
}

Expand Down
67 changes: 63 additions & 4 deletions bridges/relays/client-substrate/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use bp_polkadot_core::parachains::ParaId;
use jsonrpsee::core::Error as RpcError;
use relay_utils::MaybeConnectionError;
use sc_rpc_api::system::Health;
use sp_core::storage::StorageKey;
use sp_runtime::transaction_validity::TransactionValidityError;
use thiserror::Error;

Expand Down Expand Up @@ -55,6 +56,52 @@ pub enum Error {
/// The client we're connected to is not synced, so we can't rely on its state.
#[error("Substrate client is not synced {0}.")]
ClientNotSynced(Health),
/// Failed to read best finalized header hash from given chain.
#[error("Failed to read best finalized header hash of {chain}: {error:?}.")]
FailedToReadBestFinalizedHeaderHash {
/// Name of the chain where the error has happened.
chain: String,
/// Underlying error.
error: Box<Error>,
},
/// Failed to read best finalized header from given chain.
#[error("Failed to read best header of {chain}: {error:?}.")]
FailedToReadBestHeader {
/// Name of the chain where the error has happened.
chain: String,
/// Underlying error.
error: Box<Error>,
},
/// Failed to read header by hash from given chain.
#[error("Failed to read header {hash} of {chain}: {error:?}.")]
FailedToReadHeaderByHash {
/// Name of the chain where the error has happened.
chain: String,
/// Hash of the header we've tried to read.
hash: String,
/// Underlying error.
error: Box<Error>,
},
/// Failed to execute runtime call at given chain.
#[error("Failed to execute runtime call {method} at {chain}: {error:?}.")]
ErrorExecutingRuntimeCall {
/// Name of the chain where the error has happened.
chain: String,
/// Runtime method name.
method: String,
/// Underlying error.
error: Box<Error>,
},
/// Failed to read sotrage value at given chain.
#[error("Failed to read storage value {key:?} at {chain}: {error:?}.")]
FailedToReadRuntimeStorageValue {
/// Name of the chain where the error has happened.
chain: String,
/// Runtime storage key
key: StorageKey,
/// Underlying error.
error: Box<Error>,
},
/// The bridge pallet is halted and all transactions will be rejected.
#[error("Bridge pallet is halted.")]
BridgePalletIsHalted,
Expand All @@ -81,16 +128,28 @@ impl From<tokio::task::JoinError> for Error {
}
}

impl Error {
/// Box the error.
pub fn boxed(self) -> Box<Self> {
Box::new(self)
}
}

impl MaybeConnectionError for Error {
fn is_connection_error(&self) -> bool {
matches!(
*self,
match *self {
Error::RpcError(RpcError::Transport(_))
// right now if connection to the ws server is dropped (after it is already established),
// we're getting this error
| Error::RpcError(RpcError::Internal(_))
| Error::RpcError(RpcError::RestartNeeded(_))
| Error::ClientNotSynced(_),
)
| Error::ClientNotSynced(_) => true,
Error::FailedToReadBestFinalizedHeaderHash { ref error, .. } => error.is_connection_error(),
Error::FailedToReadBestHeader { ref error, .. } => error.is_connection_error(),
Error::FailedToReadHeaderByHash { ref error, .. } => error.is_connection_error(),
Error::ErrorExecutingRuntimeCall { ref error, .. } => error.is_connection_error(),
Error::FailedToReadRuntimeStorageValue { ref error, .. } => error.is_connection_error(),
_ => false,
}
}
}

0 comments on commit 480978e

Please sign in to comment.