mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 01:47:55 +00:00
Simplify runtime api error handling (#8114)
* Ahh * Work work work * Fix all the compilation errors * Fix test * More fixes...
This commit is contained in:
@@ -99,7 +99,7 @@ pub fn executor() -> NativeExecutor<Executor> {
|
||||
|
||||
pub fn executor_call<
|
||||
R:Decode + Encode + PartialEq,
|
||||
NC: FnOnce() -> std::result::Result<R, String> + std::panic::UnwindSafe
|
||||
NC: FnOnce() -> std::result::Result<R, Box<dyn std::error::Error + Send + Sync>> + std::panic::UnwindSafe
|
||||
>(
|
||||
t: &mut TestExternalities<BlakeTwo256>,
|
||||
method: &str,
|
||||
|
||||
@@ -78,7 +78,7 @@ pub trait CallExecutor<B: BlockT> {
|
||||
Result<NativeOrEncoded<R>, Self::Error>
|
||||
) -> Result<NativeOrEncoded<R>, Self::Error>,
|
||||
R: Encode + Decode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, String> + UnwindSafe,
|
||||
NC: FnOnce() -> result::Result<R, sp_api::ApiError> + UnwindSafe,
|
||||
>(
|
||||
&self,
|
||||
initialize_block_fn: IB,
|
||||
|
||||
@@ -93,7 +93,7 @@ where
|
||||
Block: BlockT + Unpin + 'static,
|
||||
Network: NetworkProvider,
|
||||
Client: ProvideRuntimeApi<Block> + Send + Sync + 'static + HeaderBackend<Block>,
|
||||
<Client as ProvideRuntimeApi<Block>>::Api: AuthorityDiscoveryApi<Block, Error = sp_blockchain::Error>,
|
||||
<Client as ProvideRuntimeApi<Block>>::Api: AuthorityDiscoveryApi<Block>,
|
||||
DhtEventStream: Stream<Item = DhtEvent> + Unpin,
|
||||
{
|
||||
new_worker_and_service_with_config(
|
||||
@@ -121,7 +121,7 @@ where
|
||||
Block: BlockT + Unpin + 'static,
|
||||
Network: NetworkProvider,
|
||||
Client: ProvideRuntimeApi<Block> + Send + Sync + 'static + HeaderBackend<Block>,
|
||||
<Client as ProvideRuntimeApi<Block>>::Api: AuthorityDiscoveryApi<Block, Error = sp_blockchain::Error>,
|
||||
<Client as ProvideRuntimeApi<Block>>::Api: AuthorityDiscoveryApi<Block>,
|
||||
DhtEventStream: Stream<Item = DhtEvent> + Unpin,
|
||||
{
|
||||
let (to_worker, from_service) = mpsc::channel(0);
|
||||
|
||||
@@ -132,7 +132,7 @@ where
|
||||
Network: NetworkProvider,
|
||||
Client: ProvideRuntimeApi<Block> + Send + Sync + 'static + HeaderBackend<Block>,
|
||||
<Client as ProvideRuntimeApi<Block>>::Api:
|
||||
AuthorityDiscoveryApi<Block, Error = sp_blockchain::Error>,
|
||||
AuthorityDiscoveryApi<Block>,
|
||||
DhtEventStream: Stream<Item = DhtEvent> + 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::<HashSet<_>>();
|
||||
|
||||
@@ -100,8 +100,6 @@ pub(crate) struct RuntimeApi {
|
||||
|
||||
sp_api::mock_impl_runtime_apis! {
|
||||
impl AuthorityDiscoveryApi<Block> for RuntimeApi {
|
||||
type Error = sp_blockchain::Error;
|
||||
|
||||
fn authorities(&self) -> Vec<AuthorityId> {
|
||||
self.authorities.clone()
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ impl<B, Block, C, A> ProposerFactory<A, B, C>
|
||||
C: BlockBuilderProvider<B, Block, C> + HeaderBackend<Block> + ProvideRuntimeApi<Block>
|
||||
+ Send + Sync + 'static,
|
||||
C::Api: ApiExt<Block, StateBackend = backend::StateBackendFor<B, Block>>
|
||||
+ BlockBuilderApi<Block, Error = sp_blockchain::Error>,
|
||||
+ BlockBuilderApi<Block>,
|
||||
{
|
||||
pub fn init_with_now(
|
||||
&mut self,
|
||||
@@ -138,7 +138,7 @@ impl<A, B, Block, C> sp_consensus::Environment<Block> for
|
||||
C: BlockBuilderProvider<B, Block, C> + HeaderBackend<Block> + ProvideRuntimeApi<Block>
|
||||
+ Send + Sync + 'static,
|
||||
C::Api: ApiExt<Block, StateBackend = backend::StateBackendFor<B, Block>>
|
||||
+ BlockBuilderApi<Block, Error = sp_blockchain::Error>,
|
||||
+ BlockBuilderApi<Block>,
|
||||
{
|
||||
type CreateProposer = future::Ready<Result<Self::Proposer, Self::Error>>;
|
||||
type Proposer = Proposer<B, Block, C, A>;
|
||||
@@ -175,7 +175,7 @@ impl<A, B, Block, C> sp_consensus::Proposer<Block> for
|
||||
C: BlockBuilderProvider<B, Block, C> + HeaderBackend<Block> + ProvideRuntimeApi<Block>
|
||||
+ Send + Sync + 'static,
|
||||
C::Api: ApiExt<Block, StateBackend = backend::StateBackendFor<B, Block>>
|
||||
+ BlockBuilderApi<Block, Error = sp_blockchain::Error>,
|
||||
+ BlockBuilderApi<Block>,
|
||||
{
|
||||
type Transaction = backend::TransactionFor<B, Block>;
|
||||
type Proposal = Pin<Box<dyn Future<
|
||||
@@ -221,7 +221,7 @@ impl<A, B, Block, C> Proposer<B, Block, C, A>
|
||||
C: BlockBuilderProvider<B, Block, C> + HeaderBackend<Block> + ProvideRuntimeApi<Block>
|
||||
+ Send + Sync + 'static,
|
||||
C::Api: ApiExt<Block, StateBackend = backend::StateBackendFor<B, Block>>
|
||||
+ BlockBuilderApi<Block, Error = sp_blockchain::Error>,
|
||||
+ BlockBuilderApi<Block>,
|
||||
{
|
||||
async fn propose_with(
|
||||
self,
|
||||
|
||||
@@ -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<Block> + 'a,
|
||||
A::Api: BlockBuilderApi<Block, Error = Error> +
|
||||
ApiExt<Block, StateBackend = backend::StateBackendFor<B, Block>>,
|
||||
A::Api: BlockBuilderApi<Block> + ApiExt<Block, StateBackend = backend::StateBackendFor<B, Block>>,
|
||||
B: backend::Backend<Block>,
|
||||
{
|
||||
/// 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<Block>,
|
||||
backend: &'a B,
|
||||
) -> Result<Self, ApiErrorFor<A, Block>> {
|
||||
) -> Result<Self, Error> {
|
||||
let header = <<Block as BlockT>::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: <Block as BlockT>::Extrinsic) -> Result<(), ApiErrorFor<A, Block>> {
|
||||
pub fn push(&mut self, xt: <Block as BlockT>::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<Block, backend::StateBackendFor<B, Block>>,
|
||||
ApiErrorFor<A, Block>
|
||||
> {
|
||||
pub fn build(mut self) -> Result<BuiltBlock<Block, backend::StateBackendFor<B, Block>>, 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<Vec<Block::Extrinsic>, ApiErrorFor<A, Block>> {
|
||||
) -> Result<Vec<Block::Extrinsic>, 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)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,9 +98,9 @@ pub fn slot_duration<A, B, C>(client: &C) -> CResult<SlotDuration> where
|
||||
A: Codec,
|
||||
B: BlockT,
|
||||
C: AuxStore + ProvideRuntimeApi<B>,
|
||||
C::Api: AuraApi<B, A, Error = sp_blockchain::Error>,
|
||||
C::Api: AuraApi<B, A>,
|
||||
{
|
||||
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<C, P, CAW> AuraVerifier<C, P, CAW> where
|
||||
inherent_data: InherentData,
|
||||
timestamp_now: u64,
|
||||
) -> Result<(), Error<B>> where
|
||||
C: ProvideRuntimeApi<B>, C::Api: BlockBuilderApi<B, Error = sp_blockchain::Error>,
|
||||
C: ProvideRuntimeApi<B>, C::Api: BlockBuilderApi<B>,
|
||||
CAW: CanAuthorWith<B>,
|
||||
{
|
||||
const MAX_TIMESTAMP_DRIFT_SECS: u64 = 60;
|
||||
@@ -534,7 +534,7 @@ impl<C, P, CAW> AuraVerifier<C, P, CAW> 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<B: BlockT, C, P, CAW> Verifier<B> for AuraVerifier<C, P, CAW> where
|
||||
sc_client_api::backend::AuxStore +
|
||||
ProvideCache<B> +
|
||||
BlockOf,
|
||||
C::Api: BlockBuilderApi<B> + AuraApi<B, AuthorityId<P>> + ApiExt<B, Error = sp_blockchain::Error>,
|
||||
C::Api: BlockBuilderApi<B> + AuraApi<B, AuthorityId<P>> + ApiExt<B>,
|
||||
DigestItemFor<B>: CompatibleDigestItem<P>,
|
||||
P: Pair + Send + Sync + 'static,
|
||||
P::Public: Send + Sync + Hash + Eq + Clone + Decode + Encode + Debug + 'static,
|
||||
@@ -624,7 +624,7 @@ impl<B: BlockT, C, P, CAW> Verifier<B> for AuraVerifier<C, P, CAW> where
|
||||
// skip the inherents verification if the runtime API is old.
|
||||
if self.client
|
||||
.runtime_api()
|
||||
.has_api_with::<dyn BlockBuilderApi<B, Error = ()>, _>(
|
||||
.has_api_with::<dyn BlockBuilderApi<B>, _>(
|
||||
&BlockId::Hash(parent_hash),
|
||||
|v| v >= 2,
|
||||
)
|
||||
@@ -842,7 +842,7 @@ pub fn import_queue<B, I, C, P, S, CAW>(
|
||||
can_author_with: CAW,
|
||||
) -> Result<DefaultImportQueue<B, C>, sp_consensus::Error> where
|
||||
B: BlockT,
|
||||
C::Api: BlockBuilderApi<B> + AuraApi<B, AuthorityId<P>> + ApiExt<B, Error = sp_blockchain::Error>,
|
||||
C::Api: BlockBuilderApi<B> + AuraApi<B, AuthorityId<P>> + ApiExt<B>,
|
||||
C: 'static + ProvideRuntimeApi<B> + BlockOf + ProvideCache<B> + Send + Sync + AuxStore + HeaderBackend<B>,
|
||||
I: BlockImport<B, Error=ConsensusError, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync + 'static,
|
||||
DigestItemFor<B>: CompatibleDigestItem<P>,
|
||||
|
||||
@@ -273,6 +273,8 @@ pub enum Error<B: BlockT> {
|
||||
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<B: BlockT, C>(client: &C) -> ClientResult<Self> where
|
||||
C: AuxStore + ProvideRuntimeApi<B>, C::Api: BabeApi<B, Error = sp_blockchain::Error>,
|
||||
C: AuxStore + ProvideRuntimeApi<B>, C::Api: BabeApi<B>,
|
||||
{
|
||||
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::<dyn BabeApi<B, Error = sp_blockchain::Error>, _>(
|
||||
let has_api_v1 = a.has_api_with::<dyn BabeApi<B>, _>(
|
||||
&b, |v| v == 1,
|
||||
)?;
|
||||
let has_api_v2 = a.has_api_with::<dyn BabeApi<B, Error = sp_blockchain::Error>, _>(
|
||||
let has_api_v2 = a.has_api_with::<dyn BabeApi<B>, _>(
|
||||
&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<Block, Client, SelectChain, CAW> BabeVerifier<Block, Client, SelectChain, C
|
||||
where
|
||||
Block: BlockT,
|
||||
Client: AuxStore + HeaderBackend<Block> + HeaderMetadata<Block> + ProvideRuntimeApi<Block>,
|
||||
Client::Api: BlockBuilderApi<Block, Error = sp_blockchain::Error>
|
||||
+ BabeApi<Block, Error = sp_blockchain::Error>,
|
||||
Client::Api: BlockBuilderApi<Block> + BabeApi<Block>,
|
||||
SelectChain: sp_consensus::SelectChain<Block>,
|
||||
CAW: CanAuthorWith<Block>,
|
||||
{
|
||||
@@ -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<Block, Error = sp_blockchain::Error> + HeaderBackend<Block> + ProvideRuntimeApi<Block>
|
||||
+ Send + Sync + AuxStore + ProvideCache<Block>,
|
||||
Client::Api: BlockBuilderApi<Block, Error = sp_blockchain::Error> + BabeApi<Block, Error = sp_blockchain::Error>,
|
||||
Client::Api: BlockBuilderApi<Block> + BabeApi<Block>,
|
||||
SelectChain: sp_consensus::SelectChain<Block>,
|
||||
CAW: CanAuthorWith<Block> + Send + Sync,
|
||||
{
|
||||
@@ -1498,7 +1499,7 @@ pub fn import_queue<Block: BlockT, Client, SelectChain, Inner, CAW>(
|
||||
+ Send + Sync + 'static,
|
||||
Client: ProvideRuntimeApi<Block> + ProvideCache<Block> + Send + Sync + AuxStore + 'static,
|
||||
Client: HeaderBackend<Block> + HeaderMetadata<Block, Error = sp_blockchain::Error>,
|
||||
Client::Api: BlockBuilderApi<Block> + BabeApi<Block> + ApiExt<Block, Error = sp_blockchain::Error>,
|
||||
Client::Api: BlockBuilderApi<Block> + BabeApi<Block> + ApiExt<Block>,
|
||||
SelectChain: sp_consensus::SelectChain<Block> + 'static,
|
||||
CAW: CanAuthorWith<Block> + Send + Sync + 'static,
|
||||
{
|
||||
|
||||
@@ -73,7 +73,7 @@ impl<B, C> BabeConsensusDataProvider<B, C>
|
||||
where
|
||||
B: BlockT,
|
||||
C: AuxStore + HeaderBackend<B> + ProvideRuntimeApi<B> + HeaderMetadata<B, Error = sp_blockchain::Error>,
|
||||
C::Api: BabeApi<B, Error = sp_blockchain::Error>,
|
||||
C::Api: BabeApi<B>,
|
||||
{
|
||||
pub fn new(
|
||||
client: Arc<C>,
|
||||
@@ -131,7 +131,7 @@ impl<B, C> ConsensusDataProvider<B> for BabeConsensusDataProvider<B, C>
|
||||
where
|
||||
B: BlockT,
|
||||
C: AuxStore + HeaderBackend<B> + HeaderMetadata<B, Error = sp_blockchain::Error> + ProvideRuntimeApi<B>,
|
||||
C::Api: BabeApi<B, Error = sp_blockchain::Error>,
|
||||
C::Api: BabeApi<B>,
|
||||
{
|
||||
type Transaction = TransactionFor<C, B>;
|
||||
|
||||
@@ -259,7 +259,7 @@ impl SlotTimestampProvider {
|
||||
where
|
||||
B: BlockT,
|
||||
C: AuxStore + HeaderBackend<B> + ProvideRuntimeApi<B>,
|
||||
C::Api: BabeApi<B, Error = sp_blockchain::Error>,
|
||||
C::Api: BabeApi<B>,
|
||||
{
|
||||
let slot_duration = Config::get_or_compute(&*client)?.slot_duration;
|
||||
let info = client.info();
|
||||
|
||||
@@ -232,7 +232,7 @@ impl<B, I, C, S, Algorithm, CAW> PowBlockImport<B, I, C, S, Algorithm, CAW> wher
|
||||
I: BlockImport<B, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync,
|
||||
I::Error: Into<ConsensusError>,
|
||||
C: ProvideRuntimeApi<B> + Send + Sync + HeaderBackend<B> + AuxStore + ProvideCache<B> + BlockOf,
|
||||
C::Api: BlockBuilderApi<B, Error = sp_blockchain::Error>,
|
||||
C::Api: BlockBuilderApi<B>,
|
||||
Algorithm: PowAlgorithm<B>,
|
||||
CAW: CanAuthorWith<B>,
|
||||
{
|
||||
@@ -284,7 +284,7 @@ impl<B, I, C, S, Algorithm, CAW> PowBlockImport<B, I, C, S, Algorithm, CAW> 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<B, I, C, S, Algorithm, CAW> BlockImport<B> for PowBlockImport<B, I, C, S, A
|
||||
I::Error: Into<ConsensusError>,
|
||||
S: SelectChain<B>,
|
||||
C: ProvideRuntimeApi<B> + Send + Sync + HeaderBackend<B> + AuxStore + ProvideCache<B> + BlockOf,
|
||||
C::Api: BlockBuilderApi<B, Error = sp_blockchain::Error>,
|
||||
C::Api: BlockBuilderApi<B>,
|
||||
Algorithm: PowAlgorithm<B>,
|
||||
Algorithm::Difficulty: 'static,
|
||||
CAW: CanAuthorWith<B>,
|
||||
|
||||
@@ -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<dyn std::error::Error + Send + Sync>),
|
||||
|
||||
#[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),
|
||||
}
|
||||
|
||||
@@ -456,7 +456,7 @@ impl<D: NativeExecutionDispatch + 'static> CodeExecutor for NativeExecutor<D> {
|
||||
|
||||
fn call<
|
||||
R: Decode + Encode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, String> + UnwindSafe,
|
||||
NC: FnOnce() -> result::Result<R, Box<dyn std::error::Error + Send + Sync>> + UnwindSafe,
|
||||
>(
|
||||
&self,
|
||||
ext: &mut dyn Externalities,
|
||||
@@ -514,7 +514,7 @@ impl<D: NativeExecutionDispatch + 'static> CodeExecutor for NativeExecutor<D> {
|
||||
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)
|
||||
|
||||
@@ -414,7 +414,7 @@ mod tests {
|
||||
authoring_version: 1,
|
||||
spec_version: 1,
|
||||
impl_version: 1,
|
||||
apis: sp_api::create_apis_vec!([(Core::<Block, Error = ()>::ID, 1)]),
|
||||
apis: sp_api::create_apis_vec!([(Core::<Block>::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::<Block, Error = ()>::ID, 3)]),
|
||||
apis: sp_api::create_apis_vec!([(Core::<Block>::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::<Block, Error = ()>::ID, 3)]),
|
||||
apis: sp_api::create_apis_vec!([(Core::<Block>::ID, 3)]),
|
||||
transaction_version: 3,
|
||||
};
|
||||
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -480,7 +480,7 @@ where
|
||||
Block: BlockT,
|
||||
BE: Backend<Block>,
|
||||
C: crate::ClientForGrandpa<Block, BE>,
|
||||
C::Api: GrandpaApi<Block, Error = sp_blockchain::Error>,
|
||||
C::Api: GrandpaApi<Block>,
|
||||
N: NetworkT<Block>,
|
||||
SC: SelectChain<Block> + '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<Block>,
|
||||
C: crate::ClientForGrandpa<Block, B> + 'static,
|
||||
C::Api: GrandpaApi<Block, Error = sp_blockchain::Error>,
|
||||
C::Api: GrandpaApi<Block>,
|
||||
N: NetworkT<Block> + 'static + Send + Sync,
|
||||
SC: SelectChain<Block> + 'static,
|
||||
VR: VotingRule<Block, C>,
|
||||
|
||||
@@ -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(_) => {
|
||||
|
||||
@@ -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<GrandpaError> for Error {
|
||||
@@ -698,7 +700,7 @@ where
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
DigestFor<Block>: Encode,
|
||||
C: ClientForGrandpa<Block, BE> + 'static,
|
||||
C::Api: GrandpaApi<Block, Error = sp_blockchain::Error>,
|
||||
C::Api: GrandpaApi<Block>,
|
||||
{
|
||||
let GrandpaParams {
|
||||
mut config,
|
||||
@@ -824,7 +826,7 @@ where
|
||||
Block: BlockT,
|
||||
B: Backend<Block> + 'static,
|
||||
C: ClientForGrandpa<Block, B> + 'static,
|
||||
C::Api: GrandpaApi<Block, Error = sp_blockchain::Error>,
|
||||
C::Api: GrandpaApi<Block>,
|
||||
N: NetworkT<Block> + Sync,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
SC: SelectChain<Block> + 'static,
|
||||
@@ -1042,7 +1044,7 @@ where
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
SC: SelectChain<Block> + 'static,
|
||||
C: ClientForGrandpa<Block, B> + 'static,
|
||||
C::Api: GrandpaApi<Block, Error = sp_blockchain::Error>,
|
||||
C::Api: GrandpaApi<Block>,
|
||||
VR: VotingRule<Block, C> + Clone + 'static,
|
||||
{
|
||||
type Output = Result<(), Error>;
|
||||
|
||||
@@ -174,8 +174,6 @@ impl ProvideRuntimeApi<Block> for TestApi {
|
||||
|
||||
sp_api::mock_impl_runtime_apis! {
|
||||
impl GrandpaApi<Block> for RuntimeApi {
|
||||
type Error = sp_blockchain::Error;
|
||||
|
||||
fn grandpa_authorities(&self) -> AuthorityList {
|
||||
self.inner.genesis_authorities.clone()
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ impl<Block, B, Local> CallExecutor<Block> for
|
||||
Result<NativeOrEncoded<R>, Self::Error>
|
||||
) -> Result<NativeOrEncoded<R>, Self::Error>,
|
||||
R: Encode + Decode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, String> + UnwindSafe,
|
||||
NC: FnOnce() -> result::Result<R, sp_api::ApiError> + UnwindSafe,
|
||||
>(
|
||||
&self,
|
||||
initialize_block_fn: IB,
|
||||
|
||||
@@ -132,10 +132,10 @@ impl<Client, Storage, Block> OffchainWorkers<
|
||||
) -> impl Future<Output = ()> {
|
||||
let runtime = self.client.runtime_api();
|
||||
let at = BlockId::hash(header.hash());
|
||||
let has_api_v1 = runtime.has_api_with::<dyn OffchainWorkerApi<Block, Error = ()>, _>(
|
||||
let has_api_v1 = runtime.has_api_with::<dyn OffchainWorkerApi<Block>, _>(
|
||||
&at, |v| v == 1
|
||||
);
|
||||
let has_api_v2 = runtime.has_api_with::<dyn OffchainWorkerApi<Block, Error = ()>, _>(
|
||||
let has_api_v2 = runtime.has_api_with::<dyn OffchainWorkerApi<Block>, _>(
|
||||
&at, |v| v == 2
|
||||
);
|
||||
let version = match (has_api_v1, has_api_v2) {
|
||||
|
||||
@@ -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<P, Client> AuthorApi<TxHash<P>, BlockHash<P>> for Author<P, Client>
|
||||
where
|
||||
P: TransactionPool + Sync + Send + 'static,
|
||||
Client: HeaderBackend<P::Block> + ProvideRuntimeApi<P::Block> + Send + Sync + 'static,
|
||||
Client::Api: SessionKeys<P::Block, Error = ClientError>,
|
||||
Client::Api: SessionKeys<P::Block>,
|
||||
{
|
||||
type Metadata = crate::Metadata;
|
||||
|
||||
|
||||
@@ -178,9 +178,8 @@ pub fn new_full<BE, Block: BlockT, Client>(
|
||||
BE: Backend<Block> + 'static,
|
||||
Client: ExecutorProvider<Block> + StorageProvider<Block, BE> + ProofProvider<Block> + HeaderBackend<Block>
|
||||
+ HeaderMetadata<Block, Error = sp_blockchain::Error> + BlockchainEvents<Block>
|
||||
+ CallApiAt<Block, Error = sp_blockchain::Error>
|
||||
+ ProvideRuntimeApi<Block> + Send + Sync + 'static,
|
||||
Client::Api: Metadata<Block, Error = sp_blockchain::Error>,
|
||||
+ CallApiAt<Block> + ProvideRuntimeApi<Block> + Send + Sync + 'static,
|
||||
Client::Api: Metadata<Block>,
|
||||
{
|
||||
let child_backend = Box::new(
|
||||
self::state_full::FullState::new(client.clone(), subscriptions.clone())
|
||||
|
||||
@@ -223,9 +223,9 @@ impl<BE, Block, Client> StateBackend<Block, Client> for FullState<BE, Block, Cli
|
||||
BE: Backend<Block> + 'static,
|
||||
Client: ExecutorProvider<Block> + StorageProvider<Block, BE> + ProofProvider<Block> + HeaderBackend<Block>
|
||||
+ HeaderMetadata<Block, Error = sp_blockchain::Error> + BlockchainEvents<Block>
|
||||
+ CallApiAt<Block, Error = sp_blockchain::Error> + ProvideRuntimeApi<Block>
|
||||
+ CallApiAt<Block> + ProvideRuntimeApi<Block>
|
||||
+ Send + Sync + 'static,
|
||||
Client::Api: Metadata<Block, Error = sp_blockchain::Error>,
|
||||
Client::Api: Metadata<Block>,
|
||||
{
|
||||
fn call(
|
||||
&self,
|
||||
@@ -344,17 +344,23 @@ impl<BE, Block, Client> StateBackend<Block, Client> for FullState<BE, Block, Cli
|
||||
fn metadata(&self, block: Option<Block::Hash>) -> FutureResult<Bytes> {
|
||||
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<Block::Hash>) -> FutureResult<RuntimeVersion> {
|
||||
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<BE, Block, Client> StateBackend<Block, Client> for FullState<BE, Block, Cli
|
||||
let info = client.info();
|
||||
let version = client
|
||||
.runtime_version_at(&BlockId::hash(info.best_hash))
|
||||
.map_err(client_err)
|
||||
.map_err(|e| Error::Client(Box::new(e)))
|
||||
.map_err(Into::into);
|
||||
if previous_version != version {
|
||||
previous_version = version.clone();
|
||||
@@ -528,9 +534,9 @@ impl<BE, Block, Client> ChildStateBackend<Block, Client> for FullState<BE, Block
|
||||
BE: Backend<Block> + 'static,
|
||||
Client: ExecutorProvider<Block> + StorageProvider<Block, BE> + HeaderBackend<Block>
|
||||
+ HeaderMetadata<Block, Error = sp_blockchain::Error> + BlockchainEvents<Block>
|
||||
+ CallApiAt<Block, Error = sp_blockchain::Error> + ProvideRuntimeApi<Block>
|
||||
+ CallApiAt<Block> + ProvideRuntimeApi<Block>
|
||||
+ Send + Sync + 'static,
|
||||
Client::Api: Metadata<Block, Error = sp_blockchain::Error>,
|
||||
Client::Api: Metadata<Block>,
|
||||
{
|
||||
fn storage_keys(
|
||||
&self,
|
||||
|
||||
@@ -542,14 +542,13 @@ pub fn spawn_tasks<TBl, TBackend, TExPool, TRpc, TCl>(
|
||||
TCl: ProvideRuntimeApi<TBl> + HeaderMetadata<TBl, Error=sp_blockchain::Error> + Chain<TBl> +
|
||||
BlockBackend<TBl> + BlockIdTo<TBl, Error=sp_blockchain::Error> + ProofProvider<TBl> +
|
||||
HeaderBackend<TBl> + BlockchainEvents<TBl> + ExecutorProvider<TBl> + UsageProvider<TBl> +
|
||||
StorageProvider<TBl, TBackend> + CallApiAt<TBl, Error=sp_blockchain::Error> +
|
||||
StorageProvider<TBl, TBackend> + CallApiAt<TBl> +
|
||||
Send + 'static,
|
||||
<TCl as ProvideRuntimeApi<TBl>>::Api:
|
||||
sp_api::Metadata<TBl> +
|
||||
sc_offchain::OffchainWorkerApi<TBl> +
|
||||
sp_transaction_pool::runtime_api::TaggedTransactionQueue<TBl> +
|
||||
sp_session::SessionKeys<TBl> +
|
||||
sp_api::ApiErrorExt<Error = sp_blockchain::Error> +
|
||||
sp_api::ApiExt<TBl, StateBackend = TBackend::State>,
|
||||
TBl: BlockT,
|
||||
TBackend: 'static + sc_client_api::backend::Backend<TBl> + Send,
|
||||
@@ -578,7 +577,7 @@ pub fn spawn_tasks<TBl, TBackend, TExPool, TRpc, TCl>(
|
||||
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, TBackend, TExPool, TRpc, TCl>(
|
||||
TBl: BlockT,
|
||||
TCl: ProvideRuntimeApi<TBl> + BlockchainEvents<TBl> + HeaderBackend<TBl> +
|
||||
HeaderMetadata<TBl, Error=sp_blockchain::Error> + ExecutorProvider<TBl> +
|
||||
CallApiAt<TBl, Error=sp_blockchain::Error> + ProofProvider<TBl> +
|
||||
CallApiAt<TBl> + ProofProvider<TBl> +
|
||||
StorageProvider<TBl, TBackend> + BlockBackend<TBl> + Send + Sync + 'static,
|
||||
TExPool: MaintainedTransactionPool<Block=TBl, Hash = <TBl as BlockT>::Hash> + 'static,
|
||||
TBackend: sc_client_api::backend::Backend<TBl> + 'static,
|
||||
TRpc: sc_rpc::RpcExtension<sc_rpc::Metadata>,
|
||||
<TCl as ProvideRuntimeApi<TBl>>::Api:
|
||||
sp_session::SessionKeys<TBl> +
|
||||
sp_api::Metadata<TBl, Error = sp_blockchain::Error>,
|
||||
sp_api::Metadata<TBl>,
|
||||
{
|
||||
use sc_rpc::{chain, state, author, system, offchain};
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ where
|
||||
Result<NativeOrEncoded<R>, Self::Error>
|
||||
) -> Result<NativeOrEncoded<R>, Self::Error>,
|
||||
R: Encode + Decode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, String> + UnwindSafe,
|
||||
NC: FnOnce() -> result::Result<R, sp_api::ApiError> + 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)
|
||||
}
|
||||
|
||||
@@ -604,7 +604,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
||||
new_cache: HashMap<CacheKeyId, Vec<u8>>,
|
||||
) -> sp_blockchain::Result<ImportResult> where
|
||||
Self: ProvideRuntimeApi<Block>,
|
||||
<Self as ProvideRuntimeApi<Block>>::Api: CoreApi<Block, Error = Error> +
|
||||
<Self as ProvideRuntimeApi<Block>>::Api: CoreApi<Block> +
|
||||
ApiExt<Block, StateBackend = B::State>,
|
||||
{
|
||||
let BlockImportParams {
|
||||
@@ -696,7 +696,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
||||
import_existing: bool,
|
||||
) -> sp_blockchain::Result<ImportResult> where
|
||||
Self: ProvideRuntimeApi<Block>,
|
||||
<Self as ProvideRuntimeApi<Block>>::Api: CoreApi<Block, Error = Error> +
|
||||
<Self as ProvideRuntimeApi<Block>>::Api: CoreApi<Block> +
|
||||
ApiExt<Block, StateBackend = B::State>,
|
||||
{
|
||||
let parent_hash = import_headers.post().parent_hash().clone();
|
||||
@@ -838,7 +838,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
||||
) -> sp_blockchain::Result<Option<ImportResult>>
|
||||
where
|
||||
Self: ProvideRuntimeApi<Block>,
|
||||
<Self as ProvideRuntimeApi<Block>>::Api: CoreApi<Block, Error = Error> +
|
||||
<Self as ProvideRuntimeApi<Block>>::Api: CoreApi<Block> +
|
||||
ApiExt<Block, StateBackend = B::State>,
|
||||
{
|
||||
let parent_hash = import_block.header.parent_hash();
|
||||
@@ -1272,7 +1272,7 @@ impl<B, E, Block, RA> BlockBuilderProvider<B, Block, Self> for Client<B, E, Bloc
|
||||
Block: BlockT,
|
||||
Self: ChainHeaderBackend<Block> + ProvideRuntimeApi<Block>,
|
||||
<Self as ProvideRuntimeApi<Block>>::Api: ApiExt<Block, StateBackend = backend::StateBackendFor<B, Block>>
|
||||
+ BlockBuilderApi<Block, Error = Error>,
|
||||
+ BlockBuilderApi<Block>,
|
||||
{
|
||||
fn new_block_at<R: Into<RecordProof>>(
|
||||
&self,
|
||||
@@ -1628,18 +1628,17 @@ impl<B, E, Block, RA> CallApiAt<Block> for Client<B, E, Block, RA> where
|
||||
E: CallExecutor<Block, Backend = B> + Send + Sync,
|
||||
Block: BlockT,
|
||||
{
|
||||
type Error = Error;
|
||||
type StateBackend = B::State;
|
||||
|
||||
fn call_api_at<
|
||||
'a,
|
||||
R: Encode + Decode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, String> + UnwindSafe,
|
||||
C: CoreApi<Block, Error = Error>,
|
||||
NC: FnOnce() -> result::Result<R, sp_api::ApiError> + UnwindSafe,
|
||||
C: CoreApi<Block>,
|
||||
>(
|
||||
&self,
|
||||
params: CallApiAtParams<'a, Block, C, NC, B::State>,
|
||||
) -> sp_blockchain::Result<NativeOrEncoded<R>> {
|
||||
) -> Result<NativeOrEncoded<R>, sp_api::ApiError> {
|
||||
let core_api = params.core_api;
|
||||
let at = params.at;
|
||||
|
||||
@@ -1649,7 +1648,9 @@ impl<B, E, Block, RA> CallApiAt<Block> for Client<B, E, Block, RA> 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<B, E, Block, RA> CallApiAt<Block> for Client<B, E, Block, RA> where
|
||||
params.native_call,
|
||||
params.recorder,
|
||||
Some(extensions),
|
||||
)
|
||||
).map_err(Into::into)
|
||||
}
|
||||
|
||||
fn runtime_version_at(&self, at: &BlockId<Block>) -> sp_blockchain::Result<RuntimeVersion> {
|
||||
self.runtime_version_at(at)
|
||||
fn runtime_version_at(
|
||||
&self,
|
||||
at: &BlockId<Block>,
|
||||
) -> Result<RuntimeVersion, sp_api::ApiError> {
|
||||
self.runtime_version_at(at).map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1676,7 +1680,7 @@ impl<B, E, Block, RA> sp_consensus::BlockImport<Block> for &Client<B, E, Block,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
Block: BlockT,
|
||||
Client<B, E, Block, RA>: ProvideRuntimeApi<Block>,
|
||||
<Client<B, E, Block, RA> as ProvideRuntimeApi<Block>>::Api: CoreApi<Block, Error = Error> +
|
||||
<Client<B, E, Block, RA> as ProvideRuntimeApi<Block>>::Api: CoreApi<Block> +
|
||||
ApiExt<Block, StateBackend = B::State>,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
@@ -1776,7 +1780,7 @@ impl<B, E, Block, RA> sp_consensus::BlockImport<Block> for Client<B, E, Block, R
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
Block: BlockT,
|
||||
Self: ProvideRuntimeApi<Block>,
|
||||
<Self as ProvideRuntimeApi<Block>>::Api: CoreApi<Block, Error = Error> +
|
||||
<Self as ProvideRuntimeApi<Block>>::Api: CoreApi<Block> +
|
||||
ApiExt<Block, StateBackend = B::State>,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
@@ -1935,7 +1939,7 @@ impl<B, E, Block, RA> backend::AuxStore for Client<B, E, Block, RA>
|
||||
E: CallExecutor<Block>,
|
||||
Block: BlockT,
|
||||
Self: ProvideRuntimeApi<Block>,
|
||||
<Self as ProvideRuntimeApi<Block>>::Api: CoreApi<Block, Error = Error>,
|
||||
<Self as ProvideRuntimeApi<Block>>::Api: CoreApi<Block>,
|
||||
{
|
||||
/// Insert auxiliary data into key-value store.
|
||||
fn insert_aux<
|
||||
@@ -1965,7 +1969,7 @@ impl<B, E, Block, RA> backend::AuxStore for &Client<B, E, Block, RA>
|
||||
E: CallExecutor<Block>,
|
||||
Block: BlockT,
|
||||
Client<B, E, Block, RA>: ProvideRuntimeApi<Block>,
|
||||
<Client<B, E, Block, RA> as ProvideRuntimeApi<Block>>::Api: CoreApi<Block, Error = Error>,
|
||||
<Client<B, E, Block, RA> as ProvideRuntimeApi<Block>>::Api: CoreApi<Block>,
|
||||
{
|
||||
fn insert_aux<
|
||||
'a,
|
||||
|
||||
@@ -33,13 +33,13 @@ pub type Result<T> = std::result::Result<T, Error>;
|
||||
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),
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ impl CallExecutor<Block> for DummyCallExecutor {
|
||||
Result<NativeOrEncoded<R>, Self::Error>
|
||||
) -> Result<NativeOrEncoded<R>, Self::Error>,
|
||||
R: Encode + Decode + PartialEq,
|
||||
NC: FnOnce() -> Result<R, String> + UnwindSafe,
|
||||
NC: FnOnce() -> Result<R, sp_api::ApiError> + UnwindSafe,
|
||||
>(
|
||||
&self,
|
||||
_initialize_block_fn: IB,
|
||||
|
||||
@@ -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!(
|
||||
|
||||
@@ -84,7 +84,6 @@ where
|
||||
Client: ProvideRuntimeApi<Block> + BlockBackend<Block> + BlockIdTo<Block>,
|
||||
Client: Send + Sync + 'static,
|
||||
Client::Api: TaggedTransactionQueue<Block>,
|
||||
sp_api::ApiErrorFor<Client, Block>: Send + std::fmt::Display,
|
||||
{
|
||||
type Block = Block;
|
||||
type Error = error::Error;
|
||||
@@ -166,14 +165,13 @@ where
|
||||
Client: ProvideRuntimeApi<Block> + BlockBackend<Block> + BlockIdTo<Block>,
|
||||
Client: Send + Sync + 'static,
|
||||
Client::Api: TaggedTransactionQueue<Block>,
|
||||
sp_api::ApiErrorFor<Client, Block>: 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::<dyn TaggedTransactionQueue<Block, Error=()>, _>(&at, |v| v >= 2)
|
||||
.has_api_with::<dyn TaggedTransactionQueue<Block>, _>(&at, |v| v >= 2)
|
||||
.unwrap_or_default()
|
||||
};
|
||||
|
||||
@@ -198,7 +196,6 @@ where
|
||||
Client: ProvideRuntimeApi<Block> + BlockBackend<Block> + BlockIdTo<Block>,
|
||||
Client: Send + Sync + 'static,
|
||||
Client::Api: TaggedTransactionQueue<Block>,
|
||||
sp_api::ApiErrorFor<Client, Block>: Send + std::fmt::Display,
|
||||
{
|
||||
/// Validates a transaction by calling into the runtime, same as
|
||||
/// `validate_transaction` but blocks the current thread when performing
|
||||
|
||||
@@ -360,7 +360,6 @@ where
|
||||
+ sp_runtime::traits::BlockIdTo<Block>,
|
||||
Client: sc_client_api::ExecutorProvider<Block> + Send + Sync + 'static,
|
||||
Client::Api: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>,
|
||||
sp_api::ApiErrorFor<Client, Block>: 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<Block>,
|
||||
Client: Send + Sync + 'static,
|
||||
Client::Api: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>,
|
||||
sp_api::ApiErrorFor<Client, Block>: Send + std::fmt::Display,
|
||||
{
|
||||
type Block = Block;
|
||||
type Hash = sc_transaction_graph::ExtrinsicHash<FullChainApi<Client, Block>>;
|
||||
|
||||
@@ -187,14 +187,15 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result<TokenStream> {
|
||||
result.push(quote!(
|
||||
#[cfg(any(feature = "std", test))]
|
||||
fn convert_between_block_types
|
||||
<I: #crate_::Encode, R: #crate_::Decode>(
|
||||
input: &I, error_desc: &'static str,
|
||||
) -> std::result::Result<R, String>
|
||||
<I: #crate_::Encode, R: #crate_::Decode, F: FnOnce(#crate_::codec::Error) -> #crate_::ApiError>(
|
||||
input: &I,
|
||||
map_error: F,
|
||||
) -> std::result::Result<R, #crate_::ApiError>
|
||||
{
|
||||
<R as #crate_::DecodeLimit>::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<TokenStream> {
|
||||
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<TokenStream> {
|
||||
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<TokenStream> {
|
||||
#[cfg(any(feature = "std", test))]
|
||||
pub fn #fn_name<
|
||||
R: #crate_::Encode + #crate_::Decode + PartialEq,
|
||||
NC: FnOnce() -> std::result::Result<R, String> + std::panic::UnwindSafe,
|
||||
NC: FnOnce() -> std::result::Result<R, #crate_::ApiError> + std::panic::UnwindSafe,
|
||||
Block: #crate_::BlockT,
|
||||
T: #crate_::CallApiAt<Block>,
|
||||
C: #crate_::Core<Block, Error = T::Error>,
|
||||
C: #crate_::Core<Block>,
|
||||
>(
|
||||
call_runtime_at: &T,
|
||||
core_api: &C,
|
||||
@@ -416,7 +427,7 @@ fn generate_call_api_at_calls(decl: &ItemTrait) -> Result<TokenStream> {
|
||||
native_call: Option<NC>,
|
||||
context: #crate_::ExecutionContext,
|
||||
recorder: &Option<#crate_::ProofRecorder<Block>>,
|
||||
) -> std::result::Result<#crate_::NativeOrEncoded<R>, T::Error> {
|
||||
) -> std::result::Result<#crate_::NativeOrEncoded<R>, #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<u8>,
|
||||
) -> 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))]
|
||||
|
||||
@@ -233,16 +233,6 @@ fn generate_runtime_api_base_structures() -> Result<TokenStream> {
|
||||
C::StateBackend: #crate_::StateBackend<#crate_::HashFor<Block>>,
|
||||
{}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<Block: #crate_::BlockT, C: #crate_::CallApiAt<Block>> #crate_::ApiErrorExt
|
||||
for RuntimeApiImpl<Block, C>
|
||||
where
|
||||
// Rust bug: https://github.com/rust-lang/rust/issues/24159
|
||||
C::StateBackend: #crate_::StateBackend<#crate_::HashFor<Block>>,
|
||||
{
|
||||
type Error = C::Error;
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<Block: #crate_::BlockT, C: #crate_::CallApiAt<Block>> #crate_::ApiExt<Block> for
|
||||
RuntimeApiImpl<Block, C>
|
||||
@@ -269,16 +259,20 @@ fn generate_runtime_api_base_structures() -> Result<TokenStream> {
|
||||
fn has_api<A: #crate_::RuntimeApiInfo + ?Sized>(
|
||||
&self,
|
||||
at: &#crate_::BlockId<Block>,
|
||||
) -> std::result::Result<bool, C::Error> where Self: Sized {
|
||||
self.call.runtime_version_at(at).map(|v| v.has_api_with(&A::ID, |v| v == A::VERSION))
|
||||
) -> std::result::Result<bool, #crate_::ApiError> 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<A: #crate_::RuntimeApiInfo + ?Sized, P: Fn(u32) -> bool>(
|
||||
&self,
|
||||
at: &#crate_::BlockId<Block>,
|
||||
pred: P,
|
||||
) -> std::result::Result<bool, C::Error> where Self: Sized {
|
||||
self.call.runtime_version_at(at).map(|v| v.has_api_with(&A::ID, pred))
|
||||
) -> std::result::Result<bool, #crate_::ApiError> 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<TokenStream> {
|
||||
>>,
|
||||
parent_hash: Block::Hash,
|
||||
) -> std::result::Result<
|
||||
#crate_::StorageChanges<Self::StateBackend, Block>,
|
||||
#crate_::StorageChanges<C::StateBackend, Block>,
|
||||
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;
|
||||
|
||||
@@ -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<Type>,
|
||||
block_type: TypePath,
|
||||
self_ty: Type,
|
||||
) -> Result<TokenStream> {
|
||||
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<A: #crate_::RuntimeApiInfo + ?Sized>(
|
||||
&self,
|
||||
_: &#crate_::BlockId<#block_type>,
|
||||
) -> std::result::Result<bool, #error_type> where Self: Sized {
|
||||
) -> std::result::Result<bool, #crate_::ApiError> where Self: Sized {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
@@ -105,7 +90,7 @@ fn implement_common_api_traits(
|
||||
&self,
|
||||
_: &#crate_::BlockId<#block_type>,
|
||||
pred: P,
|
||||
) -> std::result::Result<bool, #error_type> where Self: Sized {
|
||||
) -> std::result::Result<bool, #crate_::ApiError> where Self: Sized {
|
||||
Ok(pred(A::VERSION))
|
||||
}
|
||||
|
||||
@@ -140,7 +125,7 @@ fn implement_common_api_traits(
|
||||
_: #crate_::ExecutionContext,
|
||||
_: Option<()>,
|
||||
_: Vec<u8>,
|
||||
) -> 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<u8>,
|
||||
) -> 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<u8>,
|
||||
) -> 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<Type>,
|
||||
}
|
||||
|
||||
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<Type>,
|
||||
/// 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<GeneratedRuntimeApiImpls> {
|
||||
let mut result = Vec::with_capacity(impls.len());
|
||||
let mut error_type = None;
|
||||
let mut global_block_type: Option<TypePath> = None;
|
||||
let mut self_ty: Option<Box<Type>> = None;
|
||||
|
||||
@@ -451,7 +393,6 @@ fn generate_runtime_api_impls(impls: &[ItemImpl]) -> Result<GeneratedRuntimeApiI
|
||||
let mut visitor = FoldRuntimeApiImpl {
|
||||
block_type,
|
||||
impl_trait: &impl_trait.ident,
|
||||
error_type: &mut error_type,
|
||||
};
|
||||
|
||||
result.push(visitor.fold_item_impl(impl_.clone()));
|
||||
@@ -459,7 +400,6 @@ fn generate_runtime_api_impls(impls: &[ItemImpl]) -> Result<GeneratedRuntimeApiI
|
||||
|
||||
Ok(GeneratedRuntimeApiImpls {
|
||||
impls: quote!( #( #result )* ),
|
||||
error_type,
|
||||
block_type: global_block_type.expect("There is a least one runtime api; qed"),
|
||||
self_ty: *self_ty.expect("There is at least one runtime api; qed"),
|
||||
})
|
||||
@@ -475,9 +415,9 @@ pub fn mock_impl_runtime_apis_impl(input: proc_macro::TokenStream) -> proc_macro
|
||||
|
||||
fn mock_impl_runtime_apis_impl_inner(api_impls: &[ItemImpl]) -> Result<TokenStream> {
|
||||
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
|
||||
|
||||
@@ -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> )
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Block> 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<Block> for MockApi {
|
||||
/// type Error = sp_api::ApiError;
|
||||
/// #[advanced]
|
||||
/// fn get_balance(&self, at: &BlockId<Block>) -> Result<NativeOrEncoded<u64>, Self::Error> {
|
||||
/// fn get_balance(&self, at: &BlockId<Block>) -> Result<NativeOrEncoded<u64>, sp_api::ApiError> {
|
||||
/// println!("Being called at: {}", at);
|
||||
///
|
||||
/// Ok(self.balance.into())
|
||||
/// }
|
||||
/// #[advanced]
|
||||
/// fn set_balance(at: &BlockId<Block>, val: u64) -> Result<NativeOrEncoded<()>, Self::Error> {
|
||||
/// fn set_balance(at: &BlockId<Block>, val: u64) -> Result<NativeOrEncoded<()>, sp_api::ApiError> {
|
||||
/// if let BlockId::Number(1) = at {
|
||||
/// println!("Being called to set balance to: {}", val);
|
||||
/// }
|
||||
@@ -393,46 +387,35 @@ pub trait ConstructRuntimeApi<Block: BlockT, C: CallApiAt<Block>> {
|
||||
}
|
||||
|
||||
/// 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<ApiError>;
|
||||
#[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<dyn std::error::Error + Send + Sync>),
|
||||
}
|
||||
|
||||
/// Extends the runtime api implementation with some common functionality.
|
||||
#[cfg(feature = "std")]
|
||||
pub trait ApiExt<Block: BlockT>: ApiErrorExt {
|
||||
pub trait ApiExt<Block: BlockT> {
|
||||
/// The state backend that is used to store the block states.
|
||||
type StateBackend: StateBackend<HashFor<Block>>;
|
||||
|
||||
@@ -450,14 +433,14 @@ pub trait ApiExt<Block: BlockT>: ApiErrorExt {
|
||||
fn has_api<A: RuntimeApiInfo + ?Sized>(
|
||||
&self,
|
||||
at: &BlockId<Block>,
|
||||
) -> Result<bool, Self::Error> where Self: Sized;
|
||||
) -> Result<bool, ApiError> where Self: Sized;
|
||||
|
||||
/// Check if the given api is implemented and the version passes a predicate.
|
||||
fn has_api_with<A: RuntimeApiInfo + ?Sized, P: Fn(u32) -> bool>(
|
||||
&self,
|
||||
at: &BlockId<Block>,
|
||||
pred: P,
|
||||
) -> Result<bool, Self::Error> where Self: Sized;
|
||||
) -> Result<bool, ApiError> where Self: Sized;
|
||||
|
||||
/// Start recording all accessed trie nodes for generating proofs.
|
||||
fn record_proof(&mut self);
|
||||
@@ -478,7 +461,10 @@ pub trait ApiExt<Block: BlockT>: ApiErrorExt {
|
||||
backend: &Self::StateBackend,
|
||||
changes_trie_state: Option<&ChangesTrieState<HashFor<Block>, NumberFor<Block>>>,
|
||||
parent_hash: Block::Hash,
|
||||
) -> Result<StorageChanges<Self::StateBackend, Block>, String> where Self: Sized;
|
||||
) -> Result<
|
||||
StorageChanges<Self::StateBackend, Block>,
|
||||
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<HashF
|
||||
/// Something that can call into the an api at a given block.
|
||||
#[cfg(feature = "std")]
|
||||
pub trait CallApiAt<Block: BlockT> {
|
||||
/// Error type used by the implementation.
|
||||
type Error: std::fmt::Debug + From<ApiError>;
|
||||
|
||||
/// The state backend that is used to store the block states.
|
||||
type StateBackend: StateBackend<HashFor<Block>>;
|
||||
|
||||
@@ -544,15 +527,18 @@ pub trait CallApiAt<Block: BlockT> {
|
||||
fn call_api_at<
|
||||
'a,
|
||||
R: Encode + Decode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, String> + UnwindSafe,
|
||||
C: Core<Block, Error = Self::Error>,
|
||||
NC: FnOnce() -> result::Result<R, ApiError> + UnwindSafe,
|
||||
C: Core<Block>,
|
||||
>(
|
||||
&self,
|
||||
params: CallApiAtParams<'a, Block, C, NC, Self::StateBackend>,
|
||||
) -> Result<NativeOrEncoded<R>, Self::Error>;
|
||||
) -> Result<NativeOrEncoded<R>, ApiError>;
|
||||
|
||||
/// Returns the runtime version at the given block.
|
||||
fn runtime_version_at(&self, at: &BlockId<Block>) -> Result<RuntimeVersion, Self::Error>;
|
||||
fn runtime_version_at(
|
||||
&self,
|
||||
at: &BlockId<Block>,
|
||||
) -> Result<RuntimeVersion, ApiError>;
|
||||
}
|
||||
|
||||
/// 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<T, Block> = <<T as ProvideRuntimeApi<Block>>::Api as ApiErrorExt>::Error;
|
||||
|
||||
#[derive(codec::Encode, codec::Decode)]
|
||||
pub struct OldRuntimeVersion {
|
||||
pub spec_name: RuntimeString,
|
||||
|
||||
@@ -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<Block>) ->
|
||||
std::result::Result<
|
||||
Result<
|
||||
NativeOrEncoded<()>,
|
||||
ApiError
|
||||
>
|
||||
@@ -115,7 +114,7 @@ mock_impl_runtime_apis! {
|
||||
|
||||
#[advanced]
|
||||
fn wild_card(at: &BlockId<Block>, _: 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<dyn std::error::Error + Send + Sync>).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,33 +142,33 @@ type TestClient = substrate_test_runtime_client::client::Client<
|
||||
|
||||
#[test]
|
||||
fn test_client_side_function_signature() {
|
||||
let _test: fn(&RuntimeApiImpl<Block, TestClient>, &BlockId<Block>, u64) -> Result<()> =
|
||||
let _test: fn(&RuntimeApiImpl<Block, TestClient>, &BlockId<Block>, u64) -> Result<(), ApiError> =
|
||||
RuntimeApiImpl::<Block, TestClient>::test;
|
||||
let _something_with_block:
|
||||
fn(&RuntimeApiImpl<Block, TestClient>, &BlockId<Block>, Block) -> Result<Block> =
|
||||
fn(&RuntimeApiImpl<Block, TestClient>, &BlockId<Block>, Block) -> Result<Block, ApiError> =
|
||||
RuntimeApiImpl::<Block, TestClient>::something_with_block;
|
||||
|
||||
#[allow(deprecated)]
|
||||
let _same_name_before_version_2:
|
||||
fn(&RuntimeApiImpl<Block, TestClient>, &BlockId<Block>) -> Result<String> =
|
||||
fn(&RuntimeApiImpl<Block, TestClient>, &BlockId<Block>) -> Result<String, ApiError> =
|
||||
RuntimeApiImpl::<Block, TestClient>::same_name_before_version_2;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_runtime_api_info() {
|
||||
assert_eq!(&Api::<Block, Error = ()>::ID, &runtime_decl_for_Api::ID);
|
||||
assert_eq!(Api::<Block, Error = ()>::VERSION, runtime_decl_for_Api::VERSION);
|
||||
assert_eq!(Api::<Block, Error = ()>::VERSION, 1);
|
||||
assert_eq!(&Api::<Block>::ID, &runtime_decl_for_Api::ID);
|
||||
assert_eq!(Api::<Block>::VERSION, runtime_decl_for_Api::VERSION);
|
||||
assert_eq!(Api::<Block>::VERSION, 1);
|
||||
|
||||
assert_eq!(
|
||||
ApiWithCustomVersion::<Block, Error = ()>::VERSION,
|
||||
ApiWithCustomVersion::<Block>::VERSION,
|
||||
runtime_decl_for_ApiWithCustomVersion::VERSION,
|
||||
);
|
||||
assert_eq!(
|
||||
&ApiWithCustomVersion::<Block, Error = ()>::ID,
|
||||
&ApiWithCustomVersion::<Block>::ID,
|
||||
&runtime_decl_for_ApiWithCustomVersion::ID,
|
||||
);
|
||||
assert_eq!(ApiWithCustomVersion::<Block, Error = ()>::VERSION, 2);
|
||||
assert_eq!(ApiWithCustomVersion::<Block>::VERSION, 2);
|
||||
}
|
||||
|
||||
fn check_runtime_api_versions_contains<T: RuntimeApiInfo + ?Sized>() {
|
||||
@@ -178,9 +177,9 @@ fn check_runtime_api_versions_contains<T: RuntimeApiInfo + ?Sized>() {
|
||||
|
||||
#[test]
|
||||
fn check_runtime_api_versions() {
|
||||
check_runtime_api_versions_contains::<dyn Api<Block, Error = ()>>();
|
||||
check_runtime_api_versions_contains::<dyn ApiWithCustomVersion<Block, Error = ()>>();
|
||||
check_runtime_api_versions_contains::<dyn sp_api::Core<Block, Error = ()>>();
|
||||
check_runtime_api_versions_contains::<dyn Api<Block>>();
|
||||
check_runtime_api_versions_contains::<dyn ApiWithCustomVersion<Block>>();
|
||||
check_runtime_api_versions_contains::<dyn sp_api::Core<Block>>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -188,9 +187,9 @@ fn mock_runtime_api_has_api() {
|
||||
let mock = MockApi { block: None };
|
||||
|
||||
assert!(
|
||||
mock.has_api::<dyn ApiWithCustomVersion<Block, Error = ()>>(&BlockId::Number(0)).unwrap(),
|
||||
mock.has_api::<dyn ApiWithCustomVersion<Block>>(&BlockId::Number(0)).unwrap(),
|
||||
);
|
||||
assert!(mock.has_api::<dyn Api<Block, Error = ()>>(&BlockId::Number(0)).unwrap());
|
||||
assert!(mock.has_api::<dyn Api<Block>>(&BlockId::Number(0)).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -209,7 +208,7 @@ fn mock_runtime_api_works_with_advanced() {
|
||||
Api::<Block>::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(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<Block> for MockApi {
|
||||
type OtherData = u32;
|
||||
|
||||
fn test(data: u64) {}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -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;
|
||||
| ^^^^
|
||||
@@ -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<Block> for MockApi {
|
||||
type Error = u32;
|
||||
|
||||
fn test(data: u64) {}
|
||||
}
|
||||
|
||||
impl Api2<Block> for MockApi {
|
||||
type Error = u64;
|
||||
|
||||
fn test(data: u64) {}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -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<sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ApiError>` is not satisfied
|
||||
--> $DIR/mock_only_one_error_type.rs:17:16
|
||||
|
|
||||
17 | type Error = u32;
|
||||
| ^^^ the trait `From<sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ApiError>` is not implemented for `u32`
|
||||
|
|
||||
::: $WORKSPACE/primitives/api/src/lib.rs
|
||||
|
|
||||
| type Error: std::fmt::Debug + From<ApiError>;
|
||||
| -------------- required by this bound in `sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ApiErrorExt::Error`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<u32 as From<HttpError>>
|
||||
<u32 as From<HttpRequestId>>
|
||||
<u32 as From<HttpRequestStatus>>
|
||||
<u32 as From<Ipv4Addr>>
|
||||
and 18 others
|
||||
@@ -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<Box<dyn sp_state_machine::Error>> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Error> 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<Error>) -> Self {
|
||||
|
||||
@@ -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<R, String> + UnwindSafe,
|
||||
NC: FnOnce() -> Result<R, Box<dyn std::error::Error + Send + Sync>> + UnwindSafe,
|
||||
>(
|
||||
&self,
|
||||
ext: &mut dyn Externalities,
|
||||
|
||||
@@ -113,7 +113,7 @@ pub fn generate_initial_session_keys<Block, T>(
|
||||
client: std::sync::Arc<T>,
|
||||
at: &BlockId<Block>,
|
||||
seeds: Vec<String>,
|
||||
) -> Result<(), sp_api::ApiErrorFor<T, Block>>
|
||||
) -> Result<(), sp_api::ApiError>
|
||||
where
|
||||
Block: BlockT,
|
||||
T: ProvideRuntimeApi<Block>,
|
||||
|
||||
@@ -392,7 +392,7 @@ mod execution {
|
||||
bool,
|
||||
) where
|
||||
R: Decode + Encode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, String> + UnwindSafe,
|
||||
NC: FnOnce() -> result::Result<R, Box<dyn std::error::Error + Send + Sync>> + UnwindSafe,
|
||||
{
|
||||
let mut cache = StorageTransactionCache::default();
|
||||
|
||||
@@ -449,7 +449,7 @@ mod execution {
|
||||
) -> CallResult<R, Exec::Error>
|
||||
where
|
||||
R: Decode + Encode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, String> + UnwindSafe,
|
||||
NC: FnOnce() -> result::Result<R, Box<dyn std::error::Error + Send + Sync>> + UnwindSafe,
|
||||
Handler: FnOnce(
|
||||
CallResult<R, Exec::Error>,
|
||||
CallResult<R, Exec::Error>,
|
||||
@@ -485,7 +485,7 @@ mod execution {
|
||||
) -> CallResult<R, Exec::Error>
|
||||
where
|
||||
R: Decode + Encode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, String> + UnwindSafe,
|
||||
NC: FnOnce() -> result::Result<R, Box<dyn std::error::Error + Send + Sync>> + UnwindSafe,
|
||||
{
|
||||
self.overlay.start_transaction();
|
||||
let (result, was_native) = self.execute_aux(
|
||||
@@ -522,7 +522,7 @@ mod execution {
|
||||
) -> Result<NativeOrEncoded<R>, Box<dyn Error>>
|
||||
where
|
||||
R: Decode + Encode + PartialEq,
|
||||
NC: FnOnce() -> result::Result<R, String> + UnwindSafe,
|
||||
NC: FnOnce() -> result::Result<R, Box<dyn std::error::Error + Send + Sync>> + UnwindSafe,
|
||||
Handler: FnOnce(
|
||||
CallResult<R, Exec::Error>,
|
||||
CallResult<R, Exec::Error>,
|
||||
@@ -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<R, String>,
|
||||
NC: FnOnce() -> result::Result<R, Box<dyn std::error::Error + Send + Sync>> + UnwindSafe,
|
||||
>(
|
||||
&self,
|
||||
ext: &mut dyn Externalities,
|
||||
|
||||
@@ -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<substrate_test_runtime::Block> + 'a,
|
||||
A::Api: BlockBuilderApi<substrate_test_runtime::Block, Error = sp_blockchain::Error> +
|
||||
A::Api: BlockBuilderApi<substrate_test_runtime::Block> +
|
||||
ApiExt<
|
||||
substrate_test_runtime::Block,
|
||||
StateBackend = backend::StateBackendFor<B, substrate_test_runtime::Block>
|
||||
|
||||
Reference in New Issue
Block a user