diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 4a32074c59..df85a5e703 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -3553,6 +3553,7 @@ dependencies = [ "pallet-contracts-rpc-runtime-api 2.0.0", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", "sp-blockchain 2.0.0", "sp-core 2.0.0", "sp-rpc 2.0.0", @@ -3564,7 +3565,6 @@ name = "pallet-contracts-rpc-runtime-api" version = "2.0.0" dependencies = [ "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "sp-api 2.0.0", "sp-runtime 2.0.0", "sp-std 2.0.0", diff --git a/substrate/frame/contracts/rpc/Cargo.toml b/substrate/frame/contracts/rpc/Cargo.toml index 64b2318d08..fa030cb9ff 100644 --- a/substrate/frame/contracts/rpc/Cargo.toml +++ b/substrate/frame/contracts/rpc/Cargo.toml @@ -15,3 +15,6 @@ rpc-primitives = { package = "sp-rpc", path = "../../../primitives/rpc" } serde = { version = "1.0.101", features = ["derive"] } sp-runtime = { path = "../../../primitives/sr-primitives" } pallet-contracts-rpc-runtime-api = { path = "./runtime-api" } + +[dev-dependencies] +serde_json = "1.0.41" diff --git a/substrate/frame/contracts/rpc/runtime-api/Cargo.toml b/substrate/frame/contracts/rpc/runtime-api/Cargo.toml index ae71345488..dc044e1aeb 100644 --- a/substrate/frame/contracts/rpc/runtime-api/Cargo.toml +++ b/substrate/frame/contracts/rpc/runtime-api/Cargo.toml @@ -8,7 +8,6 @@ edition = "2018" sp-api = { path = "../../../../primitives/sr-api", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sp-std", path = "../../../../primitives/sr-std", default-features = false } -serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-runtime = { path = "../../../../primitives/sr-primitives", default-features = false } [features] @@ -17,6 +16,5 @@ std = [ "sp-api/std", "codec/std", "rstd/std", - "serde", "sp-runtime/std", ] diff --git a/substrate/frame/contracts/rpc/runtime-api/src/lib.rs b/substrate/frame/contracts/rpc/runtime-api/src/lib.rs index 2d3385d6d7..a4ee568c98 100644 --- a/substrate/frame/contracts/rpc/runtime-api/src/lib.rs +++ b/substrate/frame/contracts/rpc/runtime-api/src/lib.rs @@ -28,7 +28,6 @@ use sp_runtime::RuntimeDebug; /// A result of execution of a contract. #[derive(Eq, PartialEq, Encode, Decode, RuntimeDebug)] -#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub enum ContractExecResult { /// The contract returned successfully. /// diff --git a/substrate/frame/contracts/rpc/src/lib.rs b/substrate/frame/contracts/rpc/src/lib.rs index 3deee80cc3..ab0f89bd56 100644 --- a/substrate/frame/contracts/rpc/src/lib.rs +++ b/substrate/frame/contracts/rpc/src/lib.rs @@ -80,6 +80,35 @@ pub struct CallRequest { input_data: Bytes, } +/// An RPC serializable result of contract execution +#[derive(Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +#[serde(rename_all = "camelCase")] +pub enum RpcContractExecResult { + /// Successful execution + Success { + /// Status code + status: u8, + /// Output data + data: Bytes, + }, + /// Error execution + Error(()), +} + +impl From for RpcContractExecResult { + fn from(r: ContractExecResult) -> Self { + match r { + ContractExecResult::Success { status, data } => { + RpcContractExecResult::Success { status, data: data.into() } + }, + ContractExecResult::Error => { + RpcContractExecResult::Error(()) + }, + } + } +} + /// Contracts RPC methods. #[rpc] pub trait ContractsApi { @@ -94,7 +123,7 @@ pub trait ContractsApi { &self, call_request: CallRequest, at: Option, - ) -> Result; + ) -> Result; /// Returns the value under a specified storage `key` in a contract given by `address` param, /// or `None` if it is not set. @@ -138,7 +167,7 @@ where &self, call_request: CallRequest, at: Option<::Hash>, - ) -> Result { + ) -> Result { let api = self.client.runtime_api(); let at = BlockId::hash(at.unwrap_or_else(|| // If the block hash is not supplied assume the best block. @@ -178,7 +207,7 @@ where data: Some(format!("{:?}", e).into()), })?; - Ok(exec_result) + Ok(exec_result.into()) } fn get_storage( @@ -207,3 +236,20 @@ where Ok(get_storage_result) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn should_serialize_deserialize_properly() { + fn test(expected: &str) { + let res: RpcContractExecResult = serde_json::from_str(expected).unwrap(); + let actual = serde_json::to_string(&res).unwrap(); + assert_eq!(actual, expected); + } + + test(r#"{"success":{"status":5,"data":"0x1234"}}"#); + test(r#"{"error":null}"#); + } +}