Hex Balance deserialize for contracts_call RPC (#7807)

* Hex Balance deserialize for contracts_call RPC

* Avoid temporary conversion into u128

Co-authored-by: Alexander Theißen <alex.theissen@me.com>
This commit is contained in:
Jaco Greeff
2020-12-29 14:39:04 +01:00
committed by GitHub
parent ab876be9e9
commit 0b7ae4440c
+16 -8
View File
@@ -33,7 +33,7 @@ use sp_runtime::{
traits::{Block as BlockT, Header as HeaderT}, traits::{Block as BlockT, Header as HeaderT},
DispatchError, DispatchError,
}; };
use std::convert::TryInto; use std::convert::{TryFrom, TryInto};
use pallet_contracts_primitives::ContractExecResult; use pallet_contracts_primitives::ContractExecResult;
pub use pallet_contracts_rpc_runtime_api::ContractsApi as ContractsRuntimeApi; pub use pallet_contracts_rpc_runtime_api::ContractsApi as ContractsRuntimeApi;
@@ -76,10 +76,10 @@ impl From<ContractAccessError> for Error {
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
pub struct CallRequest<AccountId, Balance> { pub struct CallRequest<AccountId> {
origin: AccountId, origin: AccountId,
dest: AccountId, dest: AccountId,
value: Balance, value: number::NumberOrHex,
gas_limit: number::NumberOrHex, gas_limit: number::NumberOrHex,
input_data: Bytes, input_data: Bytes,
} }
@@ -141,7 +141,7 @@ pub trait ContractsApi<BlockHash, BlockNumber, AccountId, Balance> {
#[rpc(name = "contracts_call")] #[rpc(name = "contracts_call")]
fn call( fn call(
&self, &self,
call_request: CallRequest<AccountId, Balance>, call_request: CallRequest<AccountId>,
at: Option<BlockHash>, at: Option<BlockHash>,
) -> Result<RpcContractExecResult>; ) -> Result<RpcContractExecResult>;
@@ -201,11 +201,11 @@ where
<<Block as BlockT>::Header as HeaderT>::Number, <<Block as BlockT>::Header as HeaderT>::Number,
>, >,
AccountId: Codec, AccountId: Codec,
Balance: Codec, Balance: Codec + TryFrom<number::NumberOrHex>,
{ {
fn call( fn call(
&self, &self,
call_request: CallRequest<AccountId, Balance>, call_request: CallRequest<AccountId>,
at: Option<<Block as BlockT>::Hash>, at: Option<<Block as BlockT>::Hash>,
) -> Result<RpcContractExecResult> { ) -> Result<RpcContractExecResult> {
let api = self.client.runtime_api(); let api = self.client.runtime_api();
@@ -221,6 +221,13 @@ where
input_data, input_data,
} = call_request; } = call_request;
// Make sure that value fits into the balance type.
let value: Balance = value.try_into().map_err(|_| Error {
code: ErrorCode::InvalidParams,
message: format!("{:?} doesn't fit into the balance type", value),
data: None,
})?;
// Make sure that gas_limit fits into 64 bits. // Make sure that gas_limit fits into 64 bits.
let gas_limit: u64 = gas_limit.try_into().map_err(|_| Error { let gas_limit: u64 = gas_limit.try_into().map_err(|_| Error {
code: ErrorCode::InvalidParams, code: ErrorCode::InvalidParams,
@@ -305,17 +312,18 @@ mod tests {
#[test] #[test]
fn call_request_should_serialize_deserialize_properly() { fn call_request_should_serialize_deserialize_properly() {
type Req = CallRequest<String, u128>; type Req = CallRequest<String>;
let req: Req = serde_json::from_str(r#" let req: Req = serde_json::from_str(r#"
{ {
"origin": "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", "origin": "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL",
"dest": "5DRakbLVnjVrW6niwLfHGW24EeCEvDAFGEXrtaYS5M4ynoom", "dest": "5DRakbLVnjVrW6niwLfHGW24EeCEvDAFGEXrtaYS5M4ynoom",
"value": 0, "value": "0x112210f4B16c1cb1",
"gasLimit": 1000000000000, "gasLimit": 1000000000000,
"inputData": "0x8c97db39" "inputData": "0x8c97db39"
} }
"#).unwrap(); "#).unwrap();
assert_eq!(req.gas_limit.into_u256(), U256::from(0xe8d4a51000u64)); assert_eq!(req.gas_limit.into_u256(), U256::from(0xe8d4a51000u64));
assert_eq!(req.value.into_u256(), U256::from(1234567890987654321u128));
} }
#[test] #[test]