diff --git a/substrate/bin/node/executor/tests/common.rs b/substrate/bin/node/executor/tests/common.rs index b376ebc35b..8f8db9f72b 100644 --- a/substrate/bin/node/executor/tests/common.rs +++ b/substrate/bin/node/executor/tests/common.rs @@ -99,7 +99,7 @@ pub fn executor() -> NativeExecutor { pub fn executor_call< R:Decode + Encode + PartialEq, - NC: FnOnce() -> std::result::Result + std::panic::UnwindSafe + NC: FnOnce() -> std::result::Result> + std::panic::UnwindSafe >( t: &mut TestExternalities, method: &str, diff --git a/substrate/client/api/src/call_executor.rs b/substrate/client/api/src/call_executor.rs index 5f1e0134a5..3b725bf877 100644 --- a/substrate/client/api/src/call_executor.rs +++ b/substrate/client/api/src/call_executor.rs @@ -78,7 +78,7 @@ pub trait CallExecutor { Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >( &self, initialize_block_fn: IB, diff --git a/substrate/client/authority-discovery/src/lib.rs b/substrate/client/authority-discovery/src/lib.rs index 26d4396ca8..818eb1beb3 100644 --- a/substrate/client/authority-discovery/src/lib.rs +++ b/substrate/client/authority-discovery/src/lib.rs @@ -93,7 +93,7 @@ where Block: BlockT + Unpin + 'static, Network: NetworkProvider, Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, - >::Api: AuthorityDiscoveryApi, + >::Api: AuthorityDiscoveryApi, DhtEventStream: Stream + Unpin, { new_worker_and_service_with_config( @@ -121,7 +121,7 @@ where Block: BlockT + Unpin + 'static, Network: NetworkProvider, Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, - >::Api: AuthorityDiscoveryApi, + >::Api: AuthorityDiscoveryApi, DhtEventStream: Stream + Unpin, { let (to_worker, from_service) = mpsc::channel(0); diff --git a/substrate/client/authority-discovery/src/worker.rs b/substrate/client/authority-discovery/src/worker.rs index e47f42a445..dac7a97746 100644 --- a/substrate/client/authority-discovery/src/worker.rs +++ b/substrate/client/authority-discovery/src/worker.rs @@ -132,7 +132,7 @@ where Network: NetworkProvider, Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, >::Api: - AuthorityDiscoveryApi, + AuthorityDiscoveryApi, DhtEventStream: Stream + Unpin, { /// Construct a [`Worker`]. @@ -332,7 +332,7 @@ where .client .runtime_api() .authorities(&id) - .map_err(Error::CallingRuntime)? + .map_err(|e| Error::CallingRuntime(e.into()))? .into_iter() .filter(|id| !local_keys.contains(id.as_ref())) .collect(); @@ -546,7 +546,7 @@ where let id = BlockId::hash(client.info().best_hash); let authorities = client.runtime_api() .authorities(&id) - .map_err(Error::CallingRuntime)? + .map_err(|e| Error::CallingRuntime(e.into()))? .into_iter() .map(std::convert::Into::into) .collect::>(); diff --git a/substrate/client/authority-discovery/src/worker/tests.rs b/substrate/client/authority-discovery/src/worker/tests.rs index 20c4c93709..a994e08691 100644 --- a/substrate/client/authority-discovery/src/worker/tests.rs +++ b/substrate/client/authority-discovery/src/worker/tests.rs @@ -100,8 +100,6 @@ pub(crate) struct RuntimeApi { sp_api::mock_impl_runtime_apis! { impl AuthorityDiscoveryApi for RuntimeApi { - type Error = sp_blockchain::Error; - fn authorities(&self) -> Vec { self.authorities.clone() } diff --git a/substrate/client/basic-authorship/src/basic_authorship.rs b/substrate/client/basic-authorship/src/basic_authorship.rs index 73e6156615..067695e5a8 100644 --- a/substrate/client/basic-authorship/src/basic_authorship.rs +++ b/substrate/client/basic-authorship/src/basic_authorship.rs @@ -99,7 +99,7 @@ impl ProposerFactory C: BlockBuilderProvider + HeaderBackend + ProvideRuntimeApi + Send + Sync + 'static, C::Api: ApiExt> - + BlockBuilderApi, + + BlockBuilderApi, { pub fn init_with_now( &mut self, @@ -138,7 +138,7 @@ impl sp_consensus::Environment for C: BlockBuilderProvider + HeaderBackend + ProvideRuntimeApi + Send + Sync + 'static, C::Api: ApiExt> - + BlockBuilderApi, + + BlockBuilderApi, { type CreateProposer = future::Ready>; type Proposer = Proposer; @@ -175,7 +175,7 @@ impl sp_consensus::Proposer for C: BlockBuilderProvider + HeaderBackend + ProvideRuntimeApi + Send + Sync + 'static, C::Api: ApiExt> - + BlockBuilderApi, + + BlockBuilderApi, { type Transaction = backend::TransactionFor; type Proposal = Pin Proposer C: BlockBuilderProvider + HeaderBackend + ProvideRuntimeApi + Send + Sync + 'static, C::Api: ApiExt> - + BlockBuilderApi, + + BlockBuilderApi, { async fn propose_with( self, diff --git a/substrate/client/block-builder/src/lib.rs b/substrate/client/block-builder/src/lib.rs index 5a7e0277d9..5f700da891 100644 --- a/substrate/client/block-builder/src/lib.rs +++ b/substrate/client/block-builder/src/lib.rs @@ -35,8 +35,7 @@ use sp_runtime::{ use sp_blockchain::{ApplyExtrinsicFailed, Error}; use sp_core::ExecutionContext; use sp_api::{ - Core, ApiExt, ApiErrorFor, ApiRef, ProvideRuntimeApi, StorageChanges, StorageProof, - TransactionOutcome, + Core, ApiExt, ApiRef, ProvideRuntimeApi, StorageChanges, StorageProof, TransactionOutcome, }; use sp_consensus::RecordProof; @@ -106,8 +105,7 @@ impl<'a, Block, A, B> BlockBuilder<'a, Block, A, B> where Block: BlockT, A: ProvideRuntimeApi + 'a, - A::Api: BlockBuilderApi + - ApiExt>, + A::Api: BlockBuilderApi + ApiExt>, B: backend::Backend, { /// Create a new instance of builder based on the given `parent_hash` and `parent_number`. @@ -122,7 +120,7 @@ where record_proof: RecordProof, inherent_digests: DigestFor, backend: &'a B, - ) -> Result> { + ) -> Result { let header = <::Header as HeaderT>::new( parent_number + One::one(), Default::default(), @@ -155,7 +153,7 @@ where /// Push onto the block's list of extrinsics. /// /// This will ensure the extrinsic can be validly executed (by executing it). - pub fn push(&mut self, xt: ::Extrinsic) -> Result<(), ApiErrorFor> { + pub fn push(&mut self, xt: ::Extrinsic) -> Result<(), Error> { let block_id = &self.block_id; let extrinsics = &mut self.extrinsics; @@ -174,7 +172,7 @@ where Err(ApplyExtrinsicFailed::Validity(tx_validity).into()), ) }, - Err(e) => TransactionOutcome::Rollback(Err(e)), + Err(e) => TransactionOutcome::Rollback(Err(Error::from(e))), } }) } @@ -184,10 +182,7 @@ where /// Returns the build `Block`, the changes to the storage and an optional `StorageProof` /// supplied by `self.api`, combined as [`BuiltBlock`]. /// The storage proof will be `Some(_)` when proof recording was enabled. - pub fn build(mut self) -> Result< - BuiltBlock>, - ApiErrorFor - > { + pub fn build(mut self) -> Result>, Error> { let header = self.api.finalize_block_with_context( &self.block_id, ExecutionContext::BlockConstruction )?; @@ -227,7 +222,7 @@ where pub fn create_inherents( &mut self, inherent_data: sp_inherents::InherentData, - ) -> Result, ApiErrorFor> { + ) -> Result, Error> { let block_id = self.block_id; self.api.execute_in_transaction(move |api| { // `create_inherents` should not change any state, to ensure this we always rollback @@ -237,7 +232,7 @@ where ExecutionContext::BlockConstruction, inherent_data )) - }) + }).map_err(|e| Error::Application(Box::new(e))) } } diff --git a/substrate/client/consensus/aura/src/lib.rs b/substrate/client/consensus/aura/src/lib.rs index 5b9e7c590b..eb3c2e93e7 100644 --- a/substrate/client/consensus/aura/src/lib.rs +++ b/substrate/client/consensus/aura/src/lib.rs @@ -98,9 +98,9 @@ pub fn slot_duration(client: &C) -> CResult where A: Codec, B: BlockT, C: AuxStore + ProvideRuntimeApi, - C::Api: AuraApi, + C::Api: AuraApi, { - SlotDuration::get_or_compute(client, |a, b| a.slot_duration(b)) + SlotDuration::get_or_compute(client, |a, b| a.slot_duration(b).map_err(Into::into)) } /// Get slot author for given block along with authorities. @@ -515,7 +515,7 @@ impl AuraVerifier where inherent_data: InherentData, timestamp_now: u64, ) -> Result<(), Error> where - C: ProvideRuntimeApi, C::Api: BlockBuilderApi, + C: ProvideRuntimeApi, C::Api: BlockBuilderApi, CAW: CanAuthorWith, { const MAX_TIMESTAMP_DRIFT_SECS: u64 = 60; @@ -534,7 +534,7 @@ impl AuraVerifier where &block_id, block, inherent_data, - ).map_err(Error::Client)?; + ).map_err(|e| Error::Client(e.into()))?; if !inherent_res.ok() { inherent_res @@ -578,7 +578,7 @@ impl Verifier for AuraVerifier where sc_client_api::backend::AuxStore + ProvideCache + BlockOf, - C::Api: BlockBuilderApi + AuraApi> + ApiExt, + C::Api: BlockBuilderApi + AuraApi> + ApiExt, DigestItemFor: CompatibleDigestItem

, P: Pair + Send + Sync + 'static, P::Public: Send + Sync + Hash + Eq + Clone + Decode + Encode + Debug + 'static, @@ -624,7 +624,7 @@ impl Verifier for AuraVerifier where // skip the inherents verification if the runtime API is old. if self.client .runtime_api() - .has_api_with::, _>( + .has_api_with::, _>( &BlockId::Hash(parent_hash), |v| v >= 2, ) @@ -842,7 +842,7 @@ pub fn import_queue( can_author_with: CAW, ) -> Result, sp_consensus::Error> where B: BlockT, - C::Api: BlockBuilderApi + AuraApi> + ApiExt, + C::Api: BlockBuilderApi + AuraApi> + ApiExt, C: 'static + ProvideRuntimeApi + BlockOf + ProvideCache + Send + Sync + AuxStore + HeaderBackend, I: BlockImport> + Send + Sync + 'static, DigestItemFor: CompatibleDigestItem

, diff --git a/substrate/client/consensus/babe/src/lib.rs b/substrate/client/consensus/babe/src/lib.rs index 6ffa18c3cc..61be3a2f5e 100644 --- a/substrate/client/consensus/babe/src/lib.rs +++ b/substrate/client/consensus/babe/src/lib.rs @@ -273,6 +273,8 @@ pub enum Error { CheckInherents(String), /// Client error Client(sp_blockchain::Error), + /// Runtime Api error. + RuntimeApi(sp_api::ApiError), /// Runtime error Runtime(sp_inherents::Error), /// Fork tree error @@ -310,14 +312,14 @@ impl Config { /// Either fetch the slot duration from disk or compute it from the genesis /// state. pub fn get_or_compute(client: &C) -> ClientResult where - C: AuxStore + ProvideRuntimeApi, C::Api: BabeApi, + C: AuxStore + ProvideRuntimeApi, C::Api: BabeApi, { trace!(target: "babe", "Getting slot duration"); match sc_consensus_slots::SlotDuration::get_or_compute(client, |a, b| { - let has_api_v1 = a.has_api_with::, _>( + let has_api_v1 = a.has_api_with::, _>( &b, |v| v == 1, )?; - let has_api_v2 = a.has_api_with::, _>( + let has_api_v2 = a.has_api_with::, _>( &b, |v| v == 2, )?; @@ -326,7 +328,7 @@ impl Config { Ok(a.configuration_before_version_2(b)?.into()) } } else if has_api_v2 { - a.configuration(b) + a.configuration(b).map_err(Into::into) } else { Err(sp_blockchain::Error::VersionInvalid( "Unsupported or invalid BabeApi version".to_string() @@ -846,8 +848,7 @@ impl BabeVerifier + HeaderMetadata + ProvideRuntimeApi, - Client::Api: BlockBuilderApi - + BabeApi, + Client::Api: BlockBuilderApi + BabeApi, SelectChain: sp_consensus::SelectChain, CAW: CanAuthorWith, { @@ -871,7 +872,7 @@ where &block_id, block, inherent_data, - ).map_err(Error::Client)?; + ).map_err(Error::RuntimeApi)?; if !inherent_res.ok() { inherent_res @@ -934,7 +935,7 @@ where self.client .runtime_api() .generate_key_ownership_proof(block_id, slot, equivocation_proof.offender.clone()) - .map_err(Error::Client) + .map_err(Error::RuntimeApi) }; let parent_id = BlockId::Hash(*header.parent_hash()); @@ -957,7 +958,7 @@ where equivocation_proof, key_owner_proof, ) - .map_err(Error::Client)?; + .map_err(Error::RuntimeApi)?; info!(target: "babe", "Submitted equivocation report for author {:?}", author); @@ -971,7 +972,7 @@ where Block: BlockT, Client: HeaderMetadata + HeaderBackend + ProvideRuntimeApi + Send + Sync + AuxStore + ProvideCache, - Client::Api: BlockBuilderApi + BabeApi, + Client::Api: BlockBuilderApi + BabeApi, SelectChain: sp_consensus::SelectChain, CAW: CanAuthorWith + Send + Sync, { @@ -1498,7 +1499,7 @@ pub fn import_queue( + Send + Sync + 'static, Client: ProvideRuntimeApi + ProvideCache + Send + Sync + AuxStore + 'static, Client: HeaderBackend + HeaderMetadata, - Client::Api: BlockBuilderApi + BabeApi + ApiExt, + Client::Api: BlockBuilderApi + BabeApi + ApiExt, SelectChain: sp_consensus::SelectChain + 'static, CAW: CanAuthorWith + Send + Sync + 'static, { diff --git a/substrate/client/consensus/manual-seal/src/consensus/babe.rs b/substrate/client/consensus/manual-seal/src/consensus/babe.rs index fb1ca629f6..247a8d9091 100644 --- a/substrate/client/consensus/manual-seal/src/consensus/babe.rs +++ b/substrate/client/consensus/manual-seal/src/consensus/babe.rs @@ -73,7 +73,7 @@ impl BabeConsensusDataProvider where B: BlockT, C: AuxStore + HeaderBackend + ProvideRuntimeApi + HeaderMetadata, - C::Api: BabeApi, + C::Api: BabeApi, { pub fn new( client: Arc, @@ -131,7 +131,7 @@ impl ConsensusDataProvider for BabeConsensusDataProvider where B: BlockT, C: AuxStore + HeaderBackend + HeaderMetadata + ProvideRuntimeApi, - C::Api: BabeApi, + C::Api: BabeApi, { type Transaction = TransactionFor; @@ -259,7 +259,7 @@ impl SlotTimestampProvider { where B: BlockT, C: AuxStore + HeaderBackend + ProvideRuntimeApi, - C::Api: BabeApi, + C::Api: BabeApi, { let slot_duration = Config::get_or_compute(&*client)?.slot_duration; let info = client.info(); diff --git a/substrate/client/consensus/pow/src/lib.rs b/substrate/client/consensus/pow/src/lib.rs index 975a6f17e7..5ac8a41417 100644 --- a/substrate/client/consensus/pow/src/lib.rs +++ b/substrate/client/consensus/pow/src/lib.rs @@ -232,7 +232,7 @@ impl PowBlockImport wher I: BlockImport> + Send + Sync, I::Error: Into, C: ProvideRuntimeApi + Send + Sync + HeaderBackend + AuxStore + ProvideCache + BlockOf, - C::Api: BlockBuilderApi, + C::Api: BlockBuilderApi, Algorithm: PowAlgorithm, CAW: CanAuthorWith, { @@ -284,7 +284,7 @@ impl PowBlockImport wher &block_id, block, inherent_data, - ).map_err(Error::Client)?; + ).map_err(|e| Error::Client(e.into()))?; if !inherent_res.ok() { inherent_res @@ -314,7 +314,7 @@ impl BlockImport for PowBlockImport, S: SelectChain, C: ProvideRuntimeApi + Send + Sync + HeaderBackend + AuxStore + ProvideCache + BlockOf, - C::Api: BlockBuilderApi, + C::Api: BlockBuilderApi, Algorithm: PowAlgorithm, Algorithm::Difficulty: 'static, CAW: CanAuthorWith, diff --git a/substrate/client/executor/common/src/error.rs b/substrate/client/executor/common/src/error.rs index 0af148fd95..96329d1680 100644 --- a/substrate/client/executor/common/src/error.rs +++ b/substrate/client/executor/common/src/error.rs @@ -37,8 +37,8 @@ pub enum Error { #[error(transparent)] Wasmi(#[from] wasmi::Error), - #[error("API Error: {0}")] - ApiError(String), + #[error("Error calling api function: {0}")] + ApiError(Box), #[error("Method not found: '{0}'")] MethodNotFound(String), @@ -96,16 +96,16 @@ pub enum Error { #[error(transparent)] RuntimeConstruction(#[from] WasmError), - + #[error("Shared memory is not supported")] SharedMemUnsupported, - + #[error("Imported globals are not supported yet")] ImportedGlobalsUnsupported, - + #[error("initializer expression can have only up to 2 expressions in wasm 1.0")] InitializerHasTooManyExpressions, - + #[error("Invalid initializer expression provided {0}")] InvalidInitializerExpression(String), } diff --git a/substrate/client/executor/src/native_executor.rs b/substrate/client/executor/src/native_executor.rs index cdfe349eda..42a7950593 100644 --- a/substrate/client/executor/src/native_executor.rs +++ b/substrate/client/executor/src/native_executor.rs @@ -456,7 +456,7 @@ impl CodeExecutor for NativeExecutor { fn call< R: Decode + Encode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result> + UnwindSafe, >( &self, ext: &mut dyn Externalities, @@ -514,7 +514,7 @@ impl CodeExecutor for NativeExecutor { let res = with_externalities_safe(&mut **ext, move || (call)()) .and_then(|r| r .map(NativeOrEncoded::Native) - .map_err(|s| Error::ApiError(s)) + .map_err(Error::ApiError) ); Ok(res) diff --git a/substrate/client/executor/src/wasm_runtime.rs b/substrate/client/executor/src/wasm_runtime.rs index 4772471049..351a2b5f40 100644 --- a/substrate/client/executor/src/wasm_runtime.rs +++ b/substrate/client/executor/src/wasm_runtime.rs @@ -414,7 +414,7 @@ mod tests { authoring_version: 1, spec_version: 1, impl_version: 1, - apis: sp_api::create_apis_vec!([(Core::::ID, 1)]), + apis: sp_api::create_apis_vec!([(Core::::ID, 1)]), }; let version = decode_version(&old_runtime_version.encode()).unwrap(); @@ -429,7 +429,7 @@ mod tests { authoring_version: 1, spec_version: 1, impl_version: 1, - apis: sp_api::create_apis_vec!([(Core::::ID, 3)]), + apis: sp_api::create_apis_vec!([(Core::::ID, 3)]), }; decode_version(&old_runtime_version.encode()).unwrap_err(); @@ -443,7 +443,7 @@ mod tests { authoring_version: 1, spec_version: 1, impl_version: 1, - apis: sp_api::create_apis_vec!([(Core::::ID, 3)]), + apis: sp_api::create_apis_vec!([(Core::::ID, 3)]), transaction_version: 3, }; diff --git a/substrate/client/finality-grandpa/Cargo.toml b/substrate/client/finality-grandpa/Cargo.toml index 38f6acda05..d1ee2fe6b4 100644 --- a/substrate/client/finality-grandpa/Cargo.toml +++ b/substrate/client/finality-grandpa/Cargo.toml @@ -59,4 +59,3 @@ sp-state-machine = { version = "0.9.0", path = "../../primitives/state-machine" sp-tracing = { version = "3.0.0", path = "../../primitives/tracing" } tokio = { version = "0.2", features = ["rt-core"] } tempfile = "3.1.0" -sp-api = { version = "3.0.0", path = "../../primitives/api" } diff --git a/substrate/client/finality-grandpa/src/environment.rs b/substrate/client/finality-grandpa/src/environment.rs index 5e4203b2a4..55a60e16df 100644 --- a/substrate/client/finality-grandpa/src/environment.rs +++ b/substrate/client/finality-grandpa/src/environment.rs @@ -480,7 +480,7 @@ where Block: BlockT, BE: Backend, C: crate::ClientForGrandpa, - C::Api: GrandpaApi, + C::Api: GrandpaApi, N: NetworkT, SC: SelectChain + 'static, { @@ -549,7 +549,7 @@ where authority_set.set_id, equivocation.offender().clone(), ) - .map_err(Error::Client)? + .map_err(Error::RuntimeApi)? { Some(proof) => proof, None => { @@ -571,7 +571,7 @@ where equivocation_proof, key_owner_proof, ) - .map_err(Error::Client)?; + .map_err(Error::RuntimeApi)?; Ok(()) } @@ -726,7 +726,7 @@ where Block: 'static, B: Backend, C: crate::ClientForGrandpa + 'static, - C::Api: GrandpaApi, + C::Api: GrandpaApi, N: NetworkT + 'static + Send + Sync, SC: SelectChain + 'static, VR: VotingRule, diff --git a/substrate/client/finality-grandpa/src/import.rs b/substrate/client/finality-grandpa/src/import.rs index 2eef13d583..d7b83b8032 100644 --- a/substrate/client/finality-grandpa/src/import.rs +++ b/substrate/client/finality-grandpa/src/import.rs @@ -663,6 +663,7 @@ where Error::Safety(error) => ConsensusError::ClientImport(error), Error::Signing(error) => ConsensusError::ClientImport(error), Error::Timer(error) => ConsensusError::ClientImport(error.to_string()), + Error::RuntimeApi(error) => ConsensusError::ClientImport(error.to_string()), }); }, Ok(_) => { diff --git a/substrate/client/finality-grandpa/src/lib.rs b/substrate/client/finality-grandpa/src/lib.rs index c5ac1189e9..75500a894d 100644 --- a/substrate/client/finality-grandpa/src/lib.rs +++ b/substrate/client/finality-grandpa/src/lib.rs @@ -295,6 +295,8 @@ pub enum Error { Safety(String), /// A timer failed to fire. Timer(io::Error), + /// A runtime api request failed. + RuntimeApi(sp_api::ApiError), } impl From for Error { @@ -698,7 +700,7 @@ where NumberFor: BlockNumberOps, DigestFor: Encode, C: ClientForGrandpa + 'static, - C::Api: GrandpaApi, + C::Api: GrandpaApi, { let GrandpaParams { mut config, @@ -824,7 +826,7 @@ where Block: BlockT, B: Backend + 'static, C: ClientForGrandpa + 'static, - C::Api: GrandpaApi, + C::Api: GrandpaApi, N: NetworkT + Sync, NumberFor: BlockNumberOps, SC: SelectChain + 'static, @@ -1042,7 +1044,7 @@ where NumberFor: BlockNumberOps, SC: SelectChain + 'static, C: ClientForGrandpa + 'static, - C::Api: GrandpaApi, + C::Api: GrandpaApi, VR: VotingRule + Clone + 'static, { type Output = Result<(), Error>; diff --git a/substrate/client/finality-grandpa/src/tests.rs b/substrate/client/finality-grandpa/src/tests.rs index b949818381..4918255d02 100644 --- a/substrate/client/finality-grandpa/src/tests.rs +++ b/substrate/client/finality-grandpa/src/tests.rs @@ -174,8 +174,6 @@ impl ProvideRuntimeApi for TestApi { sp_api::mock_impl_runtime_apis! { impl GrandpaApi for RuntimeApi { - type Error = sp_blockchain::Error; - fn grandpa_authorities(&self) -> AuthorityList { self.inner.genesis_authorities.clone() } diff --git a/substrate/client/light/src/call_executor.rs b/substrate/client/light/src/call_executor.rs index 8b403823b0..ae83807dc9 100644 --- a/substrate/client/light/src/call_executor.rs +++ b/substrate/client/light/src/call_executor.rs @@ -104,7 +104,7 @@ impl CallExecutor for Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >( &self, initialize_block_fn: IB, diff --git a/substrate/client/offchain/src/lib.rs b/substrate/client/offchain/src/lib.rs index b82f89cb95..f456efb755 100644 --- a/substrate/client/offchain/src/lib.rs +++ b/substrate/client/offchain/src/lib.rs @@ -132,10 +132,10 @@ impl OffchainWorkers< ) -> impl Future { let runtime = self.client.runtime_api(); let at = BlockId::hash(header.hash()); - let has_api_v1 = runtime.has_api_with::, _>( + let has_api_v1 = runtime.has_api_with::, _>( &at, |v| v == 1 ); - let has_api_v2 = runtime.has_api_with::, _>( + let has_api_v2 = runtime.has_api_with::, _>( &at, |v| v == 2 ); let version = match (has_api_v1, has_api_v2) { diff --git a/substrate/client/rpc/src/author/mod.rs b/substrate/client/rpc/src/author/mod.rs index 7cd9805445..4181206fdd 100644 --- a/substrate/client/rpc/src/author/mod.rs +++ b/substrate/client/rpc/src/author/mod.rs @@ -24,12 +24,9 @@ mod tests; use std::{sync::Arc, convert::TryInto}; use log::warn; -use sp_blockchain::{Error as ClientError, HeaderBackend}; +use sp_blockchain::HeaderBackend; -use rpc::futures::{ - Sink, Future, - future::result, -}; +use rpc::futures::{Sink, Future, future::result}; use futures::{StreamExt as _, compat::Compat}; use futures::future::{ready, FutureExt, TryFutureExt}; use sc_rpc_api::DenyUnsafe; @@ -93,7 +90,7 @@ impl AuthorApi, BlockHash

> for Author where P: TransactionPool + Sync + Send + 'static, Client: HeaderBackend + ProvideRuntimeApi + Send + Sync + 'static, - Client::Api: SessionKeys, + Client::Api: SessionKeys, { type Metadata = crate::Metadata; diff --git a/substrate/client/rpc/src/state/mod.rs b/substrate/client/rpc/src/state/mod.rs index 52a4ed1d75..a3d83ae250 100644 --- a/substrate/client/rpc/src/state/mod.rs +++ b/substrate/client/rpc/src/state/mod.rs @@ -178,9 +178,8 @@ pub fn new_full( BE: Backend + 'static, Client: ExecutorProvider + StorageProvider + ProofProvider + HeaderBackend + HeaderMetadata + BlockchainEvents - + CallApiAt - + ProvideRuntimeApi + Send + Sync + 'static, - Client::Api: Metadata, + + CallApiAt + ProvideRuntimeApi + Send + Sync + 'static, + Client::Api: Metadata, { let child_backend = Box::new( self::state_full::FullState::new(client.clone(), subscriptions.clone()) diff --git a/substrate/client/rpc/src/state/state_full.rs b/substrate/client/rpc/src/state/state_full.rs index 8d93d445b0..a55903484a 100644 --- a/substrate/client/rpc/src/state/state_full.rs +++ b/substrate/client/rpc/src/state/state_full.rs @@ -223,9 +223,9 @@ impl StateBackend for FullState + 'static, Client: ExecutorProvider + StorageProvider + ProofProvider + HeaderBackend + HeaderMetadata + BlockchainEvents - + CallApiAt + ProvideRuntimeApi + + CallApiAt + ProvideRuntimeApi + Send + Sync + 'static, - Client::Api: Metadata, + Client::Api: Metadata, { fn call( &self, @@ -344,17 +344,23 @@ impl StateBackend for FullState) -> FutureResult { Box::new(result( self.block_or_best(block) + .map_err(client_err) .and_then(|block| - self.client.runtime_api().metadata(&BlockId::Hash(block)).map(Into::into) - ) - .map_err(client_err))) + self.client.runtime_api().metadata(&BlockId::Hash(block)) + .map(Into::into) + .map_err(|e| Error::Client(Box::new(e)))) + )) } fn runtime_version(&self, block: Option) -> FutureResult { Box::new(result( self.block_or_best(block) - .and_then(|block| self.client.runtime_version_at(&BlockId::Hash(block))) - .map_err(client_err))) + .map_err(client_err) + .and_then(|block| + self.client.runtime_version_at(&BlockId::Hash(block)) + .map_err(|e| Error::Client(Box::new(e))) + ) + )) } fn query_storage( @@ -432,7 +438,7 @@ impl StateBackend for FullState ChildStateBackend for FullState + 'static, Client: ExecutorProvider + StorageProvider + HeaderBackend + HeaderMetadata + BlockchainEvents - + CallApiAt + ProvideRuntimeApi + + CallApiAt + ProvideRuntimeApi + Send + Sync + 'static, - Client::Api: Metadata, + Client::Api: Metadata, { fn storage_keys( &self, diff --git a/substrate/client/service/src/builder.rs b/substrate/client/service/src/builder.rs index 882a6c4062..486f816676 100644 --- a/substrate/client/service/src/builder.rs +++ b/substrate/client/service/src/builder.rs @@ -542,14 +542,13 @@ pub fn spawn_tasks( TCl: ProvideRuntimeApi + HeaderMetadata + Chain + BlockBackend + BlockIdTo + ProofProvider + HeaderBackend + BlockchainEvents + ExecutorProvider + UsageProvider + - StorageProvider + CallApiAt + + StorageProvider + CallApiAt + Send + 'static, >::Api: sp_api::Metadata + sc_offchain::OffchainWorkerApi + sp_transaction_pool::runtime_api::TaggedTransactionQueue + sp_session::SessionKeys + - sp_api::ApiErrorExt + sp_api::ApiExt, TBl: BlockT, TBackend: 'static + sc_client_api::backend::Backend + Send, @@ -578,7 +577,7 @@ pub fn spawn_tasks( client.clone(), &BlockId::Hash(chain_info.best_hash), config.dev_key_seed.clone().map(|s| vec![s]).unwrap_or_default(), - )?; + ).map_err(|e| Error::Application(Box::new(e)))?; let telemetry_connection_notifier = init_telemetry( &mut config, @@ -729,14 +728,14 @@ fn gen_handler( TBl: BlockT, TCl: ProvideRuntimeApi + BlockchainEvents + HeaderBackend + HeaderMetadata + ExecutorProvider + - CallApiAt + ProofProvider + + CallApiAt + ProofProvider + StorageProvider + BlockBackend + Send + Sync + 'static, TExPool: MaintainedTransactionPool::Hash> + 'static, TBackend: sc_client_api::backend::Backend + 'static, TRpc: sc_rpc::RpcExtension, >::Api: sp_session::SessionKeys + - sp_api::Metadata, + sp_api::Metadata, { use sc_rpc::{chain, state, author, system, offchain}; diff --git a/substrate/client/service/src/client/call_executor.rs b/substrate/client/service/src/client/call_executor.rs index cc196f67a3..8c7ca645b0 100644 --- a/substrate/client/service/src/client/call_executor.rs +++ b/substrate/client/service/src/client/call_executor.rs @@ -161,7 +161,7 @@ where Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result + UnwindSafe, >( &self, initialize_block_fn: IB, @@ -226,7 +226,10 @@ where ); // TODO: https://github.com/paritytech/substrate/issues/4455 // .with_storage_transaction_cache(storage_transaction_cache.as_mut().map(|c| &mut **c)) - state_machine.execute_using_consensus_failure_handler(execution_manager, native_call) + state_machine.execute_using_consensus_failure_handler( + execution_manager, + native_call.map(|n| || (n)().map_err(|e| Box::new(e) as Box<_>)), + ) }, None => { let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(&state); @@ -245,7 +248,10 @@ where &runtime_code, self.spawn_handle.clone(), ).with_storage_transaction_cache(storage_transaction_cache.as_mut().map(|c| &mut **c)); - state_machine.execute_using_consensus_failure_handler(execution_manager, native_call) + state_machine.execute_using_consensus_failure_handler( + execution_manager, + native_call.map(|n| || (n)().map_err(|e| Box::new(e) as Box<_>)), + ) } }.map_err(Into::into) } diff --git a/substrate/client/service/src/client/client.rs b/substrate/client/service/src/client/client.rs index 8cb0e304cd..b1ff0678ee 100644 --- a/substrate/client/service/src/client/client.rs +++ b/substrate/client/service/src/client/client.rs @@ -604,7 +604,7 @@ impl Client where new_cache: HashMap>, ) -> sp_blockchain::Result where Self: ProvideRuntimeApi, - >::Api: CoreApi + + >::Api: CoreApi + ApiExt, { let BlockImportParams { @@ -696,7 +696,7 @@ impl Client where import_existing: bool, ) -> sp_blockchain::Result where Self: ProvideRuntimeApi, - >::Api: CoreApi + + >::Api: CoreApi + ApiExt, { let parent_hash = import_headers.post().parent_hash().clone(); @@ -838,7 +838,7 @@ impl Client where ) -> sp_blockchain::Result> where Self: ProvideRuntimeApi, - >::Api: CoreApi + + >::Api: CoreApi + ApiExt, { let parent_hash = import_block.header.parent_hash(); @@ -1272,7 +1272,7 @@ impl BlockBuilderProvider for Client + ProvideRuntimeApi, >::Api: ApiExt> - + BlockBuilderApi, + + BlockBuilderApi, { fn new_block_at>( &self, @@ -1628,18 +1628,17 @@ impl CallApiAt for Client where E: CallExecutor + Send + Sync, Block: BlockT, { - type Error = Error; type StateBackend = B::State; fn call_api_at< 'a, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, - C: CoreApi, + NC: FnOnce() -> result::Result + UnwindSafe, + C: CoreApi, >( &self, params: CallApiAtParams<'a, Block, C, NC, B::State>, - ) -> sp_blockchain::Result> { + ) -> Result, sp_api::ApiError> { let core_api = params.core_api; let at = params.at; @@ -1649,7 +1648,9 @@ impl CallApiAt for Client where ); self.executor.contextual_call::<_, fn(_,_) -> _,_,_>( - || core_api.initialize_block(at, &self.prepare_environment_block(at)?), + || core_api + .initialize_block(at, &self.prepare_environment_block(at)?) + .map_err(Error::RuntimeApiError), at, params.function, ¶ms.arguments, @@ -1660,11 +1661,14 @@ impl CallApiAt for Client where params.native_call, params.recorder, Some(extensions), - ) + ).map_err(Into::into) } - fn runtime_version_at(&self, at: &BlockId) -> sp_blockchain::Result { - self.runtime_version_at(at) + fn runtime_version_at( + &self, + at: &BlockId, + ) -> Result { + self.runtime_version_at(at).map_err(Into::into) } } @@ -1676,7 +1680,7 @@ impl sp_consensus::BlockImport for &Client + Send + Sync, Block: BlockT, Client: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: CoreApi + + as ProvideRuntimeApi>::Api: CoreApi + ApiExt, { type Error = ConsensusError; @@ -1776,7 +1780,7 @@ impl sp_consensus::BlockImport for Client + Send + Sync, Block: BlockT, Self: ProvideRuntimeApi, - >::Api: CoreApi + + >::Api: CoreApi + ApiExt, { type Error = ConsensusError; @@ -1935,7 +1939,7 @@ impl backend::AuxStore for Client E: CallExecutor, Block: BlockT, Self: ProvideRuntimeApi, - >::Api: CoreApi, + >::Api: CoreApi, { /// Insert auxiliary data into key-value store. fn insert_aux< @@ -1965,7 +1969,7 @@ impl backend::AuxStore for &Client E: CallExecutor, Block: BlockT, Client: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: CoreApi, + as ProvideRuntimeApi>::Api: CoreApi, { fn insert_aux< 'a, diff --git a/substrate/client/service/src/error.rs b/substrate/client/service/src/error.rs index 31c3cea4ef..caa54700da 100644 --- a/substrate/client/service/src/error.rs +++ b/substrate/client/service/src/error.rs @@ -33,13 +33,13 @@ pub type Result = std::result::Result; pub enum Error { #[error(transparent)] Client(#[from] sp_blockchain::Error), - + #[error(transparent)] Io(#[from] std::io::Error), - + #[error(transparent)] Consensus(#[from] sp_consensus::Error), - + #[error(transparent)] Network(#[from] sc_network::error::Error), diff --git a/substrate/client/service/test/src/client/light.rs b/substrate/client/service/test/src/client/light.rs index b6287741fd..3b20f16387 100644 --- a/substrate/client/service/test/src/client/light.rs +++ b/substrate/client/service/test/src/client/light.rs @@ -215,7 +215,7 @@ impl CallExecutor for DummyCallExecutor { Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, - NC: FnOnce() -> Result + UnwindSafe, + NC: FnOnce() -> Result + UnwindSafe, >( &self, _initialize_block_fn: IB, diff --git a/substrate/client/service/test/src/client/mod.rs b/substrate/client/service/test/src/client/mod.rs index 7498289c7b..66b6aae12c 100644 --- a/substrate/client/service/test/src/client/mod.rs +++ b/substrate/client/service/test/src/client/mod.rs @@ -1327,7 +1327,9 @@ fn doesnt_import_blocks_that_revert_finality() { let import_err = client.import(BlockOrigin::Own, b3).err().unwrap(); let expected_err = ConsensusError::ClientImport( - sp_blockchain::Error::NotInFinalizedChain.to_string() + sp_blockchain::Error::RuntimeApiError( + sp_api::ApiError::Application(Box::new(sp_blockchain::Error::NotInFinalizedChain)) + ).to_string() ); assert_eq!( diff --git a/substrate/client/transaction-pool/src/api.rs b/substrate/client/transaction-pool/src/api.rs index fc14a5a0cb..2ebf038844 100644 --- a/substrate/client/transaction-pool/src/api.rs +++ b/substrate/client/transaction-pool/src/api.rs @@ -84,7 +84,6 @@ where Client: ProvideRuntimeApi + BlockBackend + BlockIdTo, Client: Send + Sync + 'static, Client::Api: TaggedTransactionQueue, - sp_api::ApiErrorFor: Send + std::fmt::Display, { type Block = Block; type Error = error::Error; @@ -166,14 +165,13 @@ where Client: ProvideRuntimeApi + BlockBackend + BlockIdTo, Client: Send + Sync + 'static, Client::Api: TaggedTransactionQueue, - sp_api::ApiErrorFor: Send + std::fmt::Display, { sp_tracing::within_span!(sp_tracing::Level::TRACE, "validate_transaction"; { let runtime_api = client.runtime_api(); let has_v2 = sp_tracing::within_span! { sp_tracing::Level::TRACE, "check_version"; runtime_api - .has_api_with::, _>(&at, |v| v >= 2) + .has_api_with::, _>(&at, |v| v >= 2) .unwrap_or_default() }; @@ -198,7 +196,6 @@ where Client: ProvideRuntimeApi + BlockBackend + BlockIdTo, Client: Send + Sync + 'static, Client::Api: TaggedTransactionQueue, - sp_api::ApiErrorFor: Send + std::fmt::Display, { /// Validates a transaction by calling into the runtime, same as /// `validate_transaction` but blocks the current thread when performing diff --git a/substrate/client/transaction-pool/src/lib.rs b/substrate/client/transaction-pool/src/lib.rs index 32525065b9..b6f19ba376 100644 --- a/substrate/client/transaction-pool/src/lib.rs +++ b/substrate/client/transaction-pool/src/lib.rs @@ -360,7 +360,6 @@ where + sp_runtime::traits::BlockIdTo, Client: sc_client_api::ExecutorProvider + Send + Sync + 'static, Client::Api: sp_transaction_pool::runtime_api::TaggedTransactionQueue, - sp_api::ApiErrorFor: Send + std::fmt::Display, { /// Create new basic transaction pool for a full node with the provided api. pub fn new_full( @@ -391,7 +390,6 @@ where + sp_runtime::traits::BlockIdTo, Client: Send + Sync + 'static, Client::Api: sp_transaction_pool::runtime_api::TaggedTransactionQueue, - sp_api::ApiErrorFor: Send + std::fmt::Display, { type Block = Block; type Hash = sc_transaction_graph::ExtrinsicHash>; diff --git a/substrate/primitives/api/proc-macro/src/decl_runtime_apis.rs b/substrate/primitives/api/proc-macro/src/decl_runtime_apis.rs index ed5f33ef60..9fd5baba87 100644 --- a/substrate/primitives/api/proc-macro/src/decl_runtime_apis.rs +++ b/substrate/primitives/api/proc-macro/src/decl_runtime_apis.rs @@ -187,14 +187,15 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result { result.push(quote!( #[cfg(any(feature = "std", test))] fn convert_between_block_types - ( - input: &I, error_desc: &'static str, - ) -> std::result::Result + #crate_::ApiError>( + input: &I, + map_error: F, + ) -> std::result::Result { ::decode_with_depth_limit( #crate_::MAX_EXTRINSIC_DEPTH, &mut &#crate_::Encode::encode(input)[..], - ).map_err(|e| format!("{} {}", error_desc, e)) + ).map_err(map_error) } )); @@ -202,19 +203,26 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result { for fn_ in fns { let params = extract_parameter_names_types_and_borrows(&fn_, AllowSelfRefInParameters::No)?; let trait_fn_name = &fn_.ident; + let function_name_str = fn_.ident.to_string(); let fn_name = generate_native_call_generator_fn_name(&fn_.ident); let output = return_type_replace_block_with_node_block(fn_.output.clone()); let output_ty = return_type_extract_type(&output); - let output = quote!( std::result::Result<#output_ty, String> ); + let output = quote!( std::result::Result<#output_ty, #crate_::ApiError> ); // Every type that is using the `Block` generic parameter, we need to encode/decode, // to make it compatible between the runtime/node. let conversions = params.iter().filter(|v| type_is_using_block(&v.1)).map(|(n, t, _)| { - let name_str = format!( - "Could not convert parameter `{}` between node and runtime:", quote!(#n) - ); + let param_name = quote!(#n).to_string(); + quote!( - let #n: #t = convert_between_block_types(&#n, #name_str)?; + let #n: #t = convert_between_block_types( + &#n, + |e| #crate_::ApiError::FailedToConvertParameter { + function: #function_name_str, + parameter: #param_name, + error: e, + }, + )?; ) }); // Same as for the input types, we need to check if we also need to convert the output, @@ -223,7 +231,10 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result { quote!( convert_between_block_types( &res, - "Could not convert return value from runtime to node!" + |e| #crate_::ApiError::FailedToConvertReturnValue { + function: #function_name_str, + error: e, + }, ) ) } else { @@ -399,10 +410,10 @@ fn generate_call_api_at_calls(decl: &ItemTrait) -> Result { #[cfg(any(feature = "std", test))] pub fn #fn_name< R: #crate_::Encode + #crate_::Decode + PartialEq, - NC: FnOnce() -> std::result::Result + std::panic::UnwindSafe, + NC: FnOnce() -> std::result::Result + std::panic::UnwindSafe, Block: #crate_::BlockT, T: #crate_::CallApiAt, - C: #crate_::Core, + C: #crate_::Core, >( call_runtime_at: &T, core_api: &C, @@ -416,7 +427,7 @@ fn generate_call_api_at_calls(decl: &ItemTrait) -> Result { native_call: Option, context: #crate_::ExecutionContext, recorder: &Option<#crate_::ProofRecorder>, - ) -> std::result::Result<#crate_::NativeOrEncoded, T::Error> { + ) -> std::result::Result<#crate_::NativeOrEncoded, #crate_::ApiError> { let version = call_runtime_at.runtime_version_at(at)?; use #crate_::InitializeBlock; let initialize_block = if #skip_initialize_block { @@ -621,7 +632,7 @@ impl<'a> ToClientSideDecl<'a> { context: #crate_::ExecutionContext, params: Option<( #( #param_types ),* )>, params_encoded: Vec, - ) -> std::result::Result<#crate_::NativeOrEncoded<#ret_type>, Self::Error>; + ) -> std::result::Result<#crate_::NativeOrEncoded<#ret_type>, #crate_::ApiError>; } ) } @@ -647,7 +658,7 @@ impl<'a> ToClientSideDecl<'a> { let params2 = params.clone(); let ret_type = return_type_extract_type(&method.sig.output); - fold_fn_decl_for_client_side(&mut method.sig, &self.block_id); + fold_fn_decl_for_client_side(&mut method.sig, &self.block_id, &self.crate_); let name_impl = generate_method_runtime_api_impl_name(&self.trait_, &method.sig.ident); let crate_ = self.crate_; @@ -705,7 +716,12 @@ impl<'a> ToClientSideDecl<'a> { }, #crate_::NativeOrEncoded::Encoded(r) => { <#ret_type as #crate_::Decode>::decode(&mut &r[..]) - .map_err(|err| { #crate_::ApiError::new(#function_name, err).into() }) + .map_err(|err| + #crate_::ApiError::FailedToDecodeReturnValue { + function: #function_name, + error: err, + } + ) } } ) @@ -728,12 +744,10 @@ impl<'a> Fold for ToClientSideDecl<'a> { if is_core_trait { // Add all the supertraits we want to have for `Core`. - let crate_ = &self.crate_; input.supertraits = parse_quote!( 'static + Send + Sync - + #crate_::ApiErrorExt ); } else { // Add the `Core` runtime api as super trait. @@ -803,12 +817,12 @@ fn generate_runtime_info_impl(trait_: &ItemTrait, version: u64) -> TokenStream { let bounds = &t.bounds; quote! { #ident #colon_token #bounds } - }).chain(std::iter::once(quote! { __Sr_Api_Error__ })); + }); let ty_generics = trait_.generics.type_params().map(|t| { let ident = &t.ident; quote! { #ident } - }).chain(std::iter::once(quote! { Error = __Sr_Api_Error__ })); + }); quote!( #[cfg(any(feature = "std", test))] diff --git a/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs b/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs index f8d7c74b97..51bbe1c73a 100644 --- a/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs +++ b/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs @@ -233,16 +233,6 @@ fn generate_runtime_api_base_structures() -> Result { C::StateBackend: #crate_::StateBackend<#crate_::HashFor>, {} - #[cfg(any(feature = "std", test))] - impl> #crate_::ApiErrorExt - for RuntimeApiImpl - where - // Rust bug: https://github.com/rust-lang/rust/issues/24159 - C::StateBackend: #crate_::StateBackend<#crate_::HashFor>, - { - type Error = C::Error; - } - #[cfg(any(feature = "std", test))] impl> #crate_::ApiExt for RuntimeApiImpl @@ -269,16 +259,20 @@ fn generate_runtime_api_base_structures() -> Result { fn has_api( &self, at: &#crate_::BlockId, - ) -> std::result::Result where Self: Sized { - self.call.runtime_version_at(at).map(|v| v.has_api_with(&A::ID, |v| v == A::VERSION)) + ) -> std::result::Result where Self: Sized { + self.call + .runtime_version_at(at) + .map(|v| v.has_api_with(&A::ID, |v| v == A::VERSION)) } fn has_api_with bool>( &self, at: &#crate_::BlockId, pred: P, - ) -> std::result::Result where Self: Sized { - self.call.runtime_version_at(at).map(|v| v.has_api_with(&A::ID, pred)) + ) -> std::result::Result where Self: Sized { + self.call + .runtime_version_at(at) + .map(|v| v.has_api_with(&A::ID, pred)) } fn record_proof(&mut self) { @@ -306,7 +300,7 @@ fn generate_runtime_api_base_structures() -> Result { >>, parent_hash: Block::Hash, ) -> std::result::Result< - #crate_::StorageChanges, + #crate_::StorageChanges, String > where Self: Sized { self.initialized_block.borrow_mut().take(); @@ -513,7 +507,7 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> { // Generate the correct return type. input.sig.output = parse_quote!( - -> std::result::Result<#crate_::NativeOrEncoded<#ret_type>, RuntimeApiImplCall::Error> + -> std::result::Result<#crate_::NativeOrEncoded<#ret_type>, #crate_::ApiError> ); // Generate the new method implementation that calls into the runtime. @@ -554,7 +548,7 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> { ) }; - let mut input = fold::fold_impl_item_method(self, input); + let mut input = fold::fold_impl_item_method(self, input); // We need to set the block, after we modified the rest of the ast, otherwise we would // modify our generated block as well. input.block = block; diff --git a/substrate/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs b/substrate/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs index c6ff98c0f1..62a03a59ba 100644 --- a/substrate/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs +++ b/substrate/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs @@ -27,7 +27,7 @@ use proc_macro2::{Span, TokenStream}; use quote::{quote, quote_spanned}; use syn::{ - spanned::Spanned, parse_macro_input, Ident, Type, ItemImpl, ImplItem, TypePath, parse_quote, + spanned::Spanned, parse_macro_input, Ident, Type, ItemImpl, TypePath, parse_quote, parse::{Parse, ParseStream, Result, Error}, fold::{self, Fold}, Attribute, Pat, }; @@ -61,29 +61,14 @@ impl Parse for RuntimeApiImpls { } } -/// Implement the `ApiExt` trait, `ApiErrorExt` trait and the `Core` runtime api. +/// Implement the `ApiExt` trait and the `Core` runtime api. fn implement_common_api_traits( - error_type: Option, block_type: TypePath, self_ty: Type, ) -> Result { let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID); - let error_type = error_type - .map(|e| quote!(#e)) - .unwrap_or_else(|| quote!( #crate_::ApiError ) ); - - // Quote using the span from `error_type` to generate nice error messages when the type is - // not implementing a trait or similar. - let api_error_ext = quote_spanned! { error_type.span() => - impl #crate_::ApiErrorExt for #self_ty { - type Error = #error_type; - } - }; - Ok(quote!( - #api_error_ext - impl #crate_::ApiExt<#block_type> for #self_ty { type StateBackend = #crate_::InMemoryBackend<#crate_::HashFor<#block_type>>; @@ -97,7 +82,7 @@ fn implement_common_api_traits( fn has_api( &self, _: &#crate_::BlockId<#block_type>, - ) -> std::result::Result where Self: Sized { + ) -> std::result::Result where Self: Sized { Ok(true) } @@ -105,7 +90,7 @@ fn implement_common_api_traits( &self, _: &#crate_::BlockId<#block_type>, pred: P, - ) -> std::result::Result where Self: Sized { + ) -> std::result::Result where Self: Sized { Ok(pred(A::VERSION)) } @@ -140,7 +125,7 @@ fn implement_common_api_traits( _: #crate_::ExecutionContext, _: Option<()>, _: Vec, - ) -> std::result::Result<#crate_::NativeOrEncoded<#crate_::RuntimeVersion>, #error_type> { + ) -> std::result::Result<#crate_::NativeOrEncoded<#crate_::RuntimeVersion>, #crate_::ApiError> { unimplemented!("Not required for testing!") } @@ -150,7 +135,7 @@ fn implement_common_api_traits( _: #crate_::ExecutionContext, _: Option<#block_type>, _: Vec, - ) -> std::result::Result<#crate_::NativeOrEncoded<()>, #error_type> { + ) -> std::result::Result<#crate_::NativeOrEncoded<()>, #crate_::ApiError> { unimplemented!("Not required for testing!") } @@ -160,7 +145,7 @@ fn implement_common_api_traits( _: #crate_::ExecutionContext, _: Option<&<#block_type as #crate_::BlockT>::Header>, _: Vec, - ) -> std::result::Result<#crate_::NativeOrEncoded<()>, #error_type> { + ) -> std::result::Result<#crate_::NativeOrEncoded<()>, #crate_::ApiError> { unimplemented!("Not required for testing!") } } @@ -230,9 +215,6 @@ struct FoldRuntimeApiImpl<'a> { block_type: &'a TypePath, /// The identifier of the trait being implemented. impl_trait: &'a Ident, - /// Stores the error type that is being found in the trait implementation as associated type - /// with the name `Error`. - error_type: &'a mut Option, } impl<'a> Fold for FoldRuntimeApiImpl<'a> { @@ -300,7 +282,7 @@ impl<'a> Fold for FoldRuntimeApiImpl<'a> { // Generate the correct return type. input.sig.output = parse_quote!( - -> std::result::Result<#crate_::NativeOrEncoded<#ret_type>, Self::Error> + -> std::result::Result<#crate_::NativeOrEncoded<#ret_type>, #crate_::ApiError> ); } @@ -336,51 +318,12 @@ impl<'a> Fold for FoldRuntimeApiImpl<'a> { input.block = block; input } - - fn fold_impl_item(&mut self, input: ImplItem) -> ImplItem { - match input { - ImplItem::Type(ty) => { - if ty.ident == "Error" { - if let Some(error_type) = self.error_type { - if *error_type != ty.ty { - let mut error = Error::new( - ty.span(), - "Error type can not change between runtime apis", - ); - let error_first = Error::new( - error_type.span(), - "First error type was declared here." - ); - - error.combine(error_first); - - ImplItem::Verbatim(error.to_compile_error()) - } else { - ImplItem::Verbatim(Default::default()) - } - } else { - *self.error_type = Some(ty.ty); - ImplItem::Verbatim(Default::default()) - } - } else { - let error = Error::new( - ty.span(), - "Only associated type with name `Error` is allowed", - ); - ImplItem::Verbatim(error.to_compile_error()) - } - }, - o => fold::fold_impl_item(self, o), - } - } } /// Result of [`generate_runtime_api_impls`]. struct GeneratedRuntimeApiImpls { /// All the runtime api implementations. impls: TokenStream, - /// The error type that should be used by the runtime apis. - error_type: Option, /// The block type that is being used by the runtime apis. block_type: TypePath, /// The type the traits are implemented for. @@ -393,7 +336,6 @@ struct GeneratedRuntimeApiImpls { /// extracts the error type, self type and the block type. fn generate_runtime_api_impls(impls: &[ItemImpl]) -> Result { let mut result = Vec::with_capacity(impls.len()); - let mut error_type = None; let mut global_block_type: Option = None; let mut self_ty: Option> = None; @@ -451,7 +393,6 @@ fn generate_runtime_api_impls(impls: &[ItemImpl]) -> Result Result proc_macro fn mock_impl_runtime_apis_impl_inner(api_impls: &[ItemImpl]) -> Result { let hidden_includes = generate_hidden_includes(HIDDEN_INCLUDES_ID); - let GeneratedRuntimeApiImpls { impls, error_type, block_type, self_ty } = + let GeneratedRuntimeApiImpls { impls, block_type, self_ty } = generate_runtime_api_impls(api_impls)?; - let api_traits = implement_common_api_traits(error_type, block_type, self_ty)?; + let api_traits = implement_common_api_traits(block_type, self_ty)?; Ok(quote!( #hidden_includes diff --git a/substrate/primitives/api/proc-macro/src/utils.rs b/substrate/primitives/api/proc-macro/src/utils.rs index dbe7c723af..a7a6d35205 100644 --- a/substrate/primitives/api/proc-macro/src/utils.rs +++ b/substrate/primitives/api/proc-macro/src/utils.rs @@ -99,6 +99,7 @@ pub fn replace_wild_card_parameter_names(input: &mut Signature) { pub fn fold_fn_decl_for_client_side( input: &mut Signature, block_id: &TokenStream, + crate_: &TokenStream, ) { replace_wild_card_parameter_names(input); @@ -109,7 +110,7 @@ pub fn fold_fn_decl_for_client_side( // Wrap the output in a `Result` input.output = { let ty = return_type_extract_type(&input.output); - parse_quote!( -> std::result::Result<#ty, Self::Error> ) + parse_quote!( -> std::result::Result<#ty, #crate_::ApiError> ) }; } diff --git a/substrate/primitives/api/src/lib.rs b/substrate/primitives/api/src/lib.rs index 8ce447c0d3..592b20b62a 100644 --- a/substrate/primitives/api/src/lib.rs +++ b/substrate/primitives/api/src/lib.rs @@ -67,7 +67,7 @@ pub use sp_std::{slice, mem}; #[cfg(feature = "std")] use sp_std::result; #[doc(hidden)] -pub use codec::{Encode, Decode, DecodeLimit}; +pub use codec::{Encode, Decode, DecodeLimit, self}; use sp_core::OpaqueMetadata; #[cfg(feature = "std")] use std::{panic::UnwindSafe, cell::RefCell}; @@ -246,8 +246,8 @@ pub use sp_api_proc_macro::impl_runtime_apis; /// and the error type can be specified as associated type. If no error type is specified [`String`] /// is used as error type. /// -/// Besides implementing the given traits, the [`Core`](sp_api::Core), [`ApiExt`](sp_api::ApiExt) -/// and [`ApiErrorExt`](sp_api::ApiErrorExt) are implemented automatically. +/// Besides implementing the given traits, the [`Core`](sp_api::Core) and [`ApiExt`](sp_api::ApiExt) +/// are implemented automatically. /// /// # Example /// @@ -284,11 +284,6 @@ pub use sp_api_proc_macro::impl_runtime_apis; /// } /// /// impl BlockBuilder for MockApi { -/// /// Sets the error type that is being used by the mock implementation. -/// /// The error type is used by all runtime apis. It is only required to -/// /// be specified in one trait implementation. -/// type Error = sp_api::ApiError; -/// /// fn build_block() -> Block { /// unimplemented!("Not Required in tests") /// } @@ -331,15 +326,14 @@ pub use sp_api_proc_macro::impl_runtime_apis; /// /// sp_api::mock_impl_runtime_apis! { /// impl Balance for MockApi { -/// type Error = sp_api::ApiError; /// #[advanced] -/// fn get_balance(&self, at: &BlockId) -> Result, Self::Error> { +/// fn get_balance(&self, at: &BlockId) -> Result, sp_api::ApiError> { /// println!("Being called at: {}", at); /// /// Ok(self.balance.into()) /// } /// #[advanced] -/// fn set_balance(at: &BlockId, val: u64) -> Result, Self::Error> { +/// fn set_balance(at: &BlockId, val: u64) -> Result, sp_api::ApiError> { /// if let BlockId::Number(1) = at { /// println!("Being called to set balance to: {}", val); /// } @@ -393,46 +387,35 @@ pub trait ConstructRuntimeApi> { } /// An error describing which API call failed. -#[cfg_attr(feature = "std", derive(Debug, thiserror::Error, Eq, PartialEq))] -#[cfg_attr(feature = "std", error("Failed to execute API call {tag}"))] #[cfg(feature = "std")] -pub struct ApiError { - tag: &'static str, - #[source] - error: codec::Error, -} - -#[cfg(feature = "std")] -impl From<(&'static str, codec::Error)> for ApiError { - fn from((tag, error): (&'static str, codec::Error)) -> Self { - Self { - tag, - error, - } - } -} - -#[cfg(feature = "std")] -impl ApiError { - pub fn new(tag: &'static str, error: codec::Error) -> Self { - Self { - tag, - error, - } - } -} - -/// Extends the runtime api traits with an associated error type. This trait is given as super -/// trait to every runtime api trait. -#[cfg(feature = "std")] -pub trait ApiErrorExt { - /// Error type used by the runtime apis. - type Error: std::fmt::Debug + From; +#[derive(Debug, thiserror::Error)] +pub enum ApiError { + #[error("Failed to decode return value of {function}")] + FailedToDecodeReturnValue { + function: &'static str, + #[source] + error: codec::Error, + }, + #[error("Failed to convert return value from runtime to node of {function}")] + FailedToConvertReturnValue { + function: &'static str, + #[source] + error: codec::Error, + }, + #[error("Failed to convert parameter `{parameter}` from node to runtime of {function}")] + FailedToConvertParameter { + function: &'static str, + parameter: &'static str, + #[source] + error: codec::Error, + }, + #[error(transparent)] + Application(#[from] Box), } /// Extends the runtime api implementation with some common functionality. #[cfg(feature = "std")] -pub trait ApiExt: ApiErrorExt { +pub trait ApiExt { /// The state backend that is used to store the block states. type StateBackend: StateBackend>; @@ -450,14 +433,14 @@ pub trait ApiExt: ApiErrorExt { fn has_api( &self, at: &BlockId, - ) -> Result where Self: Sized; + ) -> Result where Self: Sized; /// Check if the given api is implemented and the version passes a predicate. fn has_api_with bool>( &self, at: &BlockId, pred: P, - ) -> Result where Self: Sized; + ) -> Result where Self: Sized; /// Start recording all accessed trie nodes for generating proofs. fn record_proof(&mut self); @@ -478,7 +461,10 @@ pub trait ApiExt: ApiErrorExt { backend: &Self::StateBackend, changes_trie_state: Option<&ChangesTrieState, NumberFor>>, parent_hash: Block::Hash, - ) -> Result, String> where Self: Sized; + ) -> Result< + StorageChanges, + String + > where Self: Sized; } /// Before calling any runtime api function, the runtime need to be initialized @@ -533,9 +519,6 @@ pub struct CallApiAtParams<'a, Block: BlockT, C, NC, Backend: StateBackend { - /// Error type used by the implementation. - type Error: std::fmt::Debug + From; - /// The state backend that is used to store the block states. type StateBackend: StateBackend>; @@ -544,15 +527,18 @@ pub trait CallApiAt { fn call_api_at< 'a, R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, - C: Core, + NC: FnOnce() -> result::Result + UnwindSafe, + C: Core, >( &self, params: CallApiAtParams<'a, Block, C, NC, Self::StateBackend>, - ) -> Result, Self::Error>; + ) -> Result, ApiError>; /// Returns the runtime version at the given block. - fn runtime_version_at(&self, at: &BlockId) -> Result; + fn runtime_version_at( + &self, + at: &BlockId, + ) -> Result; } /// Auxiliary wrapper that holds an api instance and binds it to the given lifetime. @@ -605,10 +591,6 @@ pub trait RuntimeApiInfo { const VERSION: u32; } -/// Extracts the `Api::Error` for a type that provides a runtime api. -#[cfg(feature = "std")] -pub type ApiErrorFor = <>::Api as ApiErrorExt>::Error; - #[derive(codec::Encode, codec::Decode)] pub struct OldRuntimeVersion { pub spec_name: RuntimeString, diff --git a/substrate/primitives/api/test/tests/decl_and_impl.rs b/substrate/primitives/api/test/tests/decl_and_impl.rs index 134ee50856..1f7ccf2712 100644 --- a/substrate/primitives/api/test/tests/decl_and_impl.rs +++ b/substrate/primitives/api/test/tests/decl_and_impl.rs @@ -23,7 +23,6 @@ use sp_api::{ use sp_runtime::{traits::{GetNodeBlockType, Block as BlockT}, generic::BlockId}; use sp_core::NativeOrEncoded; use substrate_test_runtime_client::runtime::Block; -use sp_blockchain::Result; /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` /// trait are done by the `construct_runtime!` macro in a real runtime. @@ -105,7 +104,7 @@ mock_impl_runtime_apis! { #[advanced] fn same_name(_: &BlockId) -> - std::result::Result< + Result< NativeOrEncoded<()>, ApiError > @@ -115,7 +114,7 @@ mock_impl_runtime_apis! { #[advanced] fn wild_card(at: &BlockId, _: u32) -> - std::result::Result< + Result< NativeOrEncoded<()>, ApiError > @@ -124,7 +123,7 @@ mock_impl_runtime_apis! { // yeah Ok(().into()) } else { - Err(ApiError::new("MockApi", codec::Error::from("Ohh noooo"))) + Err((Box::from("Test error") as Box).into()) } } } @@ -143,33 +142,33 @@ type TestClient = substrate_test_runtime_client::client::Client< #[test] fn test_client_side_function_signature() { - let _test: fn(&RuntimeApiImpl, &BlockId, u64) -> Result<()> = + let _test: fn(&RuntimeApiImpl, &BlockId, u64) -> Result<(), ApiError> = RuntimeApiImpl::::test; let _something_with_block: - fn(&RuntimeApiImpl, &BlockId, Block) -> Result = + fn(&RuntimeApiImpl, &BlockId, Block) -> Result = RuntimeApiImpl::::something_with_block; #[allow(deprecated)] let _same_name_before_version_2: - fn(&RuntimeApiImpl, &BlockId) -> Result = + fn(&RuntimeApiImpl, &BlockId) -> Result = RuntimeApiImpl::::same_name_before_version_2; } #[test] fn check_runtime_api_info() { - assert_eq!(&Api::::ID, &runtime_decl_for_Api::ID); - assert_eq!(Api::::VERSION, runtime_decl_for_Api::VERSION); - assert_eq!(Api::::VERSION, 1); + assert_eq!(&Api::::ID, &runtime_decl_for_Api::ID); + assert_eq!(Api::::VERSION, runtime_decl_for_Api::VERSION); + assert_eq!(Api::::VERSION, 1); assert_eq!( - ApiWithCustomVersion::::VERSION, + ApiWithCustomVersion::::VERSION, runtime_decl_for_ApiWithCustomVersion::VERSION, ); assert_eq!( - &ApiWithCustomVersion::::ID, + &ApiWithCustomVersion::::ID, &runtime_decl_for_ApiWithCustomVersion::ID, ); - assert_eq!(ApiWithCustomVersion::::VERSION, 2); + assert_eq!(ApiWithCustomVersion::::VERSION, 2); } fn check_runtime_api_versions_contains() { @@ -178,9 +177,9 @@ fn check_runtime_api_versions_contains() { #[test] fn check_runtime_api_versions() { - check_runtime_api_versions_contains::>(); - check_runtime_api_versions_contains::>(); - check_runtime_api_versions_contains::>(); + check_runtime_api_versions_contains::>(); + check_runtime_api_versions_contains::>(); + check_runtime_api_versions_contains::>(); } #[test] @@ -188,9 +187,9 @@ fn mock_runtime_api_has_api() { let mock = MockApi { block: None }; assert!( - mock.has_api::>(&BlockId::Number(0)).unwrap(), + mock.has_api::>(&BlockId::Number(0)).unwrap(), ); - assert!(mock.has_api::>(&BlockId::Number(0)).unwrap()); + assert!(mock.has_api::>(&BlockId::Number(0)).unwrap()); } #[test] @@ -209,7 +208,7 @@ fn mock_runtime_api_works_with_advanced() { Api::::same_name(&mock, &BlockId::Number(0)).unwrap(); mock.wild_card(&BlockId::Number(1337), 1).unwrap(); assert_eq!( - ApiError::new("MockApi", ::codec::Error::from("Ohh noooo")), - mock.wild_card(&BlockId::Number(1336), 1).unwrap_err() + "Test error".to_string(), + mock.wild_card(&BlockId::Number(1336), 1).unwrap_err().to_string(), ); } diff --git a/substrate/primitives/api/test/tests/runtime_calls.rs b/substrate/primitives/api/test/tests/runtime_calls.rs index ec1a86d837..94f419b1c4 100644 --- a/substrate/primitives/api/test/tests/runtime_calls.rs +++ b/substrate/primitives/api/test/tests/runtime_calls.rs @@ -50,10 +50,7 @@ fn calling_wasm_runtime_function() { } #[test] -#[should_panic( - expected = - "Could not convert parameter `param` between node and runtime: DecodeFails always fails" -)] +#[should_panic(expected = "FailedToConvertParameter { function: \"fail_convert_parameter\"")] fn calling_native_runtime_function_with_non_decodable_parameter() { let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::NativeWhenPossible).build(); let runtime_api = client.runtime_api(); @@ -62,7 +59,7 @@ fn calling_native_runtime_function_with_non_decodable_parameter() { } #[test] -#[should_panic(expected = "Could not convert return value from runtime to node!")] +#[should_panic(expected = "FailedToConvertReturnValue { function: \"fail_convert_return_value\"")] fn calling_native_runtime_function_with_non_decodable_return_value() { let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::NativeWhenPossible).build(); let runtime_api = client.runtime_api(); diff --git a/substrate/primitives/api/test/tests/ui/mock_only_error_associated_type.rs b/substrate/primitives/api/test/tests/ui/mock_only_error_associated_type.rs deleted file mode 100644 index bbd3c71c94..0000000000 --- a/substrate/primitives/api/test/tests/ui/mock_only_error_associated_type.rs +++ /dev/null @@ -1,19 +0,0 @@ -use substrate_test_runtime_client::runtime::Block; - -sp_api::decl_runtime_apis! { - pub trait Api { - fn test(data: u64); - } -} - -struct MockApi; - -sp_api::mock_impl_runtime_apis! { - impl Api for MockApi { - type OtherData = u32; - - fn test(data: u64) {} - } -} - -fn main() {} diff --git a/substrate/primitives/api/test/tests/ui/mock_only_error_associated_type.stderr b/substrate/primitives/api/test/tests/ui/mock_only_error_associated_type.stderr deleted file mode 100644 index beced70413..0000000000 --- a/substrate/primitives/api/test/tests/ui/mock_only_error_associated_type.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: Only associated type with name `Error` is allowed - --> $DIR/mock_only_error_associated_type.rs:13:3 - | -13 | type OtherData = u32; - | ^^^^ diff --git a/substrate/primitives/api/test/tests/ui/mock_only_one_error_type.rs b/substrate/primitives/api/test/tests/ui/mock_only_one_error_type.rs deleted file mode 100644 index 1c3f13dbb9..0000000000 --- a/substrate/primitives/api/test/tests/ui/mock_only_one_error_type.rs +++ /dev/null @@ -1,29 +0,0 @@ -use substrate_test_runtime_client::runtime::Block; - -sp_api::decl_runtime_apis! { - pub trait Api { - fn test(data: u64); - } - - pub trait Api2 { - fn test(data: u64); - } -} - -struct MockApi; - -sp_api::mock_impl_runtime_apis! { - impl Api for MockApi { - type Error = u32; - - fn test(data: u64) {} - } - - impl Api2 for MockApi { - type Error = u64; - - fn test(data: u64) {} - } -} - -fn main() {} diff --git a/substrate/primitives/api/test/tests/ui/mock_only_one_error_type.stderr b/substrate/primitives/api/test/tests/ui/mock_only_one_error_type.stderr deleted file mode 100644 index ab5b90af3a..0000000000 --- a/substrate/primitives/api/test/tests/ui/mock_only_one_error_type.stderr +++ /dev/null @@ -1,29 +0,0 @@ -error: Error type can not change between runtime apis - --> $DIR/mock_only_one_error_type.rs:23:3 - | -23 | type Error = u64; - | ^^^^ - -error: First error type was declared here. - --> $DIR/mock_only_one_error_type.rs:17:16 - | -17 | type Error = u32; - | ^^^ - -error[E0277]: the trait bound `u32: From` is not satisfied - --> $DIR/mock_only_one_error_type.rs:17:16 - | -17 | type Error = u32; - | ^^^ the trait `From` is not implemented for `u32` - | - ::: $WORKSPACE/primitives/api/src/lib.rs - | - | type Error: std::fmt::Debug + From; - | -------------- required by this bound in `sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ApiErrorExt::Error` - | - = help: the following implementations were found: - > - > - > - > - and 18 others diff --git a/substrate/primitives/blockchain/src/error.rs b/substrate/primitives/blockchain/src/error.rs index 6ed5fe1b33..58d08d06f0 100644 --- a/substrate/primitives/blockchain/src/error.rs +++ b/substrate/primitives/blockchain/src/error.rs @@ -114,8 +114,8 @@ pub enum Error { #[error("Error decoding call result of {0}")] CallResultDecode(&'static str, #[source] CodecError), - #[error(transparent)] - RuntimeApiCodecError(#[from] ApiError), + #[error("Error at calling runtime api: {0}")] + RuntimeApiError(#[from] ApiError), #[error("Runtime :code missing in storage")] RuntimeCodeMissing, @@ -153,7 +153,6 @@ pub enum Error { #[error("Failed to get header for hash {0}")] MissingHeader(String), - #[error("State Database error: {0}")] StateDatabase(String), @@ -183,6 +182,15 @@ impl From> for Error { } } +impl From for ApiError { + fn from(err: Error) -> ApiError { + match err { + Error::RuntimeApiError(err) => err, + e => ApiError::Application(Box::new(e)), + } + } +} + impl Error { /// Chain a blockchain error. pub fn from_blockchain(e: Box) -> Self { diff --git a/substrate/primitives/core/src/traits.rs b/substrate/primitives/core/src/traits.rs index 8488a1873c..15c1816331 100644 --- a/substrate/primitives/core/src/traits.rs +++ b/substrate/primitives/core/src/traits.rs @@ -34,7 +34,7 @@ pub trait CodeExecutor: Sized + Send + Sync + CallInWasm + Clone + 'static { /// or an execution error) together with a `bool`, which is true if native execution was used. fn call< R: codec::Codec + PartialEq, - NC: FnOnce() -> Result + UnwindSafe, + NC: FnOnce() -> Result> + UnwindSafe, >( &self, ext: &mut dyn Externalities, diff --git a/substrate/primitives/session/src/lib.rs b/substrate/primitives/session/src/lib.rs index 8000c23dd4..9f63d64d41 100644 --- a/substrate/primitives/session/src/lib.rs +++ b/substrate/primitives/session/src/lib.rs @@ -113,7 +113,7 @@ pub fn generate_initial_session_keys( client: std::sync::Arc, at: &BlockId, seeds: Vec, -) -> Result<(), sp_api::ApiErrorFor> +) -> Result<(), sp_api::ApiError> where Block: BlockT, T: ProvideRuntimeApi, diff --git a/substrate/primitives/state-machine/src/lib.rs b/substrate/primitives/state-machine/src/lib.rs index 31d4eacc4e..7b337620c2 100644 --- a/substrate/primitives/state-machine/src/lib.rs +++ b/substrate/primitives/state-machine/src/lib.rs @@ -392,7 +392,7 @@ mod execution { bool, ) where R: Decode + Encode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result> + UnwindSafe, { let mut cache = StorageTransactionCache::default(); @@ -449,7 +449,7 @@ mod execution { ) -> CallResult where R: Decode + Encode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result> + UnwindSafe, Handler: FnOnce( CallResult, CallResult, @@ -485,7 +485,7 @@ mod execution { ) -> CallResult where R: Decode + Encode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result> + UnwindSafe, { self.overlay.start_transaction(); let (result, was_native) = self.execute_aux( @@ -522,7 +522,7 @@ mod execution { ) -> Result, Box> where R: Decode + Encode + PartialEq, - NC: FnOnce() -> result::Result + UnwindSafe, + NC: FnOnce() -> result::Result> + UnwindSafe, Handler: FnOnce( CallResult, CallResult, @@ -869,7 +869,7 @@ mod tests { map, traits::{Externalities, RuntimeCode}, testing::TaskExecutor, }; use sp_runtime::traits::BlakeTwo256; - use std::{result, collections::HashMap}; + use std::{result, collections::HashMap, panic::UnwindSafe}; use codec::Decode; use sp_core::{ storage::ChildInfo, NativeOrEncoded, NeverNativeValue, @@ -891,7 +891,7 @@ mod tests { fn call< R: Encode + Decode + PartialEq, - NC: FnOnce() -> result::Result, + NC: FnOnce() -> result::Result> + UnwindSafe, >( &self, ext: &mut dyn Externalities, diff --git a/substrate/test-utils/runtime/client/src/block_builder_ext.rs b/substrate/test-utils/runtime/client/src/block_builder_ext.rs index 9dc27c6414..bb0f2d400b 100644 --- a/substrate/test-utils/runtime/client/src/block_builder_ext.rs +++ b/substrate/test-utils/runtime/client/src/block_builder_ext.rs @@ -43,7 +43,7 @@ pub trait BlockBuilderExt { impl<'a, A, B> BlockBuilderExt for sc_block_builder::BlockBuilder<'a, substrate_test_runtime::Block, A, B> where A: ProvideRuntimeApi + 'a, - A::Api: BlockBuilderApi + + A::Api: BlockBuilderApi + ApiExt< substrate_test_runtime::Block, StateBackend = backend::StateBackendFor