Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RPC-Spec-V2] chainHead: use integer for block index and adjust RuntimeVersion JSON format #1666

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion substrate/client/rpc-spec-v2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ tokio = { version = "1.22.0", features = ["sync"] }
array-bytes = "6.1"
log = "0.4.17"
futures-util = { version = "0.3.19", default-features = false }

[dev-dependencies]
serde_json = "1.0"
tokio = { version = "1.22.0", features = ["macros"] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ where
let parent = match parent {
Some(parent) => parent,
// Nothing to compare against, always report.
None => return Some(RuntimeEvent::Valid(RuntimeVersionEvent { spec: block_rt })),
None => return Some(RuntimeEvent::Valid(RuntimeVersionEvent { spec: block_rt.into() })),
};

let parent_rt = match self.client.runtime_version_at(parent) {
Expand All @@ -168,7 +168,7 @@ where

// Report the runtime version change.
if block_rt != parent_rt {
Some(RuntimeEvent::Valid(RuntimeVersionEvent { spec: block_rt }))
Some(RuntimeEvent::Valid(RuntimeVersionEvent { spec: block_rt.into() }))
} else {
None
}
Expand Down
1 change: 0 additions & 1 deletion substrate/client/rpc-spec-v2/src/chain_head/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ impl From<Error> for ErrorObject<'static> {
Error::InvalidSubscriptionID => ErrorObject::owned(INVALID_SUB_ID, msg, None::<()>),
Error::InvalidContinue => ErrorObject::owned(INVALID_CONTINUE, msg, None::<()>),
}
.into()
}
}

Expand Down
54 changes: 46 additions & 8 deletions substrate/client/rpc-spec-v2/src/chain_head/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
use sp_api::ApiError;
use sp_version::RuntimeVersion;
use std::collections::BTreeMap;

/// The operation could not be processed due to an error.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
Expand All @@ -35,11 +36,47 @@ pub struct ErrorEvent {
/// This event is generated for:
/// - the first announced block by the follow subscription
/// - blocks that suffered a change in runtime compared with their parents
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct RuntimeVersionEvent {
/// The runtime version.
pub spec: RuntimeVersion,
pub spec: ChainHeadRuntimeVersion,
}

/// Simplified type clone of `sp_version::RuntimeVersion`. Used instead of
/// `sp_version::RuntimeVersion` to conform to RPC spec V2.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ChainHeadRuntimeVersion {
/// Identifies the different Substrate runtimes.
pub spec_name: String,
/// Name of the implementation of the spec.
pub impl_name: String,
/// Version of the runtime specification.
pub spec_version: u32,
/// Version of the implementation of the specification.
pub impl_version: u32,
/// Map of all supported API "features" and their versions.
pub apis: BTreeMap<String, u32>,
/// Transaction version.
pub transaction_version: u32,
}

impl From<RuntimeVersion> for ChainHeadRuntimeVersion {
fn from(val: RuntimeVersion) -> Self {
Self {
spec_name: val.spec_name.into(),
impl_name: val.impl_name.into(),
spec_version: val.spec_version,
impl_version: val.impl_version,
apis: val
.apis
.into_iter()
.map(|(api, version)| (sp_core::bytes::to_hex(api, false), *version))
.collect(),
transaction_version: val.transaction_version,
}
}
}

/// The runtime event generated if the `follow` subscription
Expand Down Expand Up @@ -380,7 +417,7 @@ mod tests {
..Default::default()
};

let runtime_event = RuntimeEvent::Valid(RuntimeVersionEvent { spec: runtime });
let runtime_event = RuntimeEvent::Valid(RuntimeVersionEvent { spec: runtime.into() });
let mut initialized = Initialized {
finalized_block_hash: "0x1".into(),
finalized_block_runtime: Some(runtime_event),
Expand All @@ -391,8 +428,8 @@ mod tests {
let ser = serde_json::to_string(&event).unwrap();
let exp = concat!(
r#"{"event":"initialized","finalizedBlockHash":"0x1","#,
r#""finalizedBlockRuntime":{"type":"valid","spec":{"specName":"ABC","implName":"Impl","authoringVersion":0,"#,
r#""specVersion":1,"implVersion":0,"apis":[],"transactionVersion":0,"stateVersion":0}}}"#,
r#""finalizedBlockRuntime":{"type":"valid","spec":{"specName":"ABC","implName":"Impl","#,
r#""specVersion":1,"implVersion":0,"apis":{},"transactionVersion":0}}}"#,
);
assert_eq!(ser, exp);

Expand Down Expand Up @@ -429,10 +466,11 @@ mod tests {
spec_name: "ABC".into(),
impl_name: "Impl".into(),
spec_version: 1,
apis: vec![([0, 0, 0, 0, 0, 0, 0, 0], 2), ([1, 0, 0, 0, 0, 0, 0, 0], 3)].into(),
..Default::default()
};

let runtime_event = RuntimeEvent::Valid(RuntimeVersionEvent { spec: runtime });
let runtime_event = RuntimeEvent::Valid(RuntimeVersionEvent { spec: runtime.into() });
let mut new_block = NewBlock {
block_hash: "0x1".into(),
parent_block_hash: "0x2".into(),
Expand All @@ -445,8 +483,8 @@ mod tests {
let ser = serde_json::to_string(&event).unwrap();
let exp = concat!(
r#"{"event":"newBlock","blockHash":"0x1","parentBlockHash":"0x2","#,
r#""newRuntime":{"type":"valid","spec":{"specName":"ABC","implName":"Impl","authoringVersion":0,"#,
r#""specVersion":1,"implVersion":0,"apis":[],"transactionVersion":0,"stateVersion":0}}}"#,
r#""newRuntime":{"type":"valid","spec":{"specName":"ABC","implName":"Impl","#,
r#""specVersion":1,"implVersion":0,"apis":{"0x0000000000000000":2,"0x0100000000000000":3},"transactionVersion":0}}}"#,
);
assert_eq!(ser, exp);

Expand Down
9 changes: 5 additions & 4 deletions substrate/client/rpc-spec-v2/src/chain_head/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,17 +234,17 @@ async fn follow_with_runtime() {
let event: FollowEvent<String> = get_next_event(&mut sub).await;

// it is basically json-encoded substrate_test_runtime_client::runtime::VERSION
let runtime_str = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\
let runtime_str = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":0,\
\"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",4],\
[\"0x37e397fc7c91f5e4\",2],[\"0xd2bc9897eed08f15\",3],[\"0x40fe3ad401f8959a\",6],\
[\"0xbc9d89904f5b923f\",1],[\"0xc6e9a76309f39b09\",2],[\"0xdd718d5cc53262d4\",1],\
[\"0xcbca25e39f142387\",2],[\"0xf78b278be53f454c\",2],[\"0xab3c0572291feb8b\",1],\
[\"0xed99c5acb25eedf5\",3],[\"0xfbc577b9d747efd6\",1]],\"transactionVersion\":1,\"stateVersion\":1}";
[\"0xed99c5acb25eedf5\",3],[\"0xfbc577b9d747efd6\",1]],\"transactionVersion\":1,\"stateVersion\":0}";

let runtime: RuntimeVersion = serde_json::from_str(runtime_str).unwrap();

let finalized_block_runtime =
Some(RuntimeEvent::Valid(RuntimeVersionEvent { spec: runtime.clone() }));
Some(RuntimeEvent::Valid(RuntimeVersionEvent { spec: runtime.clone().into() }));
// Runtime must always be reported with the first event.
let expected = FollowEvent::Initialized(Initialized {
finalized_block_hash: format!("{:?}", finalized_hash),
Expand Down Expand Up @@ -308,7 +308,8 @@ async fn follow_with_runtime() {
let best_hash = block.header.hash();
client.import(BlockOrigin::Own, block.clone()).await.unwrap();

let new_runtime = Some(RuntimeEvent::Valid(RuntimeVersionEvent { spec: runtime.clone() }));
let new_runtime =
Some(RuntimeEvent::Valid(RuntimeVersionEvent { spec: runtime.clone().into() }));
let event: FollowEvent<String> = get_next_event(&mut sub).await;
let expected = FollowEvent::NewBlock(NewBlock {
block_hash: format!("{:?}", best_hash),
Expand Down
24 changes: 3 additions & 21 deletions substrate/client/rpc-spec-v2/src/transaction/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ use serde::{Deserialize, Serialize};
#[serde(rename_all = "camelCase")]
pub struct TransactionBroadcasted {
/// The number of peers the transaction was broadcasted to.
#[serde(with = "as_string")]
pub num_peers: usize,
}

Expand All @@ -45,7 +44,6 @@ pub struct TransactionBlock<Hash> {
/// The hash of the block the transaction was included into.
pub hash: Hash,
/// The index (zero-based) of the transaction within the body of the block.
#[serde(with = "as_string")]
pub index: usize,
}

Expand Down Expand Up @@ -224,22 +222,6 @@ impl<Hash> From<TransactionEventIR<Hash>> for TransactionEvent<Hash> {
}
}

/// Serialize and deserialize helper as string.
mod as_string {
use super::*;
use serde::{Deserializer, Serializer};

pub fn serialize<S: Serializer>(data: &usize, serializer: S) -> Result<S::Ok, S::Error> {
data.to_string().serialize(serializer)
}

pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<usize, D::Error> {
String::deserialize(deserializer)?
.parse()
.map_err(|e| serde::de::Error::custom(format!("Parsing failed: {}", e)))
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -263,7 +245,7 @@ mod tests {
TransactionEvent::Broadcasted(TransactionBroadcasted { num_peers: 2 });
let ser = serde_json::to_string(&event).unwrap();

let exp = r#"{"event":"broadcasted","numPeers":"2"}"#;
let exp = r#"{"event":"broadcasted","numPeers":2}"#;
assert_eq!(ser, exp);

let event_dec: TransactionEvent<()> = serde_json::from_str(exp).unwrap();
Expand All @@ -288,7 +270,7 @@ mod tests {
}));
let ser = serde_json::to_string(&event).unwrap();

let exp = r#"{"event":"bestChainBlockIncluded","block":{"hash":"0x0000000000000000000000000000000000000000000000000000000000000001","index":"2"}}"#;
let exp = r#"{"event":"bestChainBlockIncluded","block":{"hash":"0x0000000000000000000000000000000000000000000000000000000000000001","index":2}}"#;
assert_eq!(ser, exp);

let event_dec: TransactionEvent<H256> = serde_json::from_str(exp).unwrap();
Expand All @@ -303,7 +285,7 @@ mod tests {
});
let ser = serde_json::to_string(&event).unwrap();

let exp = r#"{"event":"finalized","block":{"hash":"0x0000000000000000000000000000000000000000000000000000000000000001","index":"10"}}"#;
let exp = r#"{"event":"finalized","block":{"hash":"0x0000000000000000000000000000000000000000000000000000000000000001","index":10}}"#;
assert_eq!(ser, exp);

let event_dec: TransactionEvent<H256> = serde_json::from_str(exp).unwrap();
Expand Down