mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 23:21:02 +00:00
Unify error enums in substrate and ethereum clients with thiserror (#1094)
* Unify error enums in substrate and ethereum clients with `thiserror` Related to https://github.com/paritytech/parity-bridges-common/issues/857 * Add license pre-amble * rustfmt * Fix spelling
This commit is contained in:
committed by
Bastian Köcher
parent
7b4f1c2236
commit
5842968273
@@ -21,6 +21,8 @@
|
||||
//! and authorities set from source to target chain. The headers sync starts
|
||||
//! with this header.
|
||||
|
||||
use crate::error::Error;
|
||||
|
||||
use bp_header_chain::{
|
||||
find_grandpa_authorities_scheduled_change,
|
||||
justification::{verify_justification, GrandpaJustification},
|
||||
@@ -32,7 +34,7 @@ use num_traits::{One, Zero};
|
||||
use relay_substrate_client::{Chain, Client};
|
||||
use sp_core::Bytes;
|
||||
use sp_finality_grandpa::AuthorityList as GrandpaAuthoritiesSet;
|
||||
use sp_runtime::traits::Header as HeaderT;
|
||||
use sp_runtime::traits::{Header as HeaderT, Header};
|
||||
|
||||
/// Submit headers-bridge initialization transaction.
|
||||
pub async fn initialize<SourceChain: Chain, TargetChain: Chain>(
|
||||
@@ -77,7 +79,7 @@ async fn do_initialize<SourceChain: Chain, TargetChain: Chain>(
|
||||
prepare_initialize_transaction: impl FnOnce(TargetChain::Index, InitializationData<SourceChain::Header>) -> Bytes
|
||||
+ Send
|
||||
+ 'static,
|
||||
) -> Result<TargetChain::Hash, String> {
|
||||
) -> Result<TargetChain::Hash, Error<SourceChain::Hash, <SourceChain::Header as Header>::Number>> {
|
||||
let initialization_data = prepare_initialization_data(source_client).await?;
|
||||
log::info!(
|
||||
target: "bridge",
|
||||
@@ -92,41 +94,40 @@ async fn do_initialize<SourceChain: Chain, TargetChain: Chain>(
|
||||
prepare_initialize_transaction(transaction_nonce, initialization_data)
|
||||
})
|
||||
.await
|
||||
.map_err(|err| format!("Failed to submit {} transaction: {:?}", TargetChain::NAME, err))?;
|
||||
.map_err(|err| Error::SubmitTransaction(TargetChain::NAME, err))?;
|
||||
Ok(initialization_tx_hash)
|
||||
}
|
||||
|
||||
/// Prepare initialization data for the GRANDPA verifier pallet.
|
||||
async fn prepare_initialization_data<SourceChain: Chain>(
|
||||
source_client: Client<SourceChain>,
|
||||
) -> Result<InitializationData<SourceChain::Header>, String> {
|
||||
) -> Result<
|
||||
InitializationData<SourceChain::Header>,
|
||||
Error<SourceChain::Hash, <SourceChain::Header as Header>::Number>,
|
||||
> {
|
||||
// In ideal world we just need to get best finalized header and then to read GRANDPA authorities
|
||||
// set (`pallet_grandpa::CurrentSetId` + `GrandpaApi::grandpa_authorities()`) at this header.
|
||||
//
|
||||
// But now there are problems with this approach - `CurrentSetId` may return invalid value. So
|
||||
// here we're waiting for the next justification, read the authorities set and then try to
|
||||
// figure out the set id with bruteforce.
|
||||
let justifications = source_client.subscribe_justifications().await.map_err(|err| {
|
||||
format!("Failed to subscribe to {} justifications: {:?}", SourceChain::NAME, err)
|
||||
})?;
|
||||
|
||||
let justifications = source_client
|
||||
.subscribe_justifications()
|
||||
.await
|
||||
.map_err(|err| Error::Subscribe(SourceChain::NAME, err))?;
|
||||
// Read next justification - the header that it finalizes will be used as initial header.
|
||||
let justification = justifications
|
||||
.next()
|
||||
.await
|
||||
.map_err(|err| err.to_string())
|
||||
.map_err(|e| Error::ReadJustification(SourceChain::NAME, e))
|
||||
.and_then(|justification| {
|
||||
justification.ok_or_else(|| "stream has ended unexpectedly".into())
|
||||
})
|
||||
.map_err(|err| {
|
||||
format!("Failed to read {} justification from the stream: {}", SourceChain::NAME, err,)
|
||||
justification.ok_or_else(|| Error::ReadJustificationStreamEnded(SourceChain::NAME))
|
||||
})?;
|
||||
|
||||
// Read initial header.
|
||||
let justification: GrandpaJustification<SourceChain::Header> =
|
||||
Decode::decode(&mut &justification.0[..]).map_err(|err| {
|
||||
format!("Failed to decode {} justification: {:?}", SourceChain::NAME, err)
|
||||
})?;
|
||||
Decode::decode(&mut &justification.0[..])
|
||||
.map_err(|err| Error::DecodeJustification(SourceChain::NAME, err))?;
|
||||
|
||||
let (initial_header_hash, initial_header_number) =
|
||||
(justification.commit.target_hash, justification.commit.target_number);
|
||||
@@ -174,11 +175,7 @@ async fn prepare_initialization_data<SourceChain: Chain>(
|
||||
let mut min_possible_block_number = SourceChain::BlockNumber::zero();
|
||||
let authorities_for_verification = VoterSet::new(authorities_for_verification.clone())
|
||||
.ok_or_else(|| {
|
||||
format!(
|
||||
"Read invalid {} authorities set: {:?}",
|
||||
SourceChain::NAME,
|
||||
authorities_for_verification,
|
||||
)
|
||||
Error::ReadInvalidAuthorities(SourceChain::NAME, authorities_for_verification)
|
||||
})?;
|
||||
loop {
|
||||
log::trace!(
|
||||
@@ -205,12 +202,7 @@ async fn prepare_initialization_data<SourceChain: Chain>(
|
||||
// there can't be more authorities set changes than headers => if we have reached
|
||||
// `initial_block_number` and still have not found correct value of
|
||||
// `initial_authorities_set_id`, then something else is broken => fail
|
||||
return Err(format!(
|
||||
"Failed to guess initial {} GRANDPA authorities set id: checked all\
|
||||
possible ids in range [0; {}]",
|
||||
SourceChain::NAME,
|
||||
initial_header_number
|
||||
))
|
||||
return Err(Error::GuessInitialAuthorities(SourceChain::NAME, initial_header_number))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,37 +222,24 @@ async fn prepare_initialization_data<SourceChain: Chain>(
|
||||
async fn source_header<SourceChain: Chain>(
|
||||
source_client: &Client<SourceChain>,
|
||||
header_hash: SourceChain::Hash,
|
||||
) -> Result<SourceChain::Header, String> {
|
||||
source_client.header_by_hash(header_hash).await.map_err(|err| {
|
||||
format!(
|
||||
"Failed to retrive {} header with hash {}: {:?}",
|
||||
SourceChain::NAME,
|
||||
header_hash,
|
||||
err,
|
||||
)
|
||||
})
|
||||
) -> Result<SourceChain::Header, Error<SourceChain::Hash, <SourceChain::Header as Header>::Number>>
|
||||
{
|
||||
source_client
|
||||
.header_by_hash(header_hash)
|
||||
.await
|
||||
.map_err(|err| Error::RetrieveHeader(SourceChain::NAME, header_hash, err))
|
||||
}
|
||||
|
||||
/// Read GRANDPA authorities set at given header.
|
||||
async fn source_authorities_set<SourceChain: Chain>(
|
||||
source_client: &Client<SourceChain>,
|
||||
header_hash: SourceChain::Hash,
|
||||
) -> Result<GrandpaAuthoritiesSet, String> {
|
||||
let raw_authorities_set =
|
||||
source_client.grandpa_authorities_set(header_hash).await.map_err(|err| {
|
||||
format!(
|
||||
"Failed to retrive {} GRANDPA authorities set at header {}: {:?}",
|
||||
SourceChain::NAME,
|
||||
header_hash,
|
||||
err,
|
||||
)
|
||||
})?;
|
||||
GrandpaAuthoritiesSet::decode(&mut &raw_authorities_set[..]).map_err(|err| {
|
||||
format!(
|
||||
"Failed to decode {} GRANDPA authorities set at header {}: {:?}",
|
||||
SourceChain::NAME,
|
||||
header_hash,
|
||||
err,
|
||||
)
|
||||
})
|
||||
) -> Result<GrandpaAuthoritiesSet, Error<SourceChain::Hash, <SourceChain::Header as Header>::Number>>
|
||||
{
|
||||
let raw_authorities_set = source_client
|
||||
.grandpa_authorities_set(header_hash)
|
||||
.await
|
||||
.map_err(|err| Error::RetrieveAuthorities(SourceChain::NAME, header_hash, err))?;
|
||||
GrandpaAuthoritiesSet::decode(&mut &raw_authorities_set[..])
|
||||
.map_err(|err| Error::DecodeAuthorities(SourceChain::NAME, header_hash, err))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user