diff --git a/substrate/frame/contracts/rpc/src/lib.rs b/substrate/frame/contracts/rpc/src/lib.rs index 6d43ea75c0..a44ba769e9 100644 --- a/substrate/frame/contracts/rpc/src/lib.rs +++ b/substrate/frame/contracts/rpc/src/lib.rs @@ -33,7 +33,7 @@ use sp_runtime::{ traits::{Block as BlockT, Header as HeaderT}, DispatchError, }; -use std::convert::TryInto; +use std::convert::{TryFrom, TryInto}; use pallet_contracts_primitives::ContractExecResult; pub use pallet_contracts_rpc_runtime_api::ContractsApi as ContractsRuntimeApi; @@ -76,10 +76,10 @@ impl From for Error { #[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] #[serde(deny_unknown_fields)] -pub struct CallRequest { +pub struct CallRequest { origin: AccountId, dest: AccountId, - value: Balance, + value: number::NumberOrHex, gas_limit: number::NumberOrHex, input_data: Bytes, } @@ -141,7 +141,7 @@ pub trait ContractsApi { #[rpc(name = "contracts_call")] fn call( &self, - call_request: CallRequest, + call_request: CallRequest, at: Option, ) -> Result; @@ -201,11 +201,11 @@ where <::Header as HeaderT>::Number, >, AccountId: Codec, - Balance: Codec, + Balance: Codec + TryFrom, { fn call( &self, - call_request: CallRequest, + call_request: CallRequest, at: Option<::Hash>, ) -> Result { let api = self.client.runtime_api(); @@ -221,6 +221,13 @@ where input_data, } = 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. let gas_limit: u64 = gas_limit.try_into().map_err(|_| Error { code: ErrorCode::InvalidParams, @@ -305,17 +312,18 @@ mod tests { #[test] fn call_request_should_serialize_deserialize_properly() { - type Req = CallRequest; + type Req = CallRequest; let req: Req = serde_json::from_str(r#" { "origin": "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", "dest": "5DRakbLVnjVrW6niwLfHGW24EeCEvDAFGEXrtaYS5M4ynoom", - "value": 0, + "value": "0x112210f4B16c1cb1", "gasLimit": 1000000000000, "inputData": "0x8c97db39" } "#).unwrap(); assert_eq!(req.gas_limit.into_u256(), U256::from(0xe8d4a51000u64)); + assert_eq!(req.value.into_u256(), U256::from(1234567890987654321u128)); } #[test]