rpc: add rpc v2 chainSpec to polkadot (#2859)

The [chainSpec RPC API from the v2
spec](https://paritytech.github.io/json-rpc-interface-spec/api/chainSpec.html)
was only added to substrate-node and should be added to polkadot as well

/cc @lexnv
This commit is contained in:
Niklas Adolfsson
2024-01-08 13:35:12 +01:00
committed by GitHub
parent 82327494bc
commit a97a6f2095
16 changed files with 45 additions and 23 deletions
Generated
+1
View File
@@ -13200,6 +13200,7 @@ dependencies = [
"sc-consensus-grandpa",
"sc-consensus-grandpa-rpc",
"sc-rpc",
"sc-rpc-spec-v2",
"sc-sync-state-rpc",
"sc-transaction-pool-api",
"sp-api",
@@ -32,14 +32,21 @@
//!
//! ## Comparative Table
//!
//! | Aspect | Runtime | Smart Contracts |
//! | Aspect | Runtime
//! | Smart Contracts |
//! |-----------------------|-------------------------------------------------------------------------|----------------------------------------------------------------------|
//! | **Design Philosophy** | Core logic of a blockchain, allowing broad and deep customization. | Designed for DApps deployed on the blockchain runtime.|
//! | **Development Complexity** | Requires in-depth knowledge of Rust and Substrate. Suitable for complex blockchain architectures. | Easier to develop with knowledge of Smart Contract languages like Solidity or [ink!](https://use.ink/). |
//! | **Upgradeability and Flexibility** | Offers comprehensive upgradeability with migration logic and on-chain governance, allowing modifications to the entire blockchain logic without hard forks. | Less flexible in upgrade migrations but offers more straightforward deployment and iteration. |
//! | **Performance and Efficiency** | More efficient, optimized for specific needs of the blockchain. | Can be less efficient due to its generic nature (e.g. the overhead of a virtual machine). |
//! | **Security Considerations** | Security flaws can affect the entire blockchain. | Security risks usually localized to the individual contract. |
//! | **Weighing and Metering** | Operations can be weighed, allowing for precise benchmarking. | Execution is metered, allowing for measurement of resource consumption. |
//! | **Design Philosophy** | Core logic of a blockchain, allowing broad and deep customization.
//! | Designed for DApps deployed on the blockchain runtime.| | **Development Complexity** | Requires in-depth knowledge of Rust and Substrate. Suitable for complex blockchain architectures. | Easier to develop with knowledge of Smart Contract languages like Solidity or [ink!](https://use.ink/). |
//! | **Upgradeability and Flexibility** | Offers comprehensive upgradeability with migration logic
//! and on-chain governance, allowing modifications to the entire blockchain logic without hard
//! forks. | Less flexible in upgrade migrations but offers more straightforward deployment and
//! iteration. | | **Performance and Efficiency** | More efficient, optimized for specific needs of
//! the blockchain. | Can be less efficient due to its generic nature (e.g. the overhead of a
//! virtual machine). | | **Security Considerations** | Security flaws can affect the entire
//! blockchain. | Security risks usually localized to the individual
//! contract. | | **Weighing and Metering** | Operations can be weighed, allowing for precise
//! benchmarking. | Execution is metered, allowing for measurement of resource
//! consumption. |
//!
//! We will now explore these differences in more detail.
//!
@@ -773,21 +773,21 @@ trait ValidationBackend {
if num_death_retries_left > 0 {
num_death_retries_left -= 1;
} else {
break;
break
},
Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::JobError(_))) =>
if num_job_error_retries_left > 0 {
num_job_error_retries_left -= 1;
} else {
break;
break
},
Err(ValidationError::Internal(_)) =>
if num_internal_retries_left > 0 {
num_internal_retries_left -= 1;
} else {
break;
break
},
Ok(_) | Err(ValidationError::Invalid(_) | ValidationError::Preparation(_)) => break,
@@ -726,7 +726,7 @@ fn candidate_validation_retry_on_error_helper(
ExecutorParams::default(),
exec_kind,
&Default::default(),
));
))
}
#[test]
+1
View File
@@ -21,6 +21,7 @@ sp-consensus = { path = "../../substrate/primitives/consensus/common" }
sp-consensus-babe = { path = "../../substrate/primitives/consensus/babe" }
sc-chain-spec = { path = "../../substrate/client/chain-spec" }
sc-rpc = { path = "../../substrate/client/rpc" }
sc-rpc-spec-v2 = { path = "../../substrate/client/rpc-spec-v2" }
sc-consensus-babe = { path = "../../substrate/client/consensus/babe" }
sc-consensus-babe-rpc = { path = "../../substrate/client/consensus/babe/rpc" }
sc-consensus-beefy = { path = "../../substrate/client/consensus/beefy" }
+6
View File
@@ -121,6 +121,7 @@ where
use sc_consensus_babe_rpc::{Babe, BabeApiServer};
use sc_consensus_beefy_rpc::{Beefy, BeefyApiServer};
use sc_consensus_grandpa_rpc::{Grandpa, GrandpaApiServer};
use sc_rpc_spec_v2::chain_spec::{ChainSpec, ChainSpecApiServer};
use sc_sync_state_rpc::{SyncState, SyncStateApiServer};
use substrate_state_trie_migration_rpc::{StateMigration, StateMigrationApiServer};
@@ -134,6 +135,11 @@ where
finality_provider,
} = grandpa;
let chain_name = chain_spec.name().to_string();
let genesis_hash = client.hash(0).ok().flatten().expect("Genesis block exists; qed");
let properties = chain_spec.properties();
io.merge(ChainSpec::new(chain_name, genesis_hash, properties).into_rpc())?;
io.merge(StateMigration::new(client.clone(), backend.clone(), deny_unsafe).into_rpc())?;
io.merge(System::new(client.clone(), pool.clone(), deny_unsafe).into_rpc())?;
io.merge(TransactionPayment::new(client.clone()).into_rpc())?;
@@ -53,5 +53,12 @@ where
// to call into the runtime.
// `module.merge(YourRpcTrait::into_rpc(YourRpcStruct::new(ReferenceToClient, ...)))?;`
// You probably want to enable the `rpc v2 chainSpec` API as well
//
// let chain_name = chain_spec.name().to_string();
// let genesis_hash = client.block_hash(0).ok().flatten().expect("Genesis block exists; qed");
// let properties = chain_spec.properties();
// module.merge(ChainSpec::new(chain_name, genesis_hash, properties).into_rpc())?;
Ok(module)
}
@@ -148,7 +148,7 @@ where
// The block is imported as part of some chain sync.
// The voter doesn't need to process it now.
// It will be detected and processed as part of the voter state init.
return Ok(inner_import_result);
return Ok(inner_import_result)
},
}
+1 -1
View File
@@ -398,7 +398,7 @@ where
header =
wait_for_parent_header(backend.blockchain(), header, HEADER_SYNC_DELAY).await?;
}
return Ok(state);
return Ok(state)
}
// No valid voter-state persisted, re-initialize from pallet genesis.
@@ -1037,7 +1037,7 @@ impl Notifications {
peerset_rejected,
incoming_index,
};
return self.report_reject(index).map_or((), |_| ());
return self.report_reject(index).map_or((), |_| ())
}
trace!(
+3 -3
View File
@@ -105,7 +105,7 @@ fn collect_entries(contracts_dir: &Path, out_dir: &Path) -> Vec<Entry> {
.filter_map(|file| {
let path = file.expect("file exists; qed").path();
if path.extension().map_or(true, |ext| ext != "rs") {
return None;
return None
}
let entry = Entry::new(path);
@@ -307,7 +307,7 @@ fn find_workspace_root(current_dir: &Path) -> Option<PathBuf> {
let cargo_toml_contents =
std::fs::read_to_string(current_dir.join("Cargo.toml")).ok()?;
if cargo_toml_contents.contains("[workspace]") {
return Some(current_dir);
return Some(current_dir)
}
}
@@ -325,7 +325,7 @@ fn main() -> Result<()> {
let entries = collect_entries(&contracts_dir, &out_dir);
if entries.is_empty() {
return Ok(());
return Ok(())
}
let tmp_dir = tempfile::tempdir()?;
@@ -31,7 +31,7 @@ pub fn expand_outer_task(
let mut task_paths = Vec::new();
for decl in pallet_decls {
if decl.find_part("Task").is_none() {
continue;
continue
}
let variant_name = &decl.name;
+1 -1
View File
@@ -828,7 +828,7 @@ fn last_runtime_upgrade_spec_version_usage() {
// a runtime upgrade in the pipeline of being applied, you should use the spec version
// of this upgrade.
if System::last_runtime_upgrade_spec_version() > 1337 {
return Weight::zero();
return Weight::zero()
}
// Do the migration.
+1 -1
View File
@@ -184,7 +184,7 @@ impl<'a> AddressUri<'a> {
Error::in_pass(initial_input, initial_input_len - input.len())
} else {
Error::in_phrase(initial_input, initial_input_len - input.len())
});
})
}
}
+2 -2
View File
@@ -434,7 +434,7 @@ impl<T: Sized + AsMut<[u8]> + AsRef<[u8]> + Public + Derive> Ss58Codec for T {
fn from_string(s: &str) -> Result<Self, PublicError> {
let cap = AddressUri::parse(s)?;
if cap.pass.is_some() {
return Err(PublicError::PasswordNotAllowed);
return Err(PublicError::PasswordNotAllowed)
}
let s = cap.phrase.unwrap_or(DEV_ADDRESS);
let addr = if let Some(stripped) = s.strip_prefix("0x") {
@@ -454,7 +454,7 @@ impl<T: Sized + AsMut<[u8]> + AsRef<[u8]> + Public + Derive> Ss58Codec for T {
fn from_string_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> {
let cap = AddressUri::parse(s)?;
if cap.pass.is_some() {
return Err(PublicError::PasswordNotAllowed);
return Err(PublicError::PasswordNotAllowed)
}
let (addr, v) = Self::from_ss58check_with_version(cap.phrase.unwrap_or(DEV_ADDRESS))?;
if cap.paths.is_empty() {
@@ -935,7 +935,7 @@ fn generate_rerun_if_changed_instructions(
while let Some(dependency) = dependencies.pop() {
// Ignore all dev dependencies
if dependency.kind == DependencyKind::Development {
continue;
continue
}
let path_or_git_dep =