RPC: expose chain spec properties (#1104)

* Add properties to chain spec

* Read properties as serde_json::Value

* Use a serde json::map::Map directly for properties

* Add type alias for json Map

* Update chain_spec.rs
This commit is contained in:
Andrew Jones
2018-11-12 18:58:44 +00:00
committed by Gav Wood
parent 57b2896332
commit db075b57f0
8 changed files with 42 additions and 4 deletions
+1
View File
@@ -3325,6 +3325,7 @@ dependencies = [
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 0.1.0",
"sr-version 0.1.0",
"substrate-client 0.1.0",
+1
View File
@@ -11,6 +11,7 @@ jsonrpc-pubsub = { git="https://github.com/paritytech/jsonrpc.git" }
log = "0.4"
parking_lot = "0.4"
parity-codec = "2.1"
serde_json = "1.0"
substrate-client = { path = "../client" }
substrate-executor = { path = "../executor" }
substrate-transaction-pool = { path = "../transaction-pool" }
+4
View File
@@ -37,5 +37,9 @@ build_rpc_trait! {
/// Get the chain's type. Given as a string identifier.
#[rpc(name = "system_chain")]
fn system_chain(&self) -> Result<String>;
/// Get a custom set of properties as a JSON object, defined in the chain spec.
#[rpc(name = "system_properties")]
fn system_properties(&self) -> Result<serde_json::map::Map<String, serde_json::Value>>;
}
}
+11
View File
@@ -27,6 +27,9 @@ impl SystemApi for () {
fn system_chain(&self) -> Result<String> {
Ok("testchain".into())
}
fn system_properties(&self) -> Result<serde_json::map::Map<String, serde_json::Value>> {
Ok(serde_json::map::Map::new())
}
}
#[test]
@@ -52,3 +55,11 @@ fn system_chain_works() {
"testchain".to_owned()
);
}
#[test]
fn system_properties_works() {
assert_eq!(
SystemApi::system_properties(&()).unwrap(),
serde_json::map::Map::new()
);
}
+11
View File
@@ -88,8 +88,12 @@ struct ChainSpecFile {
pub telemetry_url: Option<String>,
pub protocol_id: Option<String>,
pub consensus_engine: Option<String>,
pub properties: Option<Properties>,
}
/// Arbitrary properties defined in chain spec as a JSON object
pub type Properties = json::map::Map<String, json::Value>;
/// A configuration of a chain. Can be used to build a genesis block.
pub struct ChainSpec<G: RuntimeGenesis> {
spec: ChainSpecFile,
@@ -130,6 +134,11 @@ impl<G: RuntimeGenesis> ChainSpec<G> {
self.spec.consensus_engine.as_ref().map(String::as_str)
}
pub fn properties(&self) -> Properties {
// Return an empty JSON object if 'properties' not defined in config
self.spec.properties.as_ref().unwrap_or(&json::map::Map::new()).clone()
}
/// Parse json content into a `ChainSpec`
pub fn from_embedded(json: &'static [u8]) -> Result<Self, String> {
let spec = json::from_slice(json).map_err(|e| format!("Error parsing spec file: {}", e))?;
@@ -158,6 +167,7 @@ impl<G: RuntimeGenesis> ChainSpec<G> {
telemetry_url: Option<&str>,
protocol_id: Option<&str>,
consensus_engine: Option<&str>,
properties: Option<Properties>,
) -> Self
{
let spec = ChainSpecFile {
@@ -167,6 +177,7 @@ impl<G: RuntimeGenesis> ChainSpec<G> {
telemetry_url: telemetry_url.map(str::to_owned),
protocol_id: protocol_id.map(str::to_owned),
consensus_engine: consensus_engine.map(str::to_owned),
properties,
};
ChainSpec {
spec,
+7 -1
View File
@@ -78,7 +78,7 @@ use codec::{Encode, Decode};
pub use self::error::{ErrorKind, Error};
pub use config::{Configuration, Roles, PruningMode};
pub use chain_spec::ChainSpec;
pub use chain_spec::{ChainSpec, Properties};
pub use transaction_pool::txpool::{self, Pool as TransactionPool, Options as TransactionPoolOptions, ChainApi, IntoPoolError};
pub use client::ExecutionStrategy;
@@ -235,6 +235,7 @@ impl<Components> Service<Components>
// RPC
let rpc_config = RpcConfig {
chain_name: config.chain_spec.name().to_string(),
properties: config.chain_spec.properties().clone(),
impl_name: config.impl_name,
impl_version: config.impl_version,
};
@@ -378,6 +379,7 @@ fn maybe_start_server<T, F>(address: Option<SocketAddr>, start: F) -> Result<Opt
#[derive(Clone)]
struct RpcConfig {
chain_name: String,
properties: Properties,
impl_name: &'static str,
impl_version: &'static str,
}
@@ -394,6 +396,10 @@ impl substrate_rpc::system::SystemApi for RpcConfig {
fn system_chain(&self) -> substrate_rpc::system::error::Result<String> {
Ok(self.chain_name.clone())
}
fn system_properties(&self) -> substrate_rpc::system::error::Result<Properties> {
Ok(self.properties.clone())
}
}
/// Transaction pool adapter.
+3
View File
@@ -1,6 +1,9 @@
{
"name": "BBQ Birch",
"id": "bbq-birch",
"properties": {
"tokenSymbol": "BBQ"
},
"telemetryUrl": "wss://telemetry.polkadot.io/submit/",
"protocolId": null,
"bootNodes": [
+4 -3
View File
@@ -140,6 +140,7 @@ pub fn staging_testnet_config() -> ChainSpec {
Some(STAGING_TELEMETRY_URL.into()),
None,
None,
None,
)
}
@@ -240,7 +241,7 @@ fn development_config_genesis() -> GenesisConfig {
/// Development config (single validator Alice)
pub fn development_config() -> ChainSpec {
ChainSpec::from_genesis("Development", "development", development_config_genesis, vec![], None, None, None)
ChainSpec::from_genesis("Development", "development", development_config_genesis, vec![], None, None, None, None)
}
fn local_testnet_genesis() -> GenesisConfig {
@@ -254,7 +255,7 @@ fn local_testnet_genesis() -> GenesisConfig {
/// Local testnet config (multivalidator Alice + Bob)
pub fn local_testnet_config() -> ChainSpec {
ChainSpec::from_genesis("Local Testnet", "local_testnet", local_testnet_genesis, vec![], None, None, None)
ChainSpec::from_genesis("Local Testnet", "local_testnet", local_testnet_genesis, vec![], None, None, None, None)
}
#[cfg(test)]
@@ -271,7 +272,7 @@ mod tests {
/// Local testnet config (multivalidator Alice + Bob)
pub fn integration_test_config() -> ChainSpec {
ChainSpec::from_genesis("Integration Test", "test", local_testnet_genesis_instant, vec![], None, None, None)
ChainSpec::from_genesis("Integration Test", "test", local_testnet_genesis_instant, vec![], None, None, None, None)
}
#[test]