mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 12:51:05 +00:00
BlockId removal: runtime-api refactor (#13255)
* BlockId removal: refactor of runtime API It changes the arguments of: - `ApiExt` methods: `has_api`, `has_api_with`, `api_version` - `CallApiAt` method: `runtime_version_at` from: `BlockId<Block>` to: `Block::Hash` It also changes the first argument of all generated runtime API calls from: `BlockId<Block>` to: `Block::Hash` This PR is part of BlockId::Number refactoring analysis (paritytech/substrate#11292) * BlockId removal: refactor of runtime API - tests - tests adjusted to new runtime API, - some tests migrated from block number to block hash * benchmarking-cli: BlockId(0) migrated to info().genesis_hash `runtime_api.call()` now requires the block hash instead of BlockId::Number. To access the genesis hash widely used in benchmarking engine the Client was constrained to satisfy `sp_blockchain::HeaderBackend<Block>` trait which provides `info().genesis_hash`. * trivial: api.call(BlockId) -> api.call(Hash) - Migrated all `runtime_api.calls` to use Hash - Noteworthy (?): -- `validate_transaction_blocking` in transaction pool, * CallApiAtParams::at changed to Block::Hash * missed doc updated * Apply suggestions from code review Co-authored-by: Bastian Köcher <git@kchr.de> * ".git/.scripts/commands/fmt/fmt.sh" * BlockId removal: Benchmark::consumed_weight Little refactor around `Benchmark::consumed_weight`: `BlockId` removed. * at_hash renamed * wrong merge fixed * beefy worker: merged with master * beefy: tests: missing block problem fixed * Apply review suggestion * fix --------- Co-authored-by: Bastian Köcher <git@kchr.de> Co-authored-by: command-bot <>
This commit is contained in:
committed by
GitHub
parent
ac13aaeb2f
commit
7a10154188
@@ -60,7 +60,7 @@ pub fn fetch_nonce(client: &FullClient, account: sp_core::sr25519::Pair) -> u32
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
client
|
||||
.runtime_api()
|
||||
.account_nonce(&generic::BlockId::Hash(best_hash), account.public().into())
|
||||
.account_nonce(best_hash, account.public().into())
|
||||
.expect("Fetching account nonce works; qed")
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@ use sp_consensus::BlockOrigin;
|
||||
use sp_core::{blake2_256, ed25519, sr25519, traits::SpawnNamed, ExecutionContext, Pair, Public};
|
||||
use sp_inherents::InherentData;
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, IdentifyAccount, Verify},
|
||||
OpaqueExtrinsic,
|
||||
};
|
||||
@@ -274,7 +273,6 @@ pub struct BlockContentIterator<'a> {
|
||||
impl<'a> BlockContentIterator<'a> {
|
||||
fn new(content: BlockContent, keyring: &'a BenchKeyring, client: &Client) -> Self {
|
||||
let genesis_hash = client.chain_info().genesis_hash;
|
||||
|
||||
let runtime_version = client
|
||||
.runtime_version_at(genesis_hash)
|
||||
.expect("There should be runtime version at 0");
|
||||
@@ -442,7 +440,7 @@ impl BenchDb {
|
||||
client
|
||||
.runtime_api()
|
||||
.inherent_extrinsics_with_context(
|
||||
&BlockId::number(0),
|
||||
client.chain_info().genesis_hash,
|
||||
ExecutionContext::BlockConstruction,
|
||||
inherent_data,
|
||||
)
|
||||
|
||||
@@ -55,7 +55,7 @@ use sp_blockchain::HeaderBackend;
|
||||
|
||||
use sp_core::crypto::{key_types, CryptoTypePublicPair, Pair};
|
||||
use sp_keystore::CryptoStore;
|
||||
use sp_runtime::{generic::BlockId, traits::Block as BlockT};
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
|
||||
mod addr_cache;
|
||||
/// Dht payload schemas generated from Protobuf definitions via Prost crate in build.rs.
|
||||
@@ -171,7 +171,7 @@ where
|
||||
&self,
|
||||
at: Block::Hash,
|
||||
) -> std::result::Result<Vec<AuthorityId>, ApiError> {
|
||||
self.runtime_api().authorities(&BlockId::Hash(at))
|
||||
self.runtime_api().authorities(at)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -731,7 +731,7 @@ mod tests {
|
||||
assert_eq!(proposal.block.extrinsics().len(), 1);
|
||||
|
||||
let api = client.runtime_api();
|
||||
api.execute_block(&BlockId::Hash(genesis_hash), proposal.block).unwrap();
|
||||
api.execute_block(genesis_hash, proposal.block).unwrap();
|
||||
|
||||
let state = backend.state_at(genesis_hash).unwrap();
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ use sp_api::{ProvideRuntimeApi, TransactionFor};
|
||||
use sp_blockchain::well_known_cache_keys;
|
||||
use sp_consensus::Error as ConsensusError;
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, Header as HeaderT, NumberFor},
|
||||
EncodedJustification,
|
||||
};
|
||||
@@ -93,11 +92,10 @@ where
|
||||
hash: <Block as BlockT>::Hash,
|
||||
) -> Result<BeefyVersionedFinalityProof<Block>, ConsensusError> {
|
||||
use ConsensusError::ClientImport as ImportError;
|
||||
let block_id = BlockId::hash(hash);
|
||||
let beefy_genesis = self
|
||||
.runtime
|
||||
.runtime_api()
|
||||
.beefy_genesis(&block_id)
|
||||
.beefy_genesis(hash)
|
||||
.map_err(|e| ImportError(e.to_string()))?
|
||||
.ok_or_else(|| ImportError("Unknown BEEFY genesis".to_string()))?;
|
||||
if number < beefy_genesis {
|
||||
@@ -106,7 +104,7 @@ where
|
||||
let validator_set = self
|
||||
.runtime
|
||||
.runtime_api()
|
||||
.validator_set(&block_id)
|
||||
.validator_set(hash)
|
||||
.map_err(|e| ImportError(e.to_string()))?
|
||||
.ok_or_else(|| ImportError("Unknown validator set".to_string()))?;
|
||||
|
||||
|
||||
@@ -52,10 +52,7 @@ use sp_blockchain::{
|
||||
use sp_consensus::{Error as ConsensusError, SyncOracle};
|
||||
use sp_keystore::SyncCryptoStorePtr;
|
||||
use sp_mmr_primitives::MmrApi;
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block, Zero},
|
||||
};
|
||||
use sp_runtime::traits::{Block, Zero};
|
||||
use std::{collections::VecDeque, marker::PhantomData, sync::Arc};
|
||||
|
||||
mod aux_schema;
|
||||
@@ -345,7 +342,7 @@ where
|
||||
{
|
||||
let beefy_genesis = runtime
|
||||
.runtime_api()
|
||||
.beefy_genesis(&BlockId::hash(best_grandpa.hash()))
|
||||
.beefy_genesis(best_grandpa.hash())
|
||||
.ok()
|
||||
.flatten()
|
||||
.ok_or_else(|| ClientError::Backend("BEEFY pallet expected to be active.".into()))?;
|
||||
@@ -369,7 +366,7 @@ where
|
||||
let best_beefy = *header.number();
|
||||
// If no session boundaries detected so far, just initialize new rounds here.
|
||||
if sessions.is_empty() {
|
||||
let active_set = expect_validator_set(runtime, BlockId::hash(header.hash()))?;
|
||||
let active_set = expect_validator_set(runtime, header.hash())?;
|
||||
let mut rounds = Rounds::new(best_beefy, active_set);
|
||||
// Mark the round as already finalized.
|
||||
rounds.conclude(best_beefy);
|
||||
@@ -383,8 +380,8 @@ where
|
||||
|
||||
if *header.number() == beefy_genesis {
|
||||
// We've reached BEEFY genesis, initialize voter here.
|
||||
let genesis_set = expect_validator_set(runtime, BlockId::hash(header.hash()))
|
||||
.and_then(genesis_set_sanity_check)?;
|
||||
let genesis_set =
|
||||
expect_validator_set(runtime, header.hash()).and_then(genesis_set_sanity_check)?;
|
||||
info!(
|
||||
target: LOG_TARGET,
|
||||
"🥩 Loading BEEFY voter state from genesis on what appears to be first startup. \
|
||||
@@ -409,16 +406,11 @@ where
|
||||
|
||||
// Check if state is still available if we move up the chain.
|
||||
let parent_hash = *header.parent_hash();
|
||||
runtime
|
||||
.runtime_api()
|
||||
.validator_set(&BlockId::hash(parent_hash))
|
||||
.ok()
|
||||
.flatten()
|
||||
.ok_or_else(|| {
|
||||
let msg = format!("{}. Could not initialize BEEFY voter.", parent_hash);
|
||||
error!(target: LOG_TARGET, "🥩 {}", msg);
|
||||
ClientError::Consensus(sp_consensus::Error::StateUnavailable(msg))
|
||||
})?;
|
||||
runtime.runtime_api().validator_set(parent_hash).ok().flatten().ok_or_else(|| {
|
||||
let msg = format!("{}. Could not initialize BEEFY voter.", parent_hash);
|
||||
error!(target: LOG_TARGET, "🥩 {}", msg);
|
||||
ClientError::Consensus(sp_consensus::Error::StateUnavailable(msg))
|
||||
})?;
|
||||
|
||||
// Move up the chain.
|
||||
header = blockchain.expect_header(parent_hash)?;
|
||||
@@ -449,8 +441,8 @@ where
|
||||
Some(notif) => notif,
|
||||
None => break
|
||||
};
|
||||
let at = BlockId::hash(notif.header.hash());
|
||||
if let Some(start) = runtime.runtime_api().beefy_genesis(&at).ok().flatten() {
|
||||
let at = notif.header.hash();
|
||||
if let Some(start) = runtime.runtime_api().beefy_genesis(at).ok().flatten() {
|
||||
if *notif.header.number() >= start {
|
||||
// Beefy pallet available, return header for best grandpa at the time.
|
||||
info!(
|
||||
@@ -485,7 +477,7 @@ fn genesis_set_sanity_check(
|
||||
|
||||
fn expect_validator_set<B, R>(
|
||||
runtime: &R,
|
||||
at: BlockId<B>,
|
||||
at_hash: B::Hash,
|
||||
) -> ClientResult<ValidatorSet<AuthorityId>>
|
||||
where
|
||||
B: Block,
|
||||
@@ -494,7 +486,7 @@ where
|
||||
{
|
||||
runtime
|
||||
.runtime_api()
|
||||
.validator_set(&at)
|
||||
.validator_set(at_hash)
|
||||
.ok()
|
||||
.flatten()
|
||||
.ok_or_else(|| ClientError::Backend("BEEFY pallet expected to be active.".into()))
|
||||
|
||||
@@ -963,10 +963,21 @@ where
|
||||
}
|
||||
|
||||
let number = *proof.round_number();
|
||||
let hash = self
|
||||
.backend
|
||||
.blockchain()
|
||||
.expect_block_hash_from_id(&BlockId::Number(number))
|
||||
.map_err(|err| {
|
||||
let err_msg = format!(
|
||||
"Couldn't get hash for block #{:?} (error: {:?}), skipping report for equivocation",
|
||||
number, err
|
||||
);
|
||||
Error::Backend(err_msg)
|
||||
})?;
|
||||
let runtime_api = self.runtime.runtime_api();
|
||||
// generate key ownership proof at that block
|
||||
let key_owner_proof = match runtime_api
|
||||
.generate_key_ownership_proof(&BlockId::Number(number), validator_set_id, offender_id)
|
||||
.generate_key_ownership_proof(hash, validator_set_id, offender_id)
|
||||
.map_err(Error::RuntimeApi)?
|
||||
{
|
||||
Some(proof) => proof,
|
||||
@@ -982,11 +993,7 @@ where
|
||||
// submit equivocation report at **best** block
|
||||
let best_block_hash = self.backend.blockchain().info().best_hash;
|
||||
runtime_api
|
||||
.submit_report_equivocation_unsigned_extrinsic(
|
||||
&BlockId::Hash(best_block_hash),
|
||||
proof,
|
||||
key_owner_proof,
|
||||
)
|
||||
.submit_report_equivocation_unsigned_extrinsic(best_block_hash, proof, key_owner_proof)
|
||||
.map_err(Error::RuntimeApi)?;
|
||||
|
||||
Ok(())
|
||||
@@ -1628,6 +1635,9 @@ pub(crate) mod tests {
|
||||
let mut worker = create_beefy_worker(&net.peer(0), &keys[0], 1, validator_set.clone());
|
||||
worker.runtime = api_alice.clone();
|
||||
|
||||
// let there be a block with num = 1:
|
||||
let _ = net.peer(0).push_blocks(1, false);
|
||||
|
||||
let payload1 = Payload::from_single_entry(MMR_ROOT_ID, vec![42]);
|
||||
let payload2 = Payload::from_single_entry(MMR_ROOT_ID, vec![128]);
|
||||
|
||||
|
||||
@@ -137,7 +137,6 @@ pub struct BlockBuilder<'a, Block: BlockT, A: ProvideRuntimeApi<Block>, B> {
|
||||
extrinsics: Vec<Block::Extrinsic>,
|
||||
api: ApiRef<'a, A::Api>,
|
||||
version: u32,
|
||||
block_id: BlockId<Block>,
|
||||
parent_hash: Block::Hash,
|
||||
backend: &'a B,
|
||||
/// The estimated size of the block header.
|
||||
@@ -181,12 +180,14 @@ where
|
||||
api.record_proof();
|
||||
}
|
||||
|
||||
let block_id = BlockId::Hash(parent_hash);
|
||||
|
||||
api.initialize_block_with_context(&block_id, ExecutionContext::BlockConstruction, &header)?;
|
||||
api.initialize_block_with_context(
|
||||
parent_hash,
|
||||
ExecutionContext::BlockConstruction,
|
||||
&header,
|
||||
)?;
|
||||
|
||||
let version = api
|
||||
.api_version::<dyn BlockBuilderApi<Block>>(&block_id)?
|
||||
.api_version::<dyn BlockBuilderApi<Block>>(parent_hash)?
|
||||
.ok_or_else(|| Error::VersionInvalid("BlockBuilderApi".to_string()))?;
|
||||
|
||||
Ok(Self {
|
||||
@@ -194,7 +195,6 @@ where
|
||||
extrinsics: Vec::new(),
|
||||
api,
|
||||
version,
|
||||
block_id,
|
||||
backend,
|
||||
estimated_header_size,
|
||||
})
|
||||
@@ -204,7 +204,7 @@ where
|
||||
///
|
||||
/// This will ensure the extrinsic can be validly executed (by executing it).
|
||||
pub fn push(&mut self, xt: <Block as BlockT>::Extrinsic) -> Result<(), Error> {
|
||||
let block_id = &self.block_id;
|
||||
let parent_hash = self.parent_hash;
|
||||
let extrinsics = &mut self.extrinsics;
|
||||
let version = self.version;
|
||||
|
||||
@@ -212,14 +212,14 @@ where
|
||||
let res = if version < 6 {
|
||||
#[allow(deprecated)]
|
||||
api.apply_extrinsic_before_version_6_with_context(
|
||||
block_id,
|
||||
parent_hash,
|
||||
ExecutionContext::BlockConstruction,
|
||||
xt.clone(),
|
||||
)
|
||||
.map(legacy::byte_sized_error::convert_to_latest)
|
||||
} else {
|
||||
api.apply_extrinsic_with_context(
|
||||
block_id,
|
||||
parent_hash,
|
||||
ExecutionContext::BlockConstruction,
|
||||
xt.clone(),
|
||||
)
|
||||
@@ -246,7 +246,7 @@ where
|
||||
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)?;
|
||||
.finalize_block_with_context(self.parent_hash, ExecutionContext::BlockConstruction)?;
|
||||
|
||||
debug_assert_eq!(
|
||||
header.extrinsics_root().clone(),
|
||||
@@ -279,13 +279,13 @@ where
|
||||
&mut self,
|
||||
inherent_data: sp_inherents::InherentData,
|
||||
) -> Result<Vec<Block::Extrinsic>, Error> {
|
||||
let block_id = self.block_id;
|
||||
let parent_hash = self.parent_hash;
|
||||
self.api
|
||||
.execute_in_transaction(move |api| {
|
||||
// `create_inherents` should not change any state, to ensure this we always rollback
|
||||
// the transaction.
|
||||
TransactionOutcome::Rollback(api.inherent_extrinsics_with_context(
|
||||
&block_id,
|
||||
parent_hash,
|
||||
ExecutionContext::BlockConstruction,
|
||||
inherent_data,
|
||||
))
|
||||
|
||||
@@ -41,7 +41,6 @@ use sp_consensus_slots::Slot;
|
||||
use sp_core::{crypto::Pair, ExecutionContext};
|
||||
use sp_inherents::{CreateInherentDataProviders, InherentDataProvider as _};
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, Header, NumberFor},
|
||||
DigestItem,
|
||||
};
|
||||
@@ -142,7 +141,7 @@ where
|
||||
async fn check_inherents<B: BlockT>(
|
||||
&self,
|
||||
block: B,
|
||||
block_id: BlockId<B>,
|
||||
at_hash: B::Hash,
|
||||
inherent_data: sp_inherents::InherentData,
|
||||
create_inherent_data_providers: CIDP::InherentDataProviders,
|
||||
execution_context: ExecutionContext,
|
||||
@@ -155,7 +154,7 @@ where
|
||||
let inherent_res = self
|
||||
.client
|
||||
.runtime_api()
|
||||
.check_inherents_with_context(&block_id, execution_context, block, inherent_data)
|
||||
.check_inherents_with_context(at_hash, execution_context, block, inherent_data)
|
||||
.map_err(|e| Error::Client(e.into()))?;
|
||||
|
||||
if !inherent_res.ok() {
|
||||
@@ -248,15 +247,12 @@ where
|
||||
if self
|
||||
.client
|
||||
.runtime_api()
|
||||
.has_api_with::<dyn BlockBuilderApi<B>, _>(
|
||||
&BlockId::Hash(parent_hash),
|
||||
|v| v >= 2,
|
||||
)
|
||||
.has_api_with::<dyn BlockBuilderApi<B>, _>(parent_hash, |v| v >= 2)
|
||||
.map_err(|e| e.to_string())?
|
||||
{
|
||||
self.check_inherents(
|
||||
new_block.clone(),
|
||||
BlockId::Hash(parent_hash),
|
||||
parent_hash,
|
||||
inherent_data,
|
||||
create_inherent_data_providers,
|
||||
block.origin.into(),
|
||||
|
||||
@@ -53,7 +53,6 @@ use sp_core::crypto::{ByteArray, Pair, Public};
|
||||
use sp_inherents::CreateInherentDataProviders;
|
||||
use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr};
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, Header, Member, NumberFor, Zero},
|
||||
DigestItem,
|
||||
};
|
||||
@@ -121,8 +120,10 @@ where
|
||||
C: AuxStore + ProvideRuntimeApi<B> + UsageProvider<B>,
|
||||
C::Api: AuraApi<B, A>,
|
||||
{
|
||||
let best_block_id = BlockId::Hash(client.usage_info().chain.best_hash);
|
||||
client.runtime_api().slot_duration(&best_block_id).map_err(|err| err.into())
|
||||
client
|
||||
.runtime_api()
|
||||
.slot_duration(client.usage_info().chain.best_hash)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
/// Get slot author for given block along with authorities.
|
||||
@@ -613,7 +614,7 @@ where
|
||||
if *until > context_block_number {
|
||||
runtime_api
|
||||
.initialize_block(
|
||||
&BlockId::Hash(parent_hash),
|
||||
parent_hash,
|
||||
&B::Header::new(
|
||||
context_block_number,
|
||||
Default::default(),
|
||||
@@ -627,7 +628,7 @@ where
|
||||
}
|
||||
|
||||
runtime_api
|
||||
.authorities(&BlockId::Hash(parent_hash))
|
||||
.authorities(parent_hash)
|
||||
.ok()
|
||||
.ok_or(sp_consensus::Error::InvalidAuthoritiesSet)
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ use sc_consensus_babe::{authorship, Epoch};
|
||||
use sc_consensus_epochs::{descendent_query, Epoch as EpochT, SharedEpochChanges};
|
||||
use sc_rpc_api::DenyUnsafe;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sp_api::{BlockId, ProvideRuntimeApi};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sp_application_crypto::AppKey;
|
||||
use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
|
||||
use sp_consensus::{Error as ConsensusError, SelectChain};
|
||||
@@ -97,7 +97,7 @@ where
|
||||
let epoch_start = self
|
||||
.client
|
||||
.runtime_api()
|
||||
.current_epoch_start(&BlockId::Hash(header.hash()))
|
||||
.current_epoch_start(header.hash())
|
||||
.map_err(|err| Error::StringError(format!("{:?}", err)))?;
|
||||
|
||||
let epoch = epoch_data(
|
||||
|
||||
@@ -123,7 +123,7 @@ use sp_core::{crypto::ByteArray, ExecutionContext};
|
||||
use sp_inherents::{CreateInherentDataProviders, InherentData, InherentDataProvider};
|
||||
use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr};
|
||||
use sp_runtime::{
|
||||
generic::{BlockId, OpaqueDigestItemId},
|
||||
generic::OpaqueDigestItemId,
|
||||
traits::{Block as BlockT, Header, NumberFor, SaturatedConversion, Zero},
|
||||
DigestItem,
|
||||
};
|
||||
@@ -377,24 +377,24 @@ where
|
||||
C: AuxStore + ProvideRuntimeApi<B> + UsageProvider<B>,
|
||||
C::Api: BabeApi<B>,
|
||||
{
|
||||
let block_id = if client.usage_info().chain.finalized_state.is_some() {
|
||||
BlockId::Hash(client.usage_info().chain.best_hash)
|
||||
let at_hash = if client.usage_info().chain.finalized_state.is_some() {
|
||||
client.usage_info().chain.best_hash
|
||||
} else {
|
||||
debug!(target: LOG_TARGET, "No finalized state is available. Reading config from genesis");
|
||||
BlockId::Hash(client.usage_info().chain.genesis_hash)
|
||||
client.usage_info().chain.genesis_hash
|
||||
};
|
||||
|
||||
let runtime_api = client.runtime_api();
|
||||
let version = runtime_api.api_version::<dyn BabeApi<B>>(&block_id)?;
|
||||
let version = runtime_api.api_version::<dyn BabeApi<B>>(at_hash)?;
|
||||
|
||||
let config = match version {
|
||||
Some(1) => {
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
runtime_api.configuration_before_version_2(&block_id)?.into()
|
||||
runtime_api.configuration_before_version_2(at_hash)?.into()
|
||||
}
|
||||
},
|
||||
Some(2) => runtime_api.configuration(&block_id)?,
|
||||
Some(2) => runtime_api.configuration(at_hash)?,
|
||||
_ =>
|
||||
return Err(sp_blockchain::Error::VersionInvalid(
|
||||
"Unsupported or invalid BabeApi version".to_string(),
|
||||
@@ -1023,7 +1023,7 @@ where
|
||||
async fn check_inherents(
|
||||
&self,
|
||||
block: Block,
|
||||
block_id: BlockId<Block>,
|
||||
at_hash: Block::Hash,
|
||||
inherent_data: InherentData,
|
||||
create_inherent_data_providers: CIDP::InherentDataProviders,
|
||||
execution_context: ExecutionContext,
|
||||
@@ -1031,7 +1031,7 @@ where
|
||||
let inherent_res = self
|
||||
.client
|
||||
.runtime_api()
|
||||
.check_inherents_with_context(&block_id, execution_context, block, inherent_data)
|
||||
.check_inherents_with_context(at_hash, execution_context, block, inherent_data)
|
||||
.map_err(Error::RuntimeApi)?;
|
||||
|
||||
if !inherent_res.ok() {
|
||||
@@ -1078,11 +1078,11 @@ where
|
||||
);
|
||||
|
||||
// get the best block on which we will build and send the equivocation report.
|
||||
let best_id = self
|
||||
let best_hash = self
|
||||
.select_chain
|
||||
.best_chain()
|
||||
.await
|
||||
.map(|h| BlockId::Hash(h.hash()))
|
||||
.map(|h| h.hash())
|
||||
.map_err(|e| Error::Client(e.into()))?;
|
||||
|
||||
// generate a key ownership proof. we start by trying to generate the
|
||||
@@ -1093,17 +1093,17 @@ where
|
||||
// equivocation happens on the first block of the session, in which case
|
||||
// its parent would be on the previous session. if generation on the
|
||||
// parent header fails we try with best block as well.
|
||||
let generate_key_owner_proof = |block_id: &BlockId<Block>| {
|
||||
let generate_key_owner_proof = |at_hash: Block::Hash| {
|
||||
self.client
|
||||
.runtime_api()
|
||||
.generate_key_ownership_proof(block_id, slot, equivocation_proof.offender.clone())
|
||||
.generate_key_ownership_proof(at_hash, slot, equivocation_proof.offender.clone())
|
||||
.map_err(Error::RuntimeApi)
|
||||
};
|
||||
|
||||
let parent_id = BlockId::Hash(*header.parent_hash());
|
||||
let key_owner_proof = match generate_key_owner_proof(&parent_id)? {
|
||||
let parent_hash = *header.parent_hash();
|
||||
let key_owner_proof = match generate_key_owner_proof(parent_hash)? {
|
||||
Some(proof) => proof,
|
||||
None => match generate_key_owner_proof(&best_id)? {
|
||||
None => match generate_key_owner_proof(best_hash)? {
|
||||
Some(proof) => proof,
|
||||
None => {
|
||||
debug!(
|
||||
@@ -1119,7 +1119,7 @@ where
|
||||
self.client
|
||||
.runtime_api()
|
||||
.submit_report_equivocation_unsigned_extrinsic(
|
||||
&best_id,
|
||||
best_hash,
|
||||
equivocation_proof,
|
||||
key_owner_proof,
|
||||
)
|
||||
@@ -1268,7 +1268,7 @@ where
|
||||
|
||||
self.check_inherents(
|
||||
new_block.clone(),
|
||||
BlockId::Hash(parent_hash),
|
||||
parent_hash,
|
||||
inherent_data,
|
||||
create_inherent_data_providers,
|
||||
block.origin.into(),
|
||||
@@ -1395,11 +1395,10 @@ where
|
||||
};
|
||||
|
||||
// Read epoch info from the imported state.
|
||||
let block_id = BlockId::hash(hash);
|
||||
let current_epoch = self.client.runtime_api().current_epoch(&block_id).map_err(|e| {
|
||||
let current_epoch = self.client.runtime_api().current_epoch(hash).map_err(|e| {
|
||||
ConsensusError::ClientImport(babe_err::<Block>(Error::RuntimeApi(e)).into())
|
||||
})?;
|
||||
let next_epoch = self.client.runtime_api().next_epoch(&block_id).map_err(|e| {
|
||||
let next_epoch = self.client.runtime_api().next_epoch(hash).map_err(|e| {
|
||||
ConsensusError::ClientImport(babe_err::<Block>(Error::RuntimeApi(e)).into())
|
||||
})?;
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ use sp_keystore::{
|
||||
SyncCryptoStore,
|
||||
};
|
||||
use sp_runtime::{
|
||||
generic::{Digest, DigestItem},
|
||||
generic::{BlockId, Digest, DigestItem},
|
||||
traits::Block as BlockT,
|
||||
};
|
||||
use sp_timestamp::Timestamp;
|
||||
|
||||
@@ -267,7 +267,7 @@ where
|
||||
async fn check_inherents(
|
||||
&self,
|
||||
block: B,
|
||||
block_id: BlockId<B>,
|
||||
at_hash: B::Hash,
|
||||
inherent_data_providers: CIDP::InherentDataProviders,
|
||||
execution_context: ExecutionContext,
|
||||
) -> Result<(), Error<B>> {
|
||||
@@ -283,7 +283,7 @@ where
|
||||
let inherent_res = self
|
||||
.client
|
||||
.runtime_api()
|
||||
.check_inherents_with_context(&block_id, execution_context, block, inherent_data)
|
||||
.check_inherents_with_context(at_hash, execution_context, block, inherent_data)
|
||||
.map_err(|e| Error::Client(e.into()))?;
|
||||
|
||||
if !inherent_res.ok() {
|
||||
@@ -344,7 +344,7 @@ where
|
||||
if !block.state_action.skip_execution_checks() {
|
||||
self.check_inherents(
|
||||
check_block.clone(),
|
||||
BlockId::Hash(parent_hash),
|
||||
parent_hash,
|
||||
self.create_inherent_data_providers
|
||||
.create_inherent_data_providers(parent_hash, ())
|
||||
.await?,
|
||||
|
||||
@@ -46,10 +46,7 @@ use sp_finality_grandpa::{
|
||||
AuthorityId, AuthoritySignature, Equivocation, EquivocationProof, GrandpaApi, RoundNumber,
|
||||
SetId, GRANDPA_ENGINE_ID,
|
||||
};
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero},
|
||||
};
|
||||
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero};
|
||||
|
||||
use crate::{
|
||||
authorities::{AuthoritySet, SharedAuthoritySet},
|
||||
@@ -543,7 +540,7 @@ where
|
||||
.client
|
||||
.runtime_api()
|
||||
.generate_key_ownership_proof(
|
||||
&BlockId::Hash(current_set_latest_hash),
|
||||
current_set_latest_hash,
|
||||
authority_set.set_id,
|
||||
equivocation.offender().clone(),
|
||||
)
|
||||
@@ -565,7 +562,7 @@ where
|
||||
self.client
|
||||
.runtime_api()
|
||||
.submit_report_equivocation_unsigned_extrinsic(
|
||||
&BlockId::Hash(best_block_hash),
|
||||
best_block_hash,
|
||||
equivocation_proof,
|
||||
key_owner_proof,
|
||||
)
|
||||
|
||||
@@ -34,7 +34,7 @@ use sp_consensus::{BlockOrigin, Error as ConsensusError, SelectChain};
|
||||
use sp_core::hashing::twox_128;
|
||||
use sp_finality_grandpa::{ConsensusLog, GrandpaApi, ScheduledChange, SetId, GRANDPA_ENGINE_ID};
|
||||
use sp_runtime::{
|
||||
generic::{BlockId, OpaqueDigestItemId},
|
||||
generic::OpaqueDigestItemId,
|
||||
traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero},
|
||||
Justification,
|
||||
};
|
||||
@@ -424,8 +424,7 @@ where
|
||||
|
||||
/// Read current set id form a given state.
|
||||
fn current_set_id(&self, hash: Block::Hash) -> Result<SetId, ConsensusError> {
|
||||
let id = &BlockId::hash(hash);
|
||||
let runtime_version = self.inner.runtime_api().version(id).map_err(|e| {
|
||||
let runtime_version = self.inner.runtime_api().version(hash).map_err(|e| {
|
||||
ConsensusError::ClientImport(format!(
|
||||
"Unable to retrieve current runtime version. {}",
|
||||
e
|
||||
@@ -452,7 +451,7 @@ where
|
||||
} else {
|
||||
self.inner
|
||||
.runtime_api()
|
||||
.current_set_id(id)
|
||||
.current_set_id(hash)
|
||||
.map_err(|e| ConsensusError::ClientImport(e.to_string()))
|
||||
}
|
||||
}
|
||||
@@ -477,7 +476,7 @@ where
|
||||
let authorities = self
|
||||
.inner
|
||||
.runtime_api()
|
||||
.grandpa_authorities(&BlockId::hash(hash))
|
||||
.grandpa_authorities(hash)
|
||||
.map_err(|e| ConsensusError::ClientImport(e.to_string()))?;
|
||||
let set_id = self.current_set_id(hash)?;
|
||||
let authority_set = AuthoritySet::new(
|
||||
|
||||
@@ -34,7 +34,7 @@ use sp_api::{NumberFor, ProvideRuntimeApi};
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use sp_core::Bytes;
|
||||
use sp_mmr_primitives::{Error as MmrError, Proof};
|
||||
use sp_runtime::{generic::BlockId, traits::Block as BlockT};
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
|
||||
pub use sp_mmr_primitives::MmrApi as MmrRuntimeApi;
|
||||
|
||||
@@ -154,7 +154,7 @@ where
|
||||
self.client.info().best_hash);
|
||||
let api = self.client.runtime_api();
|
||||
let mmr_root = api
|
||||
.mmr_root(&BlockId::Hash(block_hash))
|
||||
.mmr_root(block_hash)
|
||||
.map_err(runtime_error_into_rpc_error)?
|
||||
.map_err(mmr_error_into_rpc_error)?;
|
||||
Ok(mmr_root)
|
||||
@@ -173,7 +173,7 @@ where
|
||||
|
||||
let (leaves, proof) = api
|
||||
.generate_proof_with_context(
|
||||
&BlockId::hash(block_hash),
|
||||
block_hash,
|
||||
sp_core::ExecutionContext::OffchainCall(None),
|
||||
block_numbers,
|
||||
best_known_block_number,
|
||||
@@ -194,7 +194,7 @@ where
|
||||
.map_err(|e| CallError::InvalidParams(anyhow::Error::new(e)))?;
|
||||
|
||||
api.verify_proof_with_context(
|
||||
&BlockId::hash(proof.block_hash),
|
||||
proof.block_hash,
|
||||
sp_core::ExecutionContext::OffchainCall(None),
|
||||
leaves,
|
||||
decoded_proof,
|
||||
@@ -218,14 +218,9 @@ where
|
||||
let decoded_proof = Decode::decode(&mut &proof.proof.0[..])
|
||||
.map_err(|e| CallError::InvalidParams(anyhow::Error::new(e)))?;
|
||||
|
||||
api.verify_proof_stateless(
|
||||
&BlockId::hash(proof.block_hash),
|
||||
mmr_root,
|
||||
leaves,
|
||||
decoded_proof,
|
||||
)
|
||||
.map_err(runtime_error_into_rpc_error)?
|
||||
.map_err(mmr_error_into_rpc_error)?;
|
||||
api.verify_proof_stateless(proof.block_hash, mmr_root, leaves, decoded_proof)
|
||||
.map_err(runtime_error_into_rpc_error)?
|
||||
.map_err(mmr_error_into_rpc_error)?;
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
@@ -51,10 +51,7 @@ use sc_offchain::OffchainDb;
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sp_blockchain::{HeaderBackend, HeaderMetadata};
|
||||
use sp_mmr_primitives::{utils, LeafIndex, MmrApi};
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block, Header, NumberFor},
|
||||
};
|
||||
use sp_runtime::traits::{Block, Header, NumberFor};
|
||||
use std::{marker::PhantomData, sync::Arc};
|
||||
|
||||
/// Logging target for the mmr gadget.
|
||||
@@ -71,15 +68,16 @@ where
|
||||
{
|
||||
/// Get the block number where the mmr pallet was added to the runtime.
|
||||
fn first_mmr_block_num(&self, notification: &FinalityNotification<B>) -> Option<NumberFor<B>> {
|
||||
let best_block = *notification.header.number();
|
||||
match self.runtime_api().mmr_leaf_count(&BlockId::number(best_block)) {
|
||||
let best_block_hash = notification.header.hash();
|
||||
let best_block_number = *notification.header.number();
|
||||
match self.runtime_api().mmr_leaf_count(best_block_hash) {
|
||||
Ok(Ok(mmr_leaf_count)) => {
|
||||
match utils::first_mmr_block_num::<B::Header>(best_block, mmr_leaf_count) {
|
||||
match utils::first_mmr_block_num::<B::Header>(best_block_number, mmr_leaf_count) {
|
||||
Ok(first_mmr_block) => {
|
||||
debug!(
|
||||
target: LOG_TARGET,
|
||||
"pallet-mmr detected at block {:?} with genesis at block {:?}",
|
||||
best_block,
|
||||
best_block_number,
|
||||
first_mmr_block
|
||||
);
|
||||
Some(first_mmr_block)
|
||||
@@ -97,7 +95,7 @@ where
|
||||
trace!(
|
||||
target: LOG_TARGET,
|
||||
"pallet-mmr not detected at block {:?} ... (best finalized {:?})",
|
||||
best_block,
|
||||
best_block_number,
|
||||
notification.header.number()
|
||||
);
|
||||
None
|
||||
|
||||
@@ -45,10 +45,7 @@ use parking_lot::Mutex;
|
||||
use sc_network_common::service::{NetworkPeers, NetworkStateInfo};
|
||||
use sp_api::{ApiExt, ProvideRuntimeApi};
|
||||
use sp_core::{offchain, traits::SpawnNamed, ExecutionContext};
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{self, Header},
|
||||
};
|
||||
use sp_runtime::traits::{self, Header};
|
||||
use threadpool::ThreadPool;
|
||||
|
||||
mod api;
|
||||
@@ -123,9 +120,9 @@ where
|
||||
is_validator: bool,
|
||||
) -> 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>, _>(&at, |v| v == 1);
|
||||
let has_api_v2 = runtime.has_api_with::<dyn OffchainWorkerApi<Block>, _>(&at, |v| v == 2);
|
||||
let hash = header.hash();
|
||||
let has_api_v1 = runtime.has_api_with::<dyn OffchainWorkerApi<Block>, _>(hash, |v| v == 1);
|
||||
let has_api_v2 = runtime.has_api_with::<dyn OffchainWorkerApi<Block>, _>(hash, |v| v == 2);
|
||||
let version = match (has_api_v1, has_api_v2) {
|
||||
(_, Ok(true)) => 2,
|
||||
(Ok(true), _) => 1,
|
||||
@@ -144,13 +141,13 @@ where
|
||||
tracing::debug!(
|
||||
target: LOG_TARGET,
|
||||
"Checking offchain workers at {:?}: version:{}",
|
||||
at,
|
||||
hash,
|
||||
version
|
||||
);
|
||||
let process = (version > 0).then(|| {
|
||||
let (api, runner) =
|
||||
api::AsyncApi::new(network_provider, is_validator, self.shared_http_client.clone());
|
||||
tracing::debug!(target: LOG_TARGET, "Spawning offchain workers at {:?}", at);
|
||||
tracing::debug!(target: LOG_TARGET, "Spawning offchain workers at {:?}", hash);
|
||||
let header = header.clone();
|
||||
let client = self.client.clone();
|
||||
|
||||
@@ -160,15 +157,15 @@ where
|
||||
self.spawn_worker(move || {
|
||||
let runtime = client.runtime_api();
|
||||
let api = Box::new(api);
|
||||
tracing::debug!(target: LOG_TARGET, "Running offchain workers at {:?}", at);
|
||||
tracing::debug!(target: LOG_TARGET, "Running offchain workers at {:?}", hash);
|
||||
|
||||
let context = ExecutionContext::OffchainCall(Some((api, capabilities)));
|
||||
let run = if version == 2 {
|
||||
runtime.offchain_worker_with_context(&at, context, &header)
|
||||
runtime.offchain_worker_with_context(hash, context, &header)
|
||||
} else {
|
||||
#[allow(deprecated)]
|
||||
runtime.offchain_worker_before_version_2_with_context(
|
||||
&at,
|
||||
hash,
|
||||
context,
|
||||
*header.number(),
|
||||
)
|
||||
@@ -177,7 +174,7 @@ where
|
||||
tracing::error!(
|
||||
target: LOG_TARGET,
|
||||
"Error running offchain workers at {:?}: {}",
|
||||
at,
|
||||
hash,
|
||||
e
|
||||
);
|
||||
}
|
||||
@@ -254,6 +251,7 @@ mod tests {
|
||||
use sc_transaction_pool::{BasicPool, FullChainApi};
|
||||
use sc_transaction_pool_api::{InPoolTransaction, TransactionPool};
|
||||
use sp_consensus::BlockOrigin;
|
||||
use sp_runtime::generic::BlockId;
|
||||
use std::{collections::HashSet, sync::Arc};
|
||||
use substrate_test_runtime_client::{
|
||||
runtime::Block, ClientBlockImportExt, DefaultTestClientBuilderExt, TestClient,
|
||||
|
||||
@@ -53,10 +53,7 @@ use sp_blockchain::{
|
||||
Backend as BlockChainBackend, Error as BlockChainError, HeaderBackend, HeaderMetadata,
|
||||
};
|
||||
use sp_core::{hexdisplay::HexDisplay, storage::well_known_keys, Bytes};
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, Header},
|
||||
};
|
||||
use sp_runtime::traits::{Block as BlockT, Header};
|
||||
use std::{marker::PhantomData, sync::Arc};
|
||||
|
||||
/// An API for chain head RPC calls.
|
||||
@@ -142,12 +139,8 @@ where
|
||||
let finalized_block_hash = client.info().finalized_hash;
|
||||
handle.pin_block(finalized_block_hash)?;
|
||||
|
||||
let finalized_block_runtime = generate_runtime_event(
|
||||
&client,
|
||||
runtime_updates,
|
||||
&BlockId::Hash(finalized_block_hash),
|
||||
None,
|
||||
);
|
||||
let finalized_block_runtime =
|
||||
generate_runtime_event(&client, runtime_updates, finalized_block_hash, None);
|
||||
|
||||
let initialized_event = FollowEvent::Initialized(Initialized {
|
||||
finalized_block_hash,
|
||||
@@ -162,12 +155,7 @@ where
|
||||
for (child, parent) in initial_blocks.into_iter() {
|
||||
handle.pin_block(child)?;
|
||||
|
||||
let new_runtime = generate_runtime_event(
|
||||
&client,
|
||||
runtime_updates,
|
||||
&BlockId::Hash(child),
|
||||
Some(&BlockId::Hash(parent)),
|
||||
);
|
||||
let new_runtime = generate_runtime_event(&client, runtime_updates, child, Some(parent));
|
||||
|
||||
let event = FollowEvent::NewBlock(NewBlock {
|
||||
block_hash: child,
|
||||
@@ -214,8 +202,8 @@ fn parse_hex_param(
|
||||
fn generate_runtime_event<Client, Block>(
|
||||
client: &Arc<Client>,
|
||||
runtime_updates: bool,
|
||||
block: &BlockId<Block>,
|
||||
parent: Option<&BlockId<Block>>,
|
||||
block: Block::Hash,
|
||||
parent: Option<Block::Hash>,
|
||||
) -> Option<RuntimeEvent>
|
||||
where
|
||||
Block: BlockT + 'static,
|
||||
@@ -329,8 +317,8 @@ where
|
||||
let new_runtime = generate_runtime_event(
|
||||
&client,
|
||||
runtime_updates,
|
||||
&BlockId::Hash(notification.hash),
|
||||
Some(&BlockId::Hash(*notification.header.parent_hash())),
|
||||
notification.hash,
|
||||
Some(*notification.header.parent_hash()),
|
||||
);
|
||||
|
||||
// Note: `Block::Hash` will serialize to hexadecimal encoded string.
|
||||
|
||||
@@ -123,7 +123,7 @@ where
|
||||
let best_block_hash = self.client.info().best_hash;
|
||||
self.client
|
||||
.runtime_api()
|
||||
.generate_session_keys(&generic::BlockId::Hash(best_block_hash), None)
|
||||
.generate_session_keys(best_block_hash, None)
|
||||
.map(Into::into)
|
||||
.map_err(|api_err| Error::Client(Box::new(api_err)).into())
|
||||
}
|
||||
@@ -135,7 +135,7 @@ where
|
||||
let keys = self
|
||||
.client
|
||||
.runtime_api()
|
||||
.decode_session_keys(&generic::BlockId::Hash(best_block_hash), session_keys.to_vec())
|
||||
.decode_session_keys(best_block_hash, session_keys.to_vec())
|
||||
.map_err(|e| Error::Client(Box::new(e)))?
|
||||
.ok_or(Error::InvalidSessionKeys)?;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ use sc_rpc_api::{dev::error::Error, DenyUnsafe};
|
||||
use sp_api::{ApiExt, Core, ProvideRuntimeApi};
|
||||
use sp_core::Encode;
|
||||
use sp_runtime::{
|
||||
generic::{BlockId, DigestItem},
|
||||
generic::DigestItem,
|
||||
traits::{Block as BlockT, Header},
|
||||
};
|
||||
use std::{
|
||||
@@ -98,7 +98,7 @@ where
|
||||
let mut runtime_api = self.client.runtime_api();
|
||||
runtime_api.record_proof();
|
||||
runtime_api
|
||||
.execute_block(&BlockId::Hash(parent_header.hash()), block)
|
||||
.execute_block(parent_header.hash(), block)
|
||||
.map_err(|_| Error::BlockExecutionFailed)?;
|
||||
let witness = runtime_api
|
||||
.extract_proof()
|
||||
|
||||
@@ -48,7 +48,7 @@ use sp_core::{
|
||||
},
|
||||
Bytes,
|
||||
};
|
||||
use sp_runtime::{generic::BlockId, traits::Block as BlockT};
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
use sp_version::RuntimeVersion;
|
||||
|
||||
/// The maximum time allowed for an RPC call when running without unsafe RPC enabled.
|
||||
@@ -321,7 +321,7 @@ where
|
||||
self.block_or_best(block).map_err(client_err).and_then(|block| {
|
||||
self.client
|
||||
.runtime_api()
|
||||
.metadata(&BlockId::Hash(block))
|
||||
.metadata(block)
|
||||
.map(Into::into)
|
||||
.map_err(|e| Error::Client(Box::new(e)))
|
||||
})
|
||||
@@ -332,9 +332,7 @@ where
|
||||
block: Option<Block::Hash>,
|
||||
) -> std::result::Result<RuntimeVersion, Error> {
|
||||
self.block_or_best(block).map_err(client_err).and_then(|block| {
|
||||
self.client
|
||||
.runtime_version_at(&BlockId::Hash(block))
|
||||
.map_err(|e| Error::Client(Box::new(e)))
|
||||
self.client.runtime_version_at(block).map_err(|e| Error::Client(Box::new(e)))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -383,9 +381,7 @@ where
|
||||
|
||||
let initial = match self
|
||||
.block_or_best(None)
|
||||
.and_then(|block| {
|
||||
self.client.runtime_version_at(&BlockId::Hash(block)).map_err(Into::into)
|
||||
})
|
||||
.and_then(|block| self.client.runtime_version_at(block).map_err(Into::into))
|
||||
.map_err(|e| Error::Client(Box::new(e)))
|
||||
{
|
||||
Ok(initial) => initial,
|
||||
@@ -402,9 +398,8 @@ where
|
||||
.import_notification_stream()
|
||||
.filter(|n| future::ready(n.is_new_best))
|
||||
.filter_map(move |n| {
|
||||
let version = client
|
||||
.runtime_version_at(&BlockId::hash(n.hash))
|
||||
.map_err(|e| Error::Client(Box::new(e)));
|
||||
let version =
|
||||
client.runtime_version_at(n.hash).map_err(|e| Error::Client(Box::new(e)));
|
||||
|
||||
match version {
|
||||
Ok(version) if version != previous_version => {
|
||||
|
||||
@@ -838,7 +838,6 @@ where
|
||||
CoreApi<Block> + ApiExt<Block, StateBackend = B::State>,
|
||||
{
|
||||
let parent_hash = import_block.header.parent_hash();
|
||||
let at = BlockId::Hash(*parent_hash);
|
||||
let state_action = std::mem::replace(&mut import_block.state_action, StateAction::Skip);
|
||||
let (enact_state, storage_changes) = match (self.block_status(*parent_hash)?, state_action)
|
||||
{
|
||||
@@ -870,7 +869,7 @@ where
|
||||
let execution_context = import_block.origin.into();
|
||||
|
||||
runtime_api.execute_block_with_context(
|
||||
&at,
|
||||
*parent_hash,
|
||||
execution_context,
|
||||
Block::new(import_block.header.clone(), body.clone()),
|
||||
)?;
|
||||
@@ -1725,10 +1724,9 @@ where
|
||||
&self,
|
||||
params: CallApiAtParams<Block, B::State>,
|
||||
) -> Result<Vec<u8>, sp_api::ApiError> {
|
||||
let at_hash = self.expect_block_hash_from_id(params.at)?;
|
||||
self.executor
|
||||
.contextual_call(
|
||||
at_hash,
|
||||
params.at,
|
||||
params.function,
|
||||
¶ms.arguments,
|
||||
params.overlayed_changes,
|
||||
@@ -1739,8 +1737,7 @@ where
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
fn runtime_version_at(&self, at: &BlockId<Block>) -> Result<RuntimeVersion, sp_api::ApiError> {
|
||||
let hash = self.backend.blockchain().expect_block_hash_from_id(at)?;
|
||||
fn runtime_version_at(&self, hash: Block::Hash) -> Result<RuntimeVersion, sp_api::ApiError> {
|
||||
CallExecutor::runtime_version(&self.executor, hash).map_err(Into::into)
|
||||
}
|
||||
|
||||
|
||||
@@ -291,20 +291,14 @@ fn client_initializes_from_genesis_ok() {
|
||||
assert_eq!(
|
||||
client
|
||||
.runtime_api()
|
||||
.balance_of(
|
||||
&BlockId::Number(client.chain_info().best_number),
|
||||
AccountKeyring::Alice.into(),
|
||||
)
|
||||
.balance_of(client.chain_info().best_hash, AccountKeyring::Alice.into())
|
||||
.unwrap(),
|
||||
1000
|
||||
);
|
||||
assert_eq!(
|
||||
client
|
||||
.runtime_api()
|
||||
.balance_of(
|
||||
&BlockId::Number(client.chain_info().best_number),
|
||||
AccountKeyring::Ferdie.into(),
|
||||
)
|
||||
.balance_of(client.chain_info().best_hash, AccountKeyring::Ferdie.into())
|
||||
.unwrap(),
|
||||
0
|
||||
);
|
||||
@@ -351,20 +345,14 @@ fn block_builder_works_with_transactions() {
|
||||
assert_eq!(
|
||||
client
|
||||
.runtime_api()
|
||||
.balance_of(
|
||||
&BlockId::Number(client.chain_info().best_number),
|
||||
AccountKeyring::Alice.into(),
|
||||
)
|
||||
.balance_of(client.chain_info().best_hash, AccountKeyring::Alice.into())
|
||||
.unwrap(),
|
||||
958
|
||||
);
|
||||
assert_eq!(
|
||||
client
|
||||
.runtime_api()
|
||||
.balance_of(
|
||||
&BlockId::Number(client.chain_info().best_number),
|
||||
AccountKeyring::Ferdie.into(),
|
||||
)
|
||||
.balance_of(client.chain_info().best_hash, AccountKeyring::Ferdie.into())
|
||||
.unwrap(),
|
||||
42
|
||||
);
|
||||
@@ -1256,10 +1244,7 @@ fn state_reverted_on_reorg() {
|
||||
let current_balance = |client: &substrate_test_runtime_client::TestClient| {
|
||||
client
|
||||
.runtime_api()
|
||||
.balance_of(
|
||||
&BlockId::number(client.chain_info().best_number),
|
||||
AccountKeyring::Alice.into(),
|
||||
)
|
||||
.balance_of(client.chain_info().best_hash, AccountKeyring::Alice.into())
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
@@ -1996,10 +1981,10 @@ fn use_dalek_ext_works() {
|
||||
// On block zero it will use dalek and then on block 1 it will use zebra
|
||||
assert!(!client
|
||||
.runtime_api()
|
||||
.verify_ed25519(&BlockId::Number(0), zero_ed_sig(), zero_ed_pub(), vec![])
|
||||
.verify_ed25519(client.chain_info().genesis_hash, zero_ed_sig(), zero_ed_pub(), vec![])
|
||||
.unwrap());
|
||||
assert!(client
|
||||
.runtime_api()
|
||||
.verify_ed25519(&BlockId::Number(1), zero_ed_sig(), zero_ed_pub(), vec![])
|
||||
.verify_ed25519(a1.hash(), zero_ed_sig(), zero_ed_pub(), vec![])
|
||||
.unwrap());
|
||||
}
|
||||
|
||||
@@ -229,7 +229,6 @@ where
|
||||
.ok_or_else(|| Error::MissingBlockComponent("Extrinsics not found".to_string()))?;
|
||||
tracing::debug!(target: "state_tracing", "Found {} extrinsics", extrinsics.len());
|
||||
let parent_hash = *header.parent_hash();
|
||||
let parent_id = BlockId::Hash(parent_hash);
|
||||
// Remove all `Seal`s as they are added by the consensus engines after building the block.
|
||||
// On import they are normally removed by the consensus engine.
|
||||
header.digest_mut().logs.retain(|d| d.as_seal().is_none());
|
||||
@@ -249,7 +248,7 @@ where
|
||||
if let Err(e) = dispatcher::with_default(&dispatch, || {
|
||||
let span = tracing::info_span!(target: TRACE_TARGET, "trace_block");
|
||||
let _enter = span.enter();
|
||||
self.client.runtime_api().execute_block(&parent_id, block)
|
||||
self.client.runtime_api().execute_block(parent_hash, block)
|
||||
}) {
|
||||
return Err(Error::Dispatch(format!(
|
||||
"Failed to collect traces and execute block: {}",
|
||||
@@ -298,7 +297,7 @@ where
|
||||
} else {
|
||||
TraceBlockResponse::BlockTrace(BlockTrace {
|
||||
block_hash: block_id_as_string(BlockId::<Block>::Hash(self.block)),
|
||||
parent_hash: block_id_as_string(parent_id),
|
||||
parent_hash: block_id_as_string(BlockId::<Block>::Hash(parent_hash)),
|
||||
tracing_targets: targets.to_string(),
|
||||
storage_keys: self.storage_keys.clone().unwrap_or_default(),
|
||||
methods: self.methods.clone().unwrap_or_default(),
|
||||
|
||||
@@ -225,27 +225,27 @@ where
|
||||
{
|
||||
sp_tracing::within_span!(sp_tracing::Level::TRACE, "validate_transaction";
|
||||
{
|
||||
let block_hash = client.to_hash(at)
|
||||
.map_err(|e| Error::RuntimeApi(e.to_string()))?
|
||||
.ok_or_else(|| Error::RuntimeApi(format!("Could not get hash for block `{:?}`.", at)))?;
|
||||
|
||||
let runtime_api = client.runtime_api();
|
||||
let api_version = sp_tracing::within_span! { sp_tracing::Level::TRACE, "check_version";
|
||||
runtime_api
|
||||
.api_version::<dyn TaggedTransactionQueue<Block>>(at)
|
||||
.api_version::<dyn TaggedTransactionQueue<Block>>(block_hash)
|
||||
.map_err(|e| Error::RuntimeApi(e.to_string()))?
|
||||
.ok_or_else(|| Error::RuntimeApi(
|
||||
format!("Could not find `TaggedTransactionQueue` api for block `{:?}`.", at)
|
||||
))
|
||||
}?;
|
||||
|
||||
let block_hash = client.to_hash(at)
|
||||
.map_err(|e| Error::RuntimeApi(e.to_string()))?
|
||||
.ok_or_else(|| Error::RuntimeApi(format!("Could not get hash for block `{:?}`.", at)))?;
|
||||
|
||||
use sp_api::Core;
|
||||
|
||||
sp_tracing::within_span!(
|
||||
sp_tracing::Level::TRACE, "runtime::validate_transaction";
|
||||
{
|
||||
if api_version >= 3 {
|
||||
runtime_api.validate_transaction(at, source, uxt, block_hash)
|
||||
runtime_api.validate_transaction(block_hash, source, uxt, block_hash)
|
||||
.map_err(|e| Error::RuntimeApi(e.to_string()))
|
||||
} else {
|
||||
let block_number = client.to_number(at)
|
||||
@@ -255,7 +255,7 @@ where
|
||||
)?;
|
||||
|
||||
// The old versions require us to call `initialize_block` before.
|
||||
runtime_api.initialize_block(at, &sp_runtime::traits::Header::new(
|
||||
runtime_api.initialize_block(block_hash, &sp_runtime::traits::Header::new(
|
||||
block_number + sp_runtime::traits::One::one(),
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
@@ -265,11 +265,11 @@ where
|
||||
|
||||
if api_version == 2 {
|
||||
#[allow(deprecated)] // old validate_transaction
|
||||
runtime_api.validate_transaction_before_version_3(at, source, uxt)
|
||||
runtime_api.validate_transaction_before_version_3(block_hash, source, uxt)
|
||||
.map_err(|e| Error::RuntimeApi(e.to_string()))
|
||||
} else {
|
||||
#[allow(deprecated)] // old validate_transaction
|
||||
runtime_api.validate_transaction_before_version_2(at, uxt)
|
||||
runtime_api.validate_transaction_before_version_2(block_hash, uxt)
|
||||
.map_err(|e| Error::RuntimeApi(e.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,10 +30,7 @@ use sp_api::{ApiExt, ProvideRuntimeApi};
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use sp_core::Bytes;
|
||||
use sp_rpc::number::NumberOrHex;
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, MaybeDisplay},
|
||||
};
|
||||
use sp_runtime::traits::{Block as BlockT, MaybeDisplay};
|
||||
|
||||
pub use pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi as TransactionPaymentRuntimeApi;
|
||||
|
||||
@@ -98,7 +95,7 @@ where
|
||||
at: Option<Block::Hash>,
|
||||
) -> RpcResult<RuntimeDispatchInfo<Balance, sp_weights::OldWeight>> {
|
||||
let api = self.client.runtime_api();
|
||||
let at = BlockId::hash(at.unwrap_or_else(|| self.client.info().best_hash));
|
||||
let at_hash = at.unwrap_or_else(|| self.client.info().best_hash);
|
||||
|
||||
let encoded_len = encoded_xt.len() as u32;
|
||||
|
||||
@@ -119,7 +116,7 @@ where
|
||||
}
|
||||
|
||||
let api_version = api
|
||||
.api_version::<dyn TransactionPaymentRuntimeApi<Block, Balance>>(&at)
|
||||
.api_version::<dyn TransactionPaymentRuntimeApi<Block, Balance>>(at_hash)
|
||||
.map_err(|e| map_err(e, "Failed to get transaction payment runtime api version"))?
|
||||
.ok_or_else(|| {
|
||||
CallError::Custom(ErrorObject::owned(
|
||||
@@ -131,11 +128,11 @@ where
|
||||
|
||||
if api_version < 2 {
|
||||
#[allow(deprecated)]
|
||||
api.query_info_before_version_2(&at, uxt, encoded_len)
|
||||
api.query_info_before_version_2(at_hash, uxt, encoded_len)
|
||||
.map_err(|e| map_err(e, "Unable to query dispatch info.").into())
|
||||
} else {
|
||||
let res = api
|
||||
.query_info(&at, uxt, encoded_len)
|
||||
.query_info(at_hash, uxt, encoded_len)
|
||||
.map_err(|e| map_err(e, "Unable to query dispatch info."))?;
|
||||
|
||||
Ok(RuntimeDispatchInfo {
|
||||
@@ -152,7 +149,7 @@ where
|
||||
at: Option<Block::Hash>,
|
||||
) -> RpcResult<FeeDetails<NumberOrHex>> {
|
||||
let api = self.client.runtime_api();
|
||||
let at = BlockId::hash(at.unwrap_or_else(|| self.client.info().best_hash));
|
||||
let at_hash = at.unwrap_or_else(|| self.client.info().best_hash);
|
||||
|
||||
let encoded_len = encoded_xt.len() as u32;
|
||||
|
||||
@@ -163,7 +160,7 @@ where
|
||||
Some(format!("{:?}", e)),
|
||||
))
|
||||
})?;
|
||||
let fee_details = api.query_fee_details(&at, uxt, encoded_len).map_err(|e| {
|
||||
let fee_details = api.query_fee_details(at_hash, uxt, encoded_len).map_err(|e| {
|
||||
CallError::Custom(ErrorObject::owned(
|
||||
Error::RuntimeError.into(),
|
||||
"Unable to query fee details.",
|
||||
|
||||
@@ -316,7 +316,7 @@ fn generate_runtime_decls(decls: &[ItemTrait]) -> Result<TokenStream> {
|
||||
|
||||
/// Modify the given runtime api declaration to be usable on the client side.
|
||||
struct ToClientSideDecl<'a> {
|
||||
block_id: &'a TokenStream,
|
||||
block_hash: &'a TokenStream,
|
||||
crate_: &'a TokenStream,
|
||||
found_attributes: &'a mut HashMap<&'static str, Attribute>,
|
||||
/// Any error that we found while converting this declaration.
|
||||
@@ -329,7 +329,7 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
fn process(mut self, decl: ItemTrait) -> ItemTrait {
|
||||
let mut decl = self.fold_item_trait(decl);
|
||||
|
||||
let block_id = self.block_id;
|
||||
let block_hash = self.block_hash;
|
||||
let crate_ = self.crate_;
|
||||
|
||||
// Add the special method that will be implemented by the `impl_runtime_apis!` macro
|
||||
@@ -339,7 +339,7 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
#[doc(hidden)]
|
||||
fn __runtime_api_internal_call_api_at(
|
||||
&self,
|
||||
at: &#block_id,
|
||||
at: #block_hash,
|
||||
context: #crate_::ExecutionContext,
|
||||
params: std::vec::Vec<u8>,
|
||||
fn_name: &dyn Fn(#crate_::RuntimeVersion) -> &'static str,
|
||||
@@ -420,7 +420,7 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
};
|
||||
let ret_type = return_type_extract_type(&method.sig.output);
|
||||
|
||||
fold_fn_decl_for_client_side(&mut method.sig, self.block_id, self.crate_);
|
||||
fold_fn_decl_for_client_side(&mut method.sig, self.block_hash, self.crate_);
|
||||
|
||||
let crate_ = self.crate_;
|
||||
|
||||
@@ -621,14 +621,14 @@ fn generate_client_side_decls(decls: &[ItemTrait]) -> Result<TokenStream> {
|
||||
let decl = decl.clone();
|
||||
|
||||
let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID);
|
||||
let block_id = quote!( #crate_::BlockId<Block> );
|
||||
let block_hash = quote!( <Block as #crate_::BlockT>::Hash );
|
||||
let mut found_attributes = HashMap::new();
|
||||
let mut errors = Vec::new();
|
||||
let trait_ = decl.ident.clone();
|
||||
|
||||
let decl = ToClientSideDecl {
|
||||
crate_: &crate_,
|
||||
block_id: &block_id,
|
||||
block_hash: &block_hash,
|
||||
found_attributes: &mut found_attributes,
|
||||
errors: &mut errors,
|
||||
trait_: &trait_,
|
||||
|
||||
@@ -233,7 +233,7 @@ fn generate_runtime_api_base_structures() -> Result<TokenStream> {
|
||||
|
||||
fn has_api<A: #crate_::RuntimeApiInfo + ?Sized>(
|
||||
&self,
|
||||
at: &#crate_::BlockId<Block>,
|
||||
at: <Block as #crate_::BlockT>::Hash,
|
||||
) -> std::result::Result<bool, #crate_::ApiError> where Self: Sized {
|
||||
#crate_::CallApiAt::<Block>::runtime_version_at(self.call, at)
|
||||
.map(|v| #crate_::RuntimeVersion::has_api_with(&v, &A::ID, |v| v == A::VERSION))
|
||||
@@ -241,7 +241,7 @@ fn generate_runtime_api_base_structures() -> Result<TokenStream> {
|
||||
|
||||
fn has_api_with<A: #crate_::RuntimeApiInfo + ?Sized, P: Fn(u32) -> bool>(
|
||||
&self,
|
||||
at: &#crate_::BlockId<Block>,
|
||||
at: <Block as #crate_::BlockT>::Hash,
|
||||
pred: P,
|
||||
) -> std::result::Result<bool, #crate_::ApiError> where Self: Sized {
|
||||
#crate_::CallApiAt::<Block>::runtime_version_at(self.call, at)
|
||||
@@ -250,7 +250,7 @@ fn generate_runtime_api_base_structures() -> Result<TokenStream> {
|
||||
|
||||
fn api_version<A: #crate_::RuntimeApiInfo + ?Sized>(
|
||||
&self,
|
||||
at: &#crate_::BlockId<Block>,
|
||||
at: <Block as #crate_::BlockT>::Hash,
|
||||
) -> std::result::Result<Option<u32>, #crate_::ApiError> where Self: Sized {
|
||||
#crate_::CallApiAt::<Block>::runtime_version_at(self.call, at)
|
||||
.map(|v| #crate_::RuntimeVersion::api_version(&v, &A::ID))
|
||||
@@ -281,8 +281,7 @@ fn generate_runtime_api_base_structures() -> Result<TokenStream> {
|
||||
#crate_::StorageChanges<C::StateBackend, Block>,
|
||||
String
|
||||
> where Self: Sized {
|
||||
let at = #crate_::BlockId::Hash(std::clone::Clone::clone(&parent_hash));
|
||||
let state_version = #crate_::CallApiAt::<Block>::runtime_version_at(self.call, &at)
|
||||
let state_version = #crate_::CallApiAt::<Block>::runtime_version_at(self.call, std::clone::Clone::clone(&parent_hash))
|
||||
.map(|v| #crate_::RuntimeVersion::state_version(&v))
|
||||
.map_err(|e| format!("Failed to get state version: {}", e))?;
|
||||
|
||||
@@ -424,7 +423,7 @@ impl<'a> ApiRuntimeImplToApiRuntimeApiImpl<'a> {
|
||||
input.items.push(parse_quote! {
|
||||
fn __runtime_api_internal_call_api_at(
|
||||
&self,
|
||||
at: &#crate_::BlockId<__SR_API_BLOCK__>,
|
||||
at: <__SR_API_BLOCK__ as #crate_::BlockT>::Hash,
|
||||
context: #crate_::ExecutionContext,
|
||||
params: std::vec::Vec<u8>,
|
||||
fn_name: &dyn Fn(#crate_::RuntimeVersion) -> &'static str,
|
||||
|
||||
@@ -38,7 +38,7 @@ const HIDDEN_INCLUDES_ID: &str = "MOCK_IMPL_RUNTIME_APIS";
|
||||
|
||||
/// The `advanced` attribute.
|
||||
///
|
||||
/// If this attribute is given to a function, the function gets access to the `BlockId` as first
|
||||
/// If this attribute is given to a function, the function gets access to the `Hash` as first
|
||||
/// parameter and needs to return a `Result` with the appropriate error type.
|
||||
const ADVANCED_ATTRIBUTE: &str = "advanced";
|
||||
|
||||
@@ -80,14 +80,14 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
|
||||
|
||||
fn has_api<A: #crate_::RuntimeApiInfo + ?Sized>(
|
||||
&self,
|
||||
_: &#crate_::BlockId<#block_type>,
|
||||
_: <Block as #crate_::BlockT>::Hash,
|
||||
) -> std::result::Result<bool, #crate_::ApiError> where Self: Sized {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn has_api_with<A: #crate_::RuntimeApiInfo + ?Sized, P: Fn(u32) -> bool>(
|
||||
&self,
|
||||
_: &#crate_::BlockId<#block_type>,
|
||||
_: <Block as #crate_::BlockT>::Hash,
|
||||
pred: P,
|
||||
) -> std::result::Result<bool, #crate_::ApiError> where Self: Sized {
|
||||
Ok(pred(A::VERSION))
|
||||
@@ -95,7 +95,7 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
|
||||
|
||||
fn api_version<A: #crate_::RuntimeApiInfo + ?Sized>(
|
||||
&self,
|
||||
_: &#crate_::BlockId<#block_type>,
|
||||
_: <Block as #crate_::BlockT>::Hash,
|
||||
) -> std::result::Result<Option<u32>, #crate_::ApiError> where Self: Sized {
|
||||
Ok(Some(A::VERSION))
|
||||
}
|
||||
@@ -129,7 +129,7 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
|
||||
impl #crate_::Core<#block_type> for #self_ty {
|
||||
fn __runtime_api_internal_call_api_at(
|
||||
&self,
|
||||
_: &#crate_::BlockId<#block_type>,
|
||||
_: <#block_type as #crate_::BlockT>::Hash,
|
||||
_: #crate_::ExecutionContext,
|
||||
_: std::vec::Vec<u8>,
|
||||
_: &dyn Fn(#crate_::RuntimeVersion) -> &'static str,
|
||||
@@ -139,14 +139,14 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
|
||||
|
||||
fn version(
|
||||
&self,
|
||||
_: &#crate_::BlockId<#block_type>,
|
||||
_: <#block_type as #crate_::BlockT>::Hash,
|
||||
) -> std::result::Result<#crate_::RuntimeVersion, #crate_::ApiError> {
|
||||
unimplemented!("`Core::version` not implemented for runtime api mocks")
|
||||
}
|
||||
|
||||
fn version_with_context(
|
||||
&self,
|
||||
_: &#crate_::BlockId<#block_type>,
|
||||
_: <#block_type as #crate_::BlockT>::Hash,
|
||||
_: #crate_::ExecutionContext,
|
||||
) -> std::result::Result<#crate_::RuntimeVersion, #crate_::ApiError> {
|
||||
unimplemented!("`Core::version` not implemented for runtime api mocks")
|
||||
@@ -154,7 +154,7 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
|
||||
|
||||
fn execute_block(
|
||||
&self,
|
||||
_: &#crate_::BlockId<#block_type>,
|
||||
_: <#block_type as #crate_::BlockT>::Hash,
|
||||
_: #block_type,
|
||||
) -> std::result::Result<(), #crate_::ApiError> {
|
||||
unimplemented!("`Core::execute_block` not implemented for runtime api mocks")
|
||||
@@ -162,7 +162,7 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
|
||||
|
||||
fn execute_block_with_context(
|
||||
&self,
|
||||
_: &#crate_::BlockId<#block_type>,
|
||||
_: <#block_type as #crate_::BlockT>::Hash,
|
||||
_: #crate_::ExecutionContext,
|
||||
_: #block_type,
|
||||
) -> std::result::Result<(), #crate_::ApiError> {
|
||||
@@ -171,7 +171,7 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
|
||||
|
||||
fn initialize_block(
|
||||
&self,
|
||||
_: &#crate_::BlockId<#block_type>,
|
||||
_: <#block_type as #crate_::BlockT>::Hash,
|
||||
_: &<#block_type as #crate_::BlockT>::Header,
|
||||
) -> std::result::Result<(), #crate_::ApiError> {
|
||||
unimplemented!("`Core::initialize_block` not implemented for runtime api mocks")
|
||||
@@ -179,7 +179,7 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
|
||||
|
||||
fn initialize_block_with_context(
|
||||
&self,
|
||||
_: &#crate_::BlockId<#block_type>,
|
||||
_: <#block_type as #crate_::BlockT>::Hash,
|
||||
_: #crate_::ExecutionContext,
|
||||
_: &<#block_type as #crate_::BlockT>::Header,
|
||||
) -> std::result::Result<(), #crate_::ApiError> {
|
||||
@@ -214,7 +214,7 @@ fn get_at_param_name(
|
||||
param_names: &mut Vec<Pat>,
|
||||
param_types_and_borrows: &mut Vec<(TokenStream, bool)>,
|
||||
function_span: Span,
|
||||
default_block_id_type: &TokenStream,
|
||||
default_hash_type: &TokenStream,
|
||||
) -> Result<(TokenStream, TokenStream)> {
|
||||
if is_advanced {
|
||||
if param_names.is_empty() {
|
||||
@@ -222,7 +222,7 @@ fn get_at_param_name(
|
||||
function_span,
|
||||
format!(
|
||||
"If using the `{}` attribute, it is required that the function \
|
||||
takes at least one argument, the `BlockId`.",
|
||||
takes at least one argument, the `Hash`.",
|
||||
ADVANCED_ATTRIBUTE,
|
||||
),
|
||||
))
|
||||
@@ -232,17 +232,14 @@ fn get_at_param_name(
|
||||
// `param_types` can not be empty as well.
|
||||
let ptype_and_borrows = param_types_and_borrows.remove(0);
|
||||
let span = ptype_and_borrows.1.span();
|
||||
if !ptype_and_borrows.1 {
|
||||
return Err(Error::new(
|
||||
span,
|
||||
"`BlockId` needs to be taken by reference and not by value!",
|
||||
))
|
||||
if ptype_and_borrows.1 {
|
||||
return Err(Error::new(span, "`Hash` needs to be taken by value and not by reference!"))
|
||||
}
|
||||
|
||||
let name = param_names.remove(0);
|
||||
Ok((quote!( #name ), ptype_and_borrows.0))
|
||||
} else {
|
||||
Ok((quote!(_), default_block_id_type.clone()))
|
||||
Ok((quote!(_), default_hash_type.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +276,7 @@ impl<'a> FoldRuntimeApiImpl<'a> {
|
||||
impl_item.items.push(parse_quote! {
|
||||
fn __runtime_api_internal_call_api_at(
|
||||
&self,
|
||||
_: &#crate_::BlockId<#block_type>,
|
||||
_: <#block_type as #crate_::BlockT>::Hash,
|
||||
_: #crate_::ExecutionContext,
|
||||
_: std::vec::Vec<u8>,
|
||||
_: &dyn Fn(#crate_::RuntimeVersion) -> &'static str,
|
||||
@@ -325,19 +322,19 @@ impl<'a> Fold for FoldRuntimeApiImpl<'a> {
|
||||
};
|
||||
|
||||
let block_type = &self.block_type;
|
||||
let block_id_type = quote!( &#crate_::BlockId<#block_type> );
|
||||
let hash_type = quote!( <#block_type as #crate_::BlockT>::Hash );
|
||||
|
||||
let (at_param_name, block_id_type) = match get_at_param_name(
|
||||
let (at_param_name, hash_type) = match get_at_param_name(
|
||||
is_advanced,
|
||||
&mut param_names,
|
||||
&mut param_types_and_borrows,
|
||||
input.span(),
|
||||
&block_id_type,
|
||||
&hash_type,
|
||||
) {
|
||||
Ok(res) => res,
|
||||
Err(e) => {
|
||||
errors.push(e.to_compile_error());
|
||||
(quote!(_), block_id_type)
|
||||
(quote!(_), hash_type)
|
||||
},
|
||||
};
|
||||
|
||||
@@ -345,7 +342,7 @@ impl<'a> Fold for FoldRuntimeApiImpl<'a> {
|
||||
// Rewrite the input parameters.
|
||||
input.sig.inputs = parse_quote! {
|
||||
&self,
|
||||
#at_param_name: #block_id_type,
|
||||
#at_param_name: #hash_type,
|
||||
#( #param_names: #param_types ),*
|
||||
};
|
||||
|
||||
|
||||
@@ -94,13 +94,13 @@ pub fn replace_wild_card_parameter_names(input: &mut Signature) {
|
||||
/// Fold the given `Signature` to make it usable on the client side.
|
||||
pub fn fold_fn_decl_for_client_side(
|
||||
input: &mut Signature,
|
||||
block_id: &TokenStream,
|
||||
block_hash: &TokenStream,
|
||||
crate_: &TokenStream,
|
||||
) {
|
||||
replace_wild_card_parameter_names(input);
|
||||
|
||||
// Add `&self, at:& BlockId` as parameters to each function at the beginning.
|
||||
input.inputs.insert(0, parse_quote!( __runtime_api_at_param__: &#block_id ));
|
||||
// Add `&self, at:& Block::Hash` as parameters to each function at the beginning.
|
||||
input.inputs.insert(0, parse_quote!( __runtime_api_at_param__: #block_hash ));
|
||||
input.inputs.insert(0, parse_quote!(&self));
|
||||
|
||||
// Wrap the output in a `Result`
|
||||
|
||||
@@ -115,7 +115,7 @@ pub const MAX_EXTRINSIC_DEPTH: u32 = 256;
|
||||
/// The macro will create two declarations, one for using on the client side and one for using
|
||||
/// on the runtime side. The declaration for the runtime side is hidden in its own module.
|
||||
/// The client side declaration gets two extra parameters per function,
|
||||
/// `&self` and `at: &BlockId<Block>`. The runtime side declaration will match the given trait
|
||||
/// `&self` and `at: Block::Hash`. The runtime side declaration will match the given trait
|
||||
/// declaration. Besides one exception, the macro adds an extra generic parameter `Block:
|
||||
/// BlockT` to the client side and the runtime side. This generic parameter is usable by the
|
||||
/// user.
|
||||
@@ -182,7 +182,7 @@ pub const MAX_EXTRINSIC_DEPTH: u32 = 256;
|
||||
/// ```
|
||||
///
|
||||
/// To check if a given runtime implements a runtime api trait, the `RuntimeVersion` has the
|
||||
/// function `has_api<A>()`. Also the `ApiExt` provides a function `has_api<A>(at: &BlockId)`
|
||||
/// function `has_api<A>()`. Also the `ApiExt` provides a function `has_api<A>(at: Hash)`
|
||||
/// to check if the runtime at the given block id implements the requested runtime api trait.
|
||||
///
|
||||
/// # Declaring multiple api versions
|
||||
@@ -400,16 +400,16 @@ pub use sp_api_proc_macro::impl_runtime_apis;
|
||||
///
|
||||
/// This attribute can be placed above individual function in the mock implementation to
|
||||
/// request more control over the function declaration. From the client side each runtime api
|
||||
/// function is called with the `at` parameter that is a [`BlockId`](sp_api::BlockId). When
|
||||
/// using the `advanced` attribute, the macro expects that the first parameter of the function
|
||||
/// is this `at` parameter. Besides that the macro also doesn't do the automatic return value
|
||||
/// rewrite, which means that full return value must be specified. The full return value is
|
||||
/// constructed like [`Result`]`<<ReturnValue>, Error>` while `ReturnValue` being the return
|
||||
/// value that is specified in the trait declaration.
|
||||
/// function is called with the `at` parameter that is a [`Hash`](sp_runtime::traits::Hash).
|
||||
/// When using the `advanced` attribute, the macro expects that the first parameter of the
|
||||
/// function is this `at` parameter. Besides that the macro also doesn't do the automatic
|
||||
/// return value rewrite, which means that full return value must be specified. The full return
|
||||
/// value is constructed like [`Result`]`<<ReturnValue>, Error>` while `ReturnValue` being the
|
||||
/// return value that is specified in the trait declaration.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```rust
|
||||
/// # use sp_runtime::{traits::Block as BlockT, generic::BlockId};
|
||||
/// # use sp_runtime::traits::Block as BlockT;
|
||||
/// # use sp_test_primitives::Block;
|
||||
/// # use codec;
|
||||
/// #
|
||||
@@ -429,16 +429,14 @@ pub use sp_api_proc_macro::impl_runtime_apis;
|
||||
/// sp_api::mock_impl_runtime_apis! {
|
||||
/// impl Balance<Block> for MockApi {
|
||||
/// #[advanced]
|
||||
/// fn get_balance(&self, at: &BlockId<Block>) -> Result<u64, sp_api::ApiError> {
|
||||
/// fn get_balance(&self, at: <Block as BlockT>::Hash) -> Result<u64, sp_api::ApiError> {
|
||||
/// println!("Being called at: {}", at);
|
||||
///
|
||||
/// Ok(self.balance.into())
|
||||
/// }
|
||||
/// #[advanced]
|
||||
/// fn set_balance(at: &BlockId<Block>, val: u64) -> Result<(), sp_api::ApiError> {
|
||||
/// if let BlockId::Number(1) = at {
|
||||
/// println!("Being called to set balance to: {}", val);
|
||||
/// }
|
||||
/// fn set_balance(at: <Block as BlockT>::Hash, val: u64) -> Result<(), sp_api::ApiError> {
|
||||
/// println!("Being called at: {}", at);
|
||||
///
|
||||
/// Ok(().into())
|
||||
/// }
|
||||
@@ -539,14 +537,14 @@ pub trait ApiExt<Block: BlockT> {
|
||||
Self: Sized;
|
||||
|
||||
/// Checks if the given api is implemented and versions match.
|
||||
fn has_api<A: RuntimeApiInfo + ?Sized>(&self, at: &BlockId<Block>) -> Result<bool, ApiError>
|
||||
fn has_api<A: RuntimeApiInfo + ?Sized>(&self, at_hash: Block::Hash) -> 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>,
|
||||
at_hash: Block::Hash,
|
||||
pred: P,
|
||||
) -> Result<bool, ApiError>
|
||||
where
|
||||
@@ -555,7 +553,7 @@ pub trait ApiExt<Block: BlockT> {
|
||||
/// Returns the version of the given api.
|
||||
fn api_version<A: RuntimeApiInfo + ?Sized>(
|
||||
&self,
|
||||
at: &BlockId<Block>,
|
||||
at_hash: Block::Hash,
|
||||
) -> Result<Option<u32>, ApiError>
|
||||
where
|
||||
Self: Sized;
|
||||
@@ -590,7 +588,7 @@ pub trait ApiExt<Block: BlockT> {
|
||||
#[cfg(feature = "std")]
|
||||
pub struct CallApiAtParams<'a, Block: BlockT, Backend: StateBackend<HashFor<Block>>> {
|
||||
/// The block id that determines the state that should be setup when calling the function.
|
||||
pub at: &'a BlockId<Block>,
|
||||
pub at: Block::Hash,
|
||||
/// The name of the function that should be called.
|
||||
pub function: &'static str,
|
||||
/// The encoded arguments of the function.
|
||||
@@ -619,7 +617,7 @@ pub trait CallApiAt<Block: BlockT> {
|
||||
) -> Result<Vec<u8>, ApiError>;
|
||||
|
||||
/// Returns the runtime version at the given block.
|
||||
fn runtime_version_at(&self, at: &BlockId<Block>) -> Result<RuntimeVersion, ApiError>;
|
||||
fn runtime_version_at(&self, at_hash: Block::Hash) -> Result<RuntimeVersion, ApiError>;
|
||||
|
||||
/// Get the state `at` the given block.
|
||||
fn state_at(&self, at: Block::Hash) -> Result<Self::StateBackend, ApiError>;
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sp_runtime::generic::BlockId;
|
||||
use sp_state_machine::ExecutionStrategy;
|
||||
use substrate_test_runtime_client::{
|
||||
runtime::TestAPI, DefaultTestClientBuilderExt, TestClientBuilder, TestClientBuilderExt,
|
||||
@@ -27,49 +26,49 @@ fn sp_api_benchmark(c: &mut Criterion) {
|
||||
c.bench_function("add one with same runtime api", |b| {
|
||||
let client = substrate_test_runtime_client::new();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Hash(client.chain_info().best_hash);
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
|
||||
b.iter(|| runtime_api.benchmark_add_one(&block_id, &1))
|
||||
b.iter(|| runtime_api.benchmark_add_one(best_hash, &1))
|
||||
});
|
||||
|
||||
c.bench_function("add one with recreating runtime api", |b| {
|
||||
let client = substrate_test_runtime_client::new();
|
||||
let block_id = BlockId::Hash(client.chain_info().best_hash);
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
|
||||
b.iter(|| client.runtime_api().benchmark_add_one(&block_id, &1))
|
||||
b.iter(|| client.runtime_api().benchmark_add_one(best_hash, &1))
|
||||
});
|
||||
|
||||
c.bench_function("vector add one with same runtime api", |b| {
|
||||
let client = substrate_test_runtime_client::new();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Hash(client.chain_info().best_hash);
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
let data = vec![0; 1000];
|
||||
|
||||
b.iter_with_large_drop(|| runtime_api.benchmark_vector_add_one(&block_id, &data))
|
||||
b.iter_with_large_drop(|| runtime_api.benchmark_vector_add_one(best_hash, &data))
|
||||
});
|
||||
|
||||
c.bench_function("vector add one with recreating runtime api", |b| {
|
||||
let client = substrate_test_runtime_client::new();
|
||||
let block_id = BlockId::Hash(client.chain_info().best_hash);
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
let data = vec![0; 1000];
|
||||
|
||||
b.iter_with_large_drop(|| client.runtime_api().benchmark_vector_add_one(&block_id, &data))
|
||||
b.iter_with_large_drop(|| client.runtime_api().benchmark_vector_add_one(best_hash, &data))
|
||||
});
|
||||
|
||||
c.bench_function("calling function by function pointer in wasm", |b| {
|
||||
let client = TestClientBuilder::new()
|
||||
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
|
||||
.build();
|
||||
let block_id = BlockId::Hash(client.chain_info().best_hash);
|
||||
b.iter(|| client.runtime_api().benchmark_indirect_call(&block_id).unwrap())
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
b.iter(|| client.runtime_api().benchmark_indirect_call(best_hash).unwrap())
|
||||
});
|
||||
|
||||
c.bench_function("calling function in wasm", |b| {
|
||||
let client = TestClientBuilder::new()
|
||||
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
|
||||
.build();
|
||||
let block_id = BlockId::Hash(client.chain_info().best_hash);
|
||||
b.iter(|| client.runtime_api().benchmark_direct_call(&block_id).unwrap())
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
b.iter(|| client.runtime_api().benchmark_direct_call(best_hash).unwrap())
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -18,11 +18,9 @@
|
||||
use sp_api::{
|
||||
decl_runtime_apis, impl_runtime_apis, mock_impl_runtime_apis, ApiError, ApiExt, RuntimeApiInfo,
|
||||
};
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, GetNodeBlockType},
|
||||
};
|
||||
use substrate_test_runtime_client::runtime::Block;
|
||||
use sp_runtime::traits::{Block as BlockT, GetNodeBlockType};
|
||||
|
||||
use substrate_test_runtime_client::runtime::{Block, Hash};
|
||||
|
||||
/// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType`
|
||||
/// trait are done by the `construct_runtime!` macro in a real runtime.
|
||||
@@ -119,13 +117,13 @@ mock_impl_runtime_apis! {
|
||||
}
|
||||
|
||||
#[advanced]
|
||||
fn same_name(_: &BlockId<Block>) -> Result<(), ApiError> {
|
||||
fn same_name(_: <Block as BlockT>::Hash) -> Result<(), ApiError> {
|
||||
Ok(().into())
|
||||
}
|
||||
|
||||
#[advanced]
|
||||
fn wild_card(at: &BlockId<Block>, _: u32) -> Result<(), ApiError> {
|
||||
if let BlockId::Number(1337) = at {
|
||||
fn wild_card(at: <Block as BlockT>::Hash, _: u32) -> Result<(), ApiError> {
|
||||
if Hash::repeat_byte(0x0f) == at {
|
||||
// yeah
|
||||
Ok(().into())
|
||||
} else {
|
||||
@@ -150,19 +148,19 @@ type TestClient = substrate_test_runtime_client::client::Client<
|
||||
fn test_client_side_function_signature() {
|
||||
let _test: fn(
|
||||
&RuntimeApiImpl<Block, TestClient>,
|
||||
&BlockId<Block>,
|
||||
<Block as BlockT>::Hash,
|
||||
u64,
|
||||
) -> Result<(), ApiError> = RuntimeApiImpl::<Block, TestClient>::test;
|
||||
let _something_with_block: fn(
|
||||
&RuntimeApiImpl<Block, TestClient>,
|
||||
&BlockId<Block>,
|
||||
<Block as BlockT>::Hash,
|
||||
Block,
|
||||
) -> Result<Block, ApiError> = RuntimeApiImpl::<Block, TestClient>::something_with_block;
|
||||
|
||||
#[allow(deprecated)]
|
||||
let _same_name_before_version_2: fn(
|
||||
&RuntimeApiImpl<Block, TestClient>,
|
||||
&BlockId<Block>,
|
||||
<Block as BlockT>::Hash,
|
||||
) -> Result<String, ApiError> = RuntimeApiImpl::<Block, TestClient>::same_name_before_version_2;
|
||||
}
|
||||
|
||||
@@ -204,8 +202,8 @@ fn check_runtime_api_versions() {
|
||||
fn mock_runtime_api_has_api() {
|
||||
let mock = MockApi { block: None };
|
||||
|
||||
assert!(mock.has_api::<dyn ApiWithCustomVersion<Block>>(&BlockId::Number(0)).unwrap());
|
||||
assert!(mock.has_api::<dyn Api<Block>>(&BlockId::Number(0)).unwrap());
|
||||
assert!(mock.has_api::<dyn ApiWithCustomVersion<Block>>(Hash::default()).unwrap());
|
||||
assert!(mock.has_api::<dyn Api<Block>>(Hash::default()).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -214,17 +212,17 @@ fn mock_runtime_api_panics_on_calling_old_version() {
|
||||
let mock = MockApi { block: None };
|
||||
|
||||
#[allow(deprecated)]
|
||||
let _ = mock.same_name_before_version_2(&BlockId::Number(0));
|
||||
let _ = mock.same_name_before_version_2(Hash::default());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mock_runtime_api_works_with_advanced() {
|
||||
let mock = MockApi { block: None };
|
||||
|
||||
Api::<Block>::same_name(&mock, &BlockId::Number(0)).unwrap();
|
||||
mock.wild_card(&BlockId::Number(1337), 1).unwrap();
|
||||
Api::<Block>::same_name(&mock, Hash::default()).unwrap();
|
||||
mock.wild_card(Hash::repeat_byte(0x0f), 1).unwrap();
|
||||
assert_eq!(
|
||||
"Test error".to_string(),
|
||||
mock.wild_card(&BlockId::Number(1336), 1).unwrap_err().to_string(),
|
||||
mock.wild_card(Hash::repeat_byte(0x01), 1).unwrap_err().to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@ use sp_consensus::SelectChain;
|
||||
fn calling_function_with_strat(strat: ExecutionStrategy) {
|
||||
let client = TestClientBuilder::new().set_execution_strategy(strat).build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
|
||||
assert_eq!(runtime_api.benchmark_add_one(&block_id, &1).unwrap(), 2);
|
||||
assert_eq!(runtime_api.benchmark_add_one(best_hash, &1).unwrap(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -57,9 +57,9 @@ fn calling_native_runtime_signature_changed_function() {
|
||||
.set_execution_strategy(ExecutionStrategy::NativeWhenPossible)
|
||||
.build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
|
||||
assert_eq!(runtime_api.function_signature_changed(&block_id).unwrap(), 1);
|
||||
assert_eq!(runtime_api.function_signature_changed(best_hash).unwrap(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -68,10 +68,10 @@ fn calling_wasm_runtime_signature_changed_old_function() {
|
||||
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
|
||||
.build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
|
||||
#[allow(deprecated)]
|
||||
let res = runtime_api.function_signature_changed_before_version_2(&block_id).unwrap();
|
||||
let res = runtime_api.function_signature_changed_before_version_2(best_hash).unwrap();
|
||||
assert_eq!(&res, &[1, 2]);
|
||||
}
|
||||
|
||||
@@ -79,16 +79,16 @@ fn calling_wasm_runtime_signature_changed_old_function() {
|
||||
fn calling_with_both_strategy_and_fail_on_wasm_should_return_error() {
|
||||
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::Both).build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
assert!(runtime_api.fail_on_wasm(&block_id).is_err());
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
assert!(runtime_api.fail_on_wasm(best_hash).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn calling_with_both_strategy_and_fail_on_native_should_work() {
|
||||
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::Both).build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
assert_eq!(runtime_api.fail_on_native(&block_id).unwrap(), 1);
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
assert_eq!(runtime_api.fail_on_native(best_hash).unwrap(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -97,8 +97,8 @@ fn calling_with_native_else_wasm_and_fail_on_wasm_should_work() {
|
||||
.set_execution_strategy(ExecutionStrategy::NativeElseWasm)
|
||||
.build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
assert_eq!(runtime_api.fail_on_wasm(&block_id).unwrap(), 1);
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
assert_eq!(runtime_api.fail_on_wasm(best_hash).unwrap(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -107,8 +107,8 @@ fn calling_with_native_else_wasm_and_fail_on_native_should_work() {
|
||||
.set_execution_strategy(ExecutionStrategy::NativeElseWasm)
|
||||
.build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
assert_eq!(runtime_api.fail_on_native(&block_id).unwrap(), 1);
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
assert_eq!(runtime_api.fail_on_native(best_hash).unwrap(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -117,18 +117,18 @@ fn use_trie_function() {
|
||||
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
|
||||
.build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
assert_eq!(runtime_api.use_trie(&block_id).unwrap(), 2);
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
assert_eq!(runtime_api.use_trie(best_hash).unwrap(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn initialize_block_works() {
|
||||
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::Both).build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
runtime_api
|
||||
.initialize_block(
|
||||
&block_id,
|
||||
best_hash,
|
||||
&Header::new(
|
||||
1,
|
||||
Default::default(),
|
||||
@@ -138,7 +138,7 @@ fn initialize_block_works() {
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(runtime_api.get_block_number(&block_id).unwrap(), 1);
|
||||
assert_eq!(runtime_api.get_block_number(best_hash).unwrap(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -205,10 +205,10 @@ fn call_runtime_api_with_multiple_arguments() {
|
||||
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::Both).build();
|
||||
|
||||
let data = vec![1, 2, 4, 5, 6, 7, 8, 8, 10, 12];
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
client
|
||||
.runtime_api()
|
||||
.test_multiple_arguments(&block_id, data.clone(), data.clone(), data.len() as u32)
|
||||
.test_multiple_arguments(best_hash, data.clone(), data.clone(), data.len() as u32)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -225,8 +225,9 @@ fn disable_logging_works() {
|
||||
|
||||
let client = builder.build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(0);
|
||||
runtime_api.do_trace_log(&block_id).expect("Logging should not fail");
|
||||
runtime_api
|
||||
.do_trace_log(client.chain_info().genesis_hash)
|
||||
.expect("Logging should not fail");
|
||||
log::error!("Logging from native works");
|
||||
} else {
|
||||
let executable = std::env::current_exe().unwrap();
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ struct MockApi;
|
||||
sp_api::mock_impl_runtime_apis! {
|
||||
impl Api<Block> for MockApi {
|
||||
#[advanced]
|
||||
fn test(&self, _: BlockId<Block>) -> Result<(), ApiError> {
|
||||
fn test(&self, _: &Hash) -> Result<(), ApiError> {
|
||||
Ok(().into())
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
error: `BlockId` needs to be taken by reference and not by value!
|
||||
--> tests/ui/mock_advanced_block_id_by_value.rs:12:1
|
||||
error: `Hash` needs to be taken by value and not by reference!
|
||||
--> tests/ui/mock_advanced_hash_by_reference.rs:12:1
|
||||
|
|
||||
12 | / sp_api::mock_impl_runtime_apis! {
|
||||
13 | | impl Api<Block> for MockApi {
|
||||
14 | | #[advanced]
|
||||
15 | | fn test(&self, _: BlockId<Block>) -> Result<(), ApiError> {
|
||||
15 | | fn test(&self, _: &Hash) -> Result<(), ApiError> {
|
||||
... |
|
||||
18 | | }
|
||||
19 | | }
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
error: If using the `advanced` attribute, it is required that the function takes at least one argument, the `BlockId`.
|
||||
--> tests/ui/mock_advanced_missing_blockid.rs:15:3
|
||||
error: If using the `advanced` attribute, it is required that the function takes at least one argument, the `Hash`.
|
||||
--> tests/ui/mock_advanced_missing_hash.rs:15:3
|
||||
|
|
||||
15 | fn test(&self) -> Result<(), ApiError> {
|
||||
| ^^
|
||||
@@ -20,7 +20,6 @@ use sp_api::ProvideRuntimeApi;
|
||||
use sp_application_crypto::ecdsa::{AppPair, AppPublic};
|
||||
use sp_core::{crypto::Pair, testing::ECDSA};
|
||||
use sp_keystore::{testing::KeyStore, SyncCryptoStore};
|
||||
use sp_runtime::generic::BlockId;
|
||||
use std::sync::Arc;
|
||||
use substrate_test_runtime_client::{
|
||||
runtime::TestAPI, DefaultTestClientBuilderExt, TestClientBuilder, TestClientBuilderExt,
|
||||
@@ -32,7 +31,7 @@ fn ecdsa_works_in_runtime() {
|
||||
let test_client = TestClientBuilder::new().set_keystore(keystore.clone()).build();
|
||||
let (signature, public) = test_client
|
||||
.runtime_api()
|
||||
.test_ecdsa_crypto(&BlockId::Number(0))
|
||||
.test_ecdsa_crypto(test_client.chain_info().genesis_hash)
|
||||
.expect("Tests `ecdsa` crypto.");
|
||||
|
||||
let supported_keys = SyncCryptoStore::keys(&*keystore, ECDSA).unwrap();
|
||||
|
||||
@@ -21,7 +21,6 @@ use sp_api::ProvideRuntimeApi;
|
||||
use sp_application_crypto::ed25519::{AppPair, AppPublic};
|
||||
use sp_core::{crypto::Pair, testing::ED25519};
|
||||
use sp_keystore::{testing::KeyStore, SyncCryptoStore};
|
||||
use sp_runtime::generic::BlockId;
|
||||
use std::sync::Arc;
|
||||
use substrate_test_runtime_client::{
|
||||
runtime::TestAPI, DefaultTestClientBuilderExt, TestClientBuilder, TestClientBuilderExt,
|
||||
@@ -33,7 +32,7 @@ fn ed25519_works_in_runtime() {
|
||||
let test_client = TestClientBuilder::new().set_keystore(keystore.clone()).build();
|
||||
let (signature, public) = test_client
|
||||
.runtime_api()
|
||||
.test_ed25519_crypto(&BlockId::Number(0))
|
||||
.test_ed25519_crypto(test_client.chain_info().genesis_hash)
|
||||
.expect("Tests `ed25519` crypto.");
|
||||
|
||||
let supported_keys = SyncCryptoStore::keys(&*keystore, ED25519).unwrap();
|
||||
|
||||
@@ -21,7 +21,6 @@ use sp_api::ProvideRuntimeApi;
|
||||
use sp_application_crypto::sr25519::{AppPair, AppPublic};
|
||||
use sp_core::{crypto::Pair, testing::SR25519};
|
||||
use sp_keystore::{testing::KeyStore, SyncCryptoStore};
|
||||
use sp_runtime::generic::BlockId;
|
||||
use std::sync::Arc;
|
||||
use substrate_test_runtime_client::{
|
||||
runtime::TestAPI, DefaultTestClientBuilderExt, TestClientBuilder, TestClientBuilderExt,
|
||||
@@ -33,7 +32,7 @@ fn sr25519_works_in_runtime() {
|
||||
let test_client = TestClientBuilder::new().set_keystore(keystore.clone()).build();
|
||||
let (signature, public) = test_client
|
||||
.runtime_api()
|
||||
.test_sr25519_crypto(&BlockId::Number(0))
|
||||
.test_sr25519_crypto(test_client.chain_info().genesis_hash)
|
||||
.expect("Tests `sr25519` crypto.");
|
||||
|
||||
let supported_keys = SyncCryptoStore::keys(&*keystore, SR25519).unwrap();
|
||||
|
||||
@@ -145,7 +145,6 @@ mod mmr_root_provider {
|
||||
use crate::{known_payloads, payload::PayloadProvider, Payload};
|
||||
use sp_api::{NumberFor, ProvideRuntimeApi};
|
||||
use sp_mmr_primitives::MmrApi;
|
||||
use sp_runtime::generic::BlockId;
|
||||
use sp_std::{marker::PhantomData, sync::Arc};
|
||||
|
||||
/// A [`crate::Payload`] provider where payload is Merkle Mountain Range root hash.
|
||||
@@ -170,11 +169,7 @@ mod mmr_root_provider {
|
||||
/// Simple wrapper that gets MMR root from header digests or from client state.
|
||||
fn mmr_root_from_digest_or_runtime(&self, header: &B::Header) -> Option<MmrRootHash> {
|
||||
find_mmr_root_digest::<B>(header).or_else(|| {
|
||||
self.runtime
|
||||
.runtime_api()
|
||||
.mmr_root(&BlockId::hash(header.hash()))
|
||||
.ok()
|
||||
.and_then(|r| r.ok())
|
||||
self.runtime.runtime_api().mmr_root(header.hash()).ok().and_then(|r| r.ok())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ impl log::Log for RuntimeLogger {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use sp_api::{BlockId, ProvideRuntimeApi};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use std::{env, str::FromStr};
|
||||
use substrate_test_runtime_client::{
|
||||
runtime::TestAPI, DefaultTestClientBuilderExt, ExecutionStrategy, TestClientBuilder,
|
||||
@@ -82,8 +82,9 @@ mod tests {
|
||||
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
|
||||
.build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(0);
|
||||
runtime_api.do_trace_log(&block_id).expect("Logging should not fail");
|
||||
runtime_api
|
||||
.do_trace_log(client.chain_info().genesis_hash)
|
||||
.expect("Logging should not fail");
|
||||
} else {
|
||||
for (level, should_print) in &[("trace", true), ("info", false)] {
|
||||
let executable = std::env::current_exe().unwrap();
|
||||
|
||||
@@ -24,7 +24,7 @@ use codec::{Decode, Encode};
|
||||
#[cfg(feature = "std")]
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
#[cfg(feature = "std")]
|
||||
use sp_runtime::{generic::BlockId, traits::Block as BlockT};
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
|
||||
use sp_core::{crypto::KeyTypeId, RuntimeDebug};
|
||||
use sp_staking::SessionIndex;
|
||||
@@ -125,7 +125,7 @@ where
|
||||
let runtime_api = client.runtime_api();
|
||||
|
||||
for seed in seeds {
|
||||
runtime_api.generate_session_keys(&BlockId::Hash(at), Some(seed.as_bytes().to_vec()))?;
|
||||
runtime_api.generate_session_keys(at, Some(seed.as_bytes().to_vec()))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -1353,7 +1353,6 @@ mod tests {
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sp_consensus::BlockOrigin;
|
||||
use sp_core::storage::well_known_keys::HEAP_PAGES;
|
||||
use sp_runtime::generic::BlockId;
|
||||
use sp_state_machine::ExecutionStrategy;
|
||||
use substrate_test_runtime_client::{
|
||||
prelude::*, runtime::TestAPI, DefaultTestClientBuilderExt, TestClientBuilder,
|
||||
@@ -1368,27 +1367,27 @@ mod tests {
|
||||
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
|
||||
.set_heap_pages(8)
|
||||
.build();
|
||||
let block_id = BlockId::Hash(client.chain_info().best_hash);
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
|
||||
// Try to allocate 1024k of memory on heap. This is going to fail since it is twice larger
|
||||
// than the heap.
|
||||
let ret = client.runtime_api().vec_with_capacity(&block_id, 1048576);
|
||||
let ret = client.runtime_api().vec_with_capacity(best_hash, 1048576);
|
||||
assert!(ret.is_err());
|
||||
|
||||
// Create a block that sets the `:heap_pages` to 32 pages of memory which corresponds to
|
||||
// ~2048k of heap memory.
|
||||
let (new_block_id, block) = {
|
||||
let (new_at_hash, block) = {
|
||||
let mut builder = client.new_block(Default::default()).unwrap();
|
||||
builder.push_storage_change(HEAP_PAGES.to_vec(), Some(32u64.encode())).unwrap();
|
||||
let block = builder.build().unwrap().block;
|
||||
let hash = block.header.hash();
|
||||
(BlockId::Hash(hash), block)
|
||||
(hash, block)
|
||||
};
|
||||
|
||||
futures::executor::block_on(client.import(BlockOrigin::Own, block)).unwrap();
|
||||
|
||||
// Allocation of 1024k while having ~2048k should succeed.
|
||||
let ret = client.runtime_api().vec_with_capacity(&new_block_id, 1048576);
|
||||
let ret = client.runtime_api().vec_with_capacity(new_at_hash, 1048576);
|
||||
assert!(ret.is_ok());
|
||||
}
|
||||
|
||||
@@ -1397,9 +1396,9 @@ mod tests {
|
||||
let client =
|
||||
TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::Both).build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Hash(client.chain_info().best_hash);
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
|
||||
runtime_api.test_storage(&block_id).unwrap();
|
||||
runtime_api.test_storage(best_hash).unwrap();
|
||||
}
|
||||
|
||||
fn witness_backend() -> (sp_trie::MemoryDB<crate::Hashing>, crate::Hash) {
|
||||
@@ -1424,8 +1423,8 @@ mod tests {
|
||||
let client =
|
||||
TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::Both).build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Hash(client.chain_info().best_hash);
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
|
||||
runtime_api.test_witness(&block_id, proof, root).unwrap();
|
||||
runtime_api.test_witness(best_hash, proof, root).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,13 +92,12 @@ where
|
||||
|
||||
for i in self.params.from..=self.params.to {
|
||||
let block_num = BlockId::Number(i.into());
|
||||
let parent_num = BlockId::Number(((i - 1) as u32).into());
|
||||
let consumed = self.consumed_weight(&block_num)?;
|
||||
let hash = self.client.expect_block_hash_from_id(&block_num)?;
|
||||
let consumed = self.consumed_weight(hash)?;
|
||||
|
||||
let block = self.client.block(hash)?.ok_or(format!("Block {} not found", block_num))?;
|
||||
let block = self.unsealed(block.block);
|
||||
let took = self.measure_block(&block, &parent_num)?;
|
||||
let took = self.measure_block(&block, *block.header().parent_hash())?;
|
||||
|
||||
self.log_weight(i, block.extrinsics().len(), consumed, took);
|
||||
}
|
||||
@@ -107,7 +106,7 @@ where
|
||||
}
|
||||
|
||||
/// Return the average *execution* aka. *import* time of the block.
|
||||
fn measure_block(&self, block: &Block, parent_num: &BlockId<Block>) -> Result<NanoSeconds> {
|
||||
fn measure_block(&self, block: &Block, parent_hash: Block::Hash) -> Result<NanoSeconds> {
|
||||
let mut record = Vec::<NanoSeconds>::default();
|
||||
// Interesting part here:
|
||||
// Execute the block multiple times and collect stats about its execution time.
|
||||
@@ -117,7 +116,7 @@ where
|
||||
let start = Instant::now();
|
||||
|
||||
runtime_api
|
||||
.execute_block(&parent_num, block)
|
||||
.execute_block(parent_hash, block)
|
||||
.map_err(|e| Error::Client(RuntimeApiError(e)))?;
|
||||
|
||||
record.push(start.elapsed().as_nanos() as NanoSeconds);
|
||||
@@ -131,7 +130,7 @@ where
|
||||
///
|
||||
/// This is the post-dispatch corrected weight and is only available
|
||||
/// after executing the block.
|
||||
fn consumed_weight(&self, block: &BlockId<Block>) -> Result<NanoSeconds> {
|
||||
fn consumed_weight(&self, block_hash: Block::Hash) -> Result<NanoSeconds> {
|
||||
// Hard-coded key for System::BlockWeight. It could also be passed in as argument
|
||||
// for the benchmark, but I think this should work as well.
|
||||
let hash = array_bytes::hex2bytes(
|
||||
@@ -139,11 +138,10 @@ where
|
||||
)?;
|
||||
let key = StorageKey(hash);
|
||||
|
||||
let block_hash = self.client.expect_block_hash_from_id(block)?;
|
||||
let mut raw_weight = &self
|
||||
.client
|
||||
.storage(block_hash, &key)?
|
||||
.ok_or(format!("Could not find System::BlockWeight for block: {}", block))?
|
||||
.ok_or(format!("Could not find System::BlockWeight for block: {}", block_hash))?
|
||||
.0[..];
|
||||
|
||||
let weight = ConsumedWeight::decode_all(&mut raw_weight)?;
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
use sc_block_builder::{BlockBuilderApi, BlockBuilderProvider};
|
||||
use sc_cli::{Error, Result};
|
||||
use sc_client_api::Backend as ClientBackend;
|
||||
use sp_api::{ApiExt, BlockId, Core, ProvideRuntimeApi};
|
||||
use sp_api::{ApiExt, Core, ProvideRuntimeApi};
|
||||
use sp_blockchain::{
|
||||
ApplyExtrinsicFailed::Validity,
|
||||
Error::{ApplyExtrinsicFailed, RuntimeApiError},
|
||||
};
|
||||
use sp_runtime::{
|
||||
traits::{Block as BlockT, Zero},
|
||||
traits::Block as BlockT,
|
||||
transaction_validity::{InvalidTransaction, TransactionValidityError},
|
||||
Digest, DigestItem, OpaqueExtrinsic,
|
||||
};
|
||||
@@ -73,7 +73,9 @@ impl<Block, BA, C> Benchmark<Block, BA, C>
|
||||
where
|
||||
Block: BlockT<Extrinsic = OpaqueExtrinsic>,
|
||||
BA: ClientBackend<Block>,
|
||||
C: BlockBuilderProvider<BA, Block, C> + ProvideRuntimeApi<Block>,
|
||||
C: BlockBuilderProvider<BA, Block, C>
|
||||
+ ProvideRuntimeApi<Block>
|
||||
+ sp_blockchain::HeaderBackend<Block>,
|
||||
C::Api: ApiExt<Block, StateBackend = BA::State> + BlockBuilderApi<Block>,
|
||||
{
|
||||
/// Create a new [`Self`] from the arguments.
|
||||
@@ -167,13 +169,13 @@ where
|
||||
/// Measures the time that it take to execute a block or an extrinsic.
|
||||
fn measure_block(&self, block: &Block) -> Result<BenchRecord> {
|
||||
let mut record = BenchRecord::new();
|
||||
let genesis = BlockId::Number(Zero::zero());
|
||||
let genesis = self.client.info().genesis_hash;
|
||||
|
||||
info!("Running {} warmups...", self.params.warmup);
|
||||
for _ in 0..self.params.warmup {
|
||||
self.client
|
||||
.runtime_api()
|
||||
.execute_block(&genesis, block.clone())
|
||||
.execute_block(genesis, block.clone())
|
||||
.map_err(|e| Error::Client(RuntimeApiError(e)))?;
|
||||
}
|
||||
|
||||
@@ -186,7 +188,7 @@ where
|
||||
let start = Instant::now();
|
||||
|
||||
runtime_api
|
||||
.execute_block(&genesis, block)
|
||||
.execute_block(genesis, block)
|
||||
.map_err(|e| Error::Client(RuntimeApiError(e)))?;
|
||||
|
||||
let elapsed = start.elapsed().as_nanos();
|
||||
|
||||
@@ -94,7 +94,9 @@ impl ExtrinsicCmd {
|
||||
where
|
||||
Block: BlockT<Extrinsic = OpaqueExtrinsic>,
|
||||
BA: ClientBackend<Block>,
|
||||
C: BlockBuilderProvider<BA, Block, C> + ProvideRuntimeApi<Block>,
|
||||
C: BlockBuilderProvider<BA, Block, C>
|
||||
+ ProvideRuntimeApi<Block>
|
||||
+ sp_blockchain::HeaderBackend<Block>,
|
||||
C::Api: ApiExt<Block, StateBackend = BA::State> + BlockBuilderApi<Block>,
|
||||
{
|
||||
// Short circuit if --list was specified.
|
||||
|
||||
@@ -108,7 +108,9 @@ impl OverheadCmd {
|
||||
where
|
||||
Block: BlockT<Extrinsic = OpaqueExtrinsic>,
|
||||
BA: ClientBackend<Block>,
|
||||
C: BlockBuilderProvider<BA, Block, C> + ProvideRuntimeApi<Block>,
|
||||
C: BlockBuilderProvider<BA, Block, C>
|
||||
+ ProvideRuntimeApi<Block>
|
||||
+ sp_blockchain::HeaderBackend<Block>,
|
||||
C::Api: ApiExt<Block, StateBackend = BA::State> + BlockBuilderApi<Block>,
|
||||
{
|
||||
if ext_builder.pallet() != "system" || ext_builder.extrinsic() != "remark" {
|
||||
|
||||
@@ -32,7 +32,7 @@ use sp_api::ApiExt;
|
||||
use sp_block_builder::BlockBuilder;
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use sp_core::{hexdisplay::HexDisplay, Bytes};
|
||||
use sp_runtime::{generic::BlockId, legacy, traits};
|
||||
use sp_runtime::{legacy, traits};
|
||||
|
||||
pub use frame_system_rpc_runtime_api::AccountNonceApi;
|
||||
|
||||
@@ -101,9 +101,8 @@ where
|
||||
async fn nonce(&self, account: AccountId) -> RpcResult<Index> {
|
||||
let api = self.client.runtime_api();
|
||||
let best = self.client.info().best_hash;
|
||||
let at = BlockId::hash(best);
|
||||
|
||||
let nonce = api.account_nonce(&at, account.clone()).map_err(|e| {
|
||||
let nonce = api.account_nonce(best, account.clone()).map_err(|e| {
|
||||
CallError::Custom(ErrorObject::owned(
|
||||
Error::RuntimeError.into(),
|
||||
"Unable to query nonce.",
|
||||
@@ -120,9 +119,9 @@ where
|
||||
) -> RpcResult<Bytes> {
|
||||
self.deny_unsafe.check_if_safe()?;
|
||||
let api = self.client.runtime_api();
|
||||
let at = BlockId::<Block>::hash(at.unwrap_or_else(||
|
||||
let best_hash = at.unwrap_or_else(||
|
||||
// If the block hash is not supplied assume the best block.
|
||||
self.client.info().best_hash));
|
||||
self.client.info().best_hash);
|
||||
|
||||
let uxt: <Block as traits::Block>::Extrinsic =
|
||||
Decode::decode(&mut &*extrinsic).map_err(|e| {
|
||||
@@ -134,7 +133,7 @@ where
|
||||
})?;
|
||||
|
||||
let api_version = api
|
||||
.api_version::<dyn BlockBuilder<Block>>(&at)
|
||||
.api_version::<dyn BlockBuilder<Block>>(best_hash)
|
||||
.map_err(|e| {
|
||||
CallError::Custom(ErrorObject::owned(
|
||||
Error::RuntimeError.into(),
|
||||
@@ -146,13 +145,13 @@ where
|
||||
CallError::Custom(ErrorObject::owned(
|
||||
Error::RuntimeError.into(),
|
||||
"Unable to dry run extrinsic.",
|
||||
Some(format!("Could not find `BlockBuilder` api for block `{:?}`.", at)),
|
||||
Some(format!("Could not find `BlockBuilder` api for block `{:?}`.", best_hash)),
|
||||
))
|
||||
})?;
|
||||
|
||||
let result = if api_version < 6 {
|
||||
#[allow(deprecated)]
|
||||
api.apply_extrinsic_before_version_6(&at, uxt)
|
||||
api.apply_extrinsic_before_version_6(best_hash, uxt)
|
||||
.map(legacy::byte_sized_error::convert_to_latest)
|
||||
.map_err(|e| {
|
||||
CallError::Custom(ErrorObject::owned(
|
||||
@@ -162,7 +161,7 @@ where
|
||||
))
|
||||
})?
|
||||
} else {
|
||||
api.apply_extrinsic(&at, uxt).map_err(|e| {
|
||||
api.apply_extrinsic(best_hash, uxt).map_err(|e| {
|
||||
CallError::Custom(ErrorObject::owned(
|
||||
Error::RuntimeError.into(),
|
||||
"Unable to dry run extrinsic.",
|
||||
@@ -220,6 +219,7 @@ mod tests {
|
||||
use jsonrpsee::{core::Error as JsonRpseeError, types::error::CallError};
|
||||
use sc_transaction_pool::BasicPool;
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
transaction_validity::{InvalidTransaction, TransactionValidityError},
|
||||
ApplyExtrinsicResult,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user