Skip to content
Snippets Groups Projects
Commit a5a64740 authored by Alexander Theißen's avatar Alexander Theißen Committed by GitHub
Browse files

contracts: Rework contracts_call RPC (#7468)

* Implement serde::Deserialize for DispatchError if std

This is needed to use this type in the contracts RPC.

* contracts: Change contract_call RPC to return more information
parent 9026eee5
No related merge requests found
......@@ -31,6 +31,7 @@ use sp_rpc::number;
use sp_runtime::{
generic::BlockId,
traits::{Block as BlockT, Header as HeaderT},
DispatchError,
};
use std::convert::TryInto;
use pallet_contracts_primitives::ContractExecResult;
......@@ -83,33 +84,47 @@ pub struct CallRequest<AccountId, Balance> {
input_data: Bytes,
}
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
struct RpcContractExecSuccess {
/// The return flags. See `pallet_contracts_primitives::ReturnFlags`.
flags: u32,
/// Data as returned by the contract.
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 {
/// The return flags
flags: u32,
/// Output data
data: Bytes,
/// How much gas was consumed by the call.
gas_consumed: u64,
},
/// Error execution
Error(()),
pub struct RpcContractExecResult {
/// How much gas was consumed by the call. In case of an error this is the amount
/// that was used up until the error occurred.
gas_consumed: u64,
/// Additional dynamic human readable error information for debugging. An empty string
/// indicates that no additional information is available.
debug_message: String,
/// Indicates whether the contract execution was successful or not.
result: std::result::Result<RpcContractExecSuccess, DispatchError>,
}
impl From<ContractExecResult> for RpcContractExecResult {
fn from(r: ContractExecResult) -> Self {
match r.exec_result {
Ok(val) => RpcContractExecResult::Success {
flags: val.flags.bits(),
data: val.data.into(),
Ok(val) => RpcContractExecResult {
gas_consumed: r.gas_consumed,
debug_message: String::new(),
result: Ok(RpcContractExecSuccess {
flags: val.flags.bits(),
data: val.data.into(),
}),
},
Err(err) => RpcContractExecResult {
gas_consumed: r.gas_consumed,
debug_message: String::new(),
result: Err(err.error),
},
_ => RpcContractExecResult::Error(()),
}
}
}
......@@ -310,7 +325,7 @@ mod tests {
let actual = serde_json::to_string(&res).unwrap();
assert_eq!(actual, expected);
}
test(r#"{"success":{"flags":5,"data":"0x1234","gas_consumed":5000}}"#);
test(r#"{"error":null}"#);
test(r#"{"gasConsumed":5000,"debugMessage":"helpOk","result":{"Ok":{"flags":5,"data":"0x1234"}}}"#);
test(r#"{"gasConsumed":3400,"debugMessage":"helpErr","result":{"Err":"BadOrigin"}}"#);
}
}
......@@ -388,10 +388,10 @@ pub type DispatchResultWithInfo<T> = sp_std::result::Result<T, DispatchErrorWith
/// Reason why a dispatch call failed.
#[derive(Eq, PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug)]
#[cfg_attr(feature = "std", derive(Serialize))]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum DispatchError {
/// Some error occurred.
Other(#[codec(skip)] &'static str),
Other(#[codec(skip)] #[cfg_attr(feature = "std", serde(skip_deserializing))] &'static str),
/// Failed to lookup some data.
CannotLookup,
/// A bad origin.
......@@ -404,6 +404,7 @@ pub enum DispatchError {
error: u8,
/// Optional error message.
#[codec(skip)]
#[cfg_attr(feature = "std", serde(skip_deserializing))]
message: Option<&'static str>,
},
}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment