git.delta.rocks / unique-network / refs/commits / 5fa1e1446963

difftreelog

fix serde rpc

Yaroslav Bolyukin2021-11-01parent: #a02890f.patch.diff
in: master

3 files changed

modifiedclient/rpc/src/lib.rsdiffbeforeafterboth
before · client/rpc/src/lib.rs
1use std::sync::Arc;23use codec::Decode;4use jsonrpc_core::{Error as RpcError, ErrorCode, Result};5use jsonrpc_derive::rpc;6use nft_data_structs::{CollectionId, TokenId};7use sp_api::{BlockId, BlockT, ProvideRuntimeApi};8use sp_blockchain::HeaderBackend;9use up_rpc::NftApi as NftRuntimeApi;1011#[rpc]12pub trait NftApi<BlockHash, CrossAccountId, AccountId> {13	#[rpc(name = "nft_accountTokens")]14	fn account_tokens(15		&self,16		collection: CollectionId,17		account: CrossAccountId,18		at: Option<BlockHash>,19	) -> Result<Vec<TokenId>>;20	#[rpc(name = "nft_tokenExists")]21	fn token_exists(22		&self,23		collection: CollectionId,24		token: TokenId,25		at: Option<BlockHash>,26	) -> Result<bool>;2728	#[rpc(name = "nft_tokenOwner")]29	fn token_owner(30		&self,31		collection: CollectionId,32		token: TokenId,33		at: Option<BlockHash>,34	) -> Result<CrossAccountId>;35	#[rpc(name = "nft_constMetadata")]36	fn const_metadata(37		&self,38		collection: CollectionId,39		token: TokenId,40		at: Option<BlockHash>,41	) -> Result<Vec<u8>>;42	#[rpc(name = "nft_variableMetadata")]43	fn variable_metadata(44		&self,45		collection: CollectionId,46		token: TokenId,47		at: Option<BlockHash>,48	) -> Result<Vec<u8>>;4950	#[rpc(name = "nft_collectionTokens")]51	fn collection_tokens(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<u32>;52	#[rpc(name = "nft_accountBalance")]53	fn account_balance(54		&self,55		collection: CollectionId,56		account: CrossAccountId,57		at: Option<BlockHash>,58	) -> Result<u32>;59	#[rpc(name = "nft_balance")]60	fn balance(61		&self,62		collection: CollectionId,63		account: CrossAccountId,64		token: TokenId,65		at: Option<BlockHash>,66	) -> Result<u128>;67	#[rpc(name = "nft_allowance")]68	fn allowance(69		&self,70		collection: CollectionId,71		sender: CrossAccountId,72		spender: CrossAccountId,73		token: TokenId,74		at: Option<BlockHash>,75	) -> Result<u128>;7677	#[rpc(name = "nft_adminlist")]78	fn adminlist(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<Vec<AccountId>>;79	#[rpc(name = "nft_allowlist")]80	fn allowlist(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<Vec<AccountId>>;81	#[rpc(name = "nft_lastTokenId")]82	fn last_token_id(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<TokenId>;83}8485pub struct Nft<C, P> {86	client: Arc<C>,87	_marker: std::marker::PhantomData<P>,88}8990impl<C, P> Nft<C, P> {91	pub fn new(client: Arc<C>) -> Self {92		Self {93			client,94			_marker: Default::default(),95		}96	}97}9899pub enum Error {100	RuntimeError,101}102103impl From<Error> for i64 {104	fn from(e: Error) -> i64 {105		match e {106			Error::RuntimeError => 1,107		}108	}109}110111macro_rules! pass_method {112	($method_name:ident($($name:ident: $ty:ty),* $(,)?) -> $result:ty) => {113		fn $method_name(114			&self,115			$(116				$name: $ty,117			)*118			at: Option<<Block as BlockT>::Hash>,119		) -> Result<$result> {120			let api = self.client.runtime_api();121			let at = BlockId::hash(at.unwrap_or_else(|| self.client.info().best_hash));122123			api.$method_name(&at, $($name),*).map_err(|e| RpcError {124				code: ErrorCode::ServerError(Error::RuntimeError.into()),125				message: "Unable to query".into(),126				data: Some(format!("{:?}", e).into()),127			})128		}129	};130}131132impl<C, Block, CrossAccountId, AccountId> NftApi<<Block as BlockT>::Hash, CrossAccountId, AccountId>133	for Nft<C, Block>134where135	Block: BlockT,136	AccountId: Decode,137	C: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,138	C::Api: NftRuntimeApi<Block, CrossAccountId, AccountId>,139	CrossAccountId: pallet_common::account::CrossAccountId<AccountId>,140{141	pass_method!(account_tokens(collection: CollectionId, account: CrossAccountId) -> Vec<TokenId>);142	pass_method!(token_exists(collection: CollectionId, token: TokenId) -> bool);143	pass_method!(token_owner(collection: CollectionId, token: TokenId) -> CrossAccountId);144	pass_method!(const_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>);145	pass_method!(variable_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>);146	pass_method!(collection_tokens(collection: CollectionId) -> u32);147	pass_method!(account_balance(collection: CollectionId, account: CrossAccountId) -> u32);148	pass_method!(balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> u128);149	pass_method!(allowance(collection: CollectionId, sender: CrossAccountId, spender: CrossAccountId, token: TokenId) -> u128);150151	pass_method!(adminlist(collection: CollectionId) -> Vec<AccountId>);152	pass_method!(allowlist(collection: CollectionId) -> Vec<AccountId>);153	pass_method!(last_token_id(collection: CollectionId) -> TokenId);154}
after · client/rpc/src/lib.rs
1use std::sync::Arc;23use codec::Decode;4use jsonrpc_core::{Error as RpcError, ErrorCode, Result};5use jsonrpc_derive::rpc;6use nft_data_structs::{CollectionId, TokenId};7use sp_api::{BlockId, BlockT, ProvideRuntimeApi};8use sp_blockchain::HeaderBackend;9use up_rpc::NftApi as NftRuntimeApi;1011#[rpc]12pub trait NftApi<BlockHash, CrossAccountId, AccountId> {13	#[rpc(name = "nft_accountTokens")]14	fn account_tokens(15		&self,16		collection: CollectionId,17		account: CrossAccountId,18		at: Option<BlockHash>,19	) -> Result<Vec<TokenId>>;20	#[rpc(name = "nft_tokenExists")]21	fn token_exists(22		&self,23		collection: CollectionId,24		token: TokenId,25		at: Option<BlockHash>,26	) -> Result<bool>;2728	#[rpc(name = "nft_tokenOwner")]29	fn token_owner(30		&self,31		collection: CollectionId,32		token: TokenId,33		at: Option<BlockHash>,34	) -> Result<CrossAccountId>;35	#[rpc(name = "nft_constMetadata")]36	fn const_metadata(37		&self,38		collection: CollectionId,39		token: TokenId,40		at: Option<BlockHash>,41	) -> Result<Vec<u8>>;42	#[rpc(name = "nft_variableMetadata")]43	fn variable_metadata(44		&self,45		collection: CollectionId,46		token: TokenId,47		at: Option<BlockHash>,48	) -> Result<Vec<u8>>;4950	#[rpc(name = "nft_collectionTokens")]51	fn collection_tokens(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<u32>;52	#[rpc(name = "nft_accountBalance")]53	fn account_balance(54		&self,55		collection: CollectionId,56		account: CrossAccountId,57		at: Option<BlockHash>,58	) -> Result<u32>;59	#[rpc(name = "nft_balance")]60	fn balance(61		&self,62		collection: CollectionId,63		account: CrossAccountId,64		token: TokenId,65		at: Option<BlockHash>,66	) -> Result<String>;67	#[rpc(name = "nft_allowance")]68	fn allowance(69		&self,70		collection: CollectionId,71		sender: CrossAccountId,72		spender: CrossAccountId,73		token: TokenId,74		at: Option<BlockHash>,75	) -> Result<String>;7677	#[rpc(name = "nft_adminlist")]78	fn adminlist(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<Vec<AccountId>>;79	#[rpc(name = "nft_allowlist")]80	fn allowlist(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<Vec<AccountId>>;81	#[rpc(name = "nft_lastTokenId")]82	fn last_token_id(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<TokenId>;83}8485pub struct Nft<C, P> {86	client: Arc<C>,87	_marker: std::marker::PhantomData<P>,88}8990impl<C, P> Nft<C, P> {91	pub fn new(client: Arc<C>) -> Self {92		Self {93			client,94			_marker: Default::default(),95		}96	}97}9899pub enum Error {100	RuntimeError,101}102103impl From<Error> for i64 {104	fn from(e: Error) -> i64 {105		match e {106			Error::RuntimeError => 1,107		}108	}109}110111macro_rules! pass_method {112	($method_name:ident($($name:ident: $ty:ty),* $(,)?) -> $result:ty $(=> $mapper:expr)?) => {113		fn $method_name(114			&self,115			$(116				$name: $ty,117			)*118			at: Option<<Block as BlockT>::Hash>,119		) -> Result<$result> {120			let api = self.client.runtime_api();121			let at = BlockId::hash(at.unwrap_or_else(|| self.client.info().best_hash));122123			api.$method_name(&at, $($name),*).map_err(|e| RpcError {124				code: ErrorCode::ServerError(Error::RuntimeError.into()),125				message: "Unable to query".into(),126				data: Some(format!("{:?}", e).into()),127			}) $(128				.map($mapper)129			)?130		}131	};132}133134impl<C, Block, CrossAccountId, AccountId> NftApi<<Block as BlockT>::Hash, CrossAccountId, AccountId>135	for Nft<C, Block>136where137	Block: BlockT,138	AccountId: Decode,139	C: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,140	C::Api: NftRuntimeApi<Block, CrossAccountId, AccountId>,141	CrossAccountId: pallet_common::account::CrossAccountId<AccountId>,142{143	pass_method!(account_tokens(collection: CollectionId, account: CrossAccountId) -> Vec<TokenId>);144	pass_method!(token_exists(collection: CollectionId, token: TokenId) -> bool);145	pass_method!(token_owner(collection: CollectionId, token: TokenId) -> CrossAccountId);146	pass_method!(const_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>);147	pass_method!(variable_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>);148	pass_method!(collection_tokens(collection: CollectionId) -> u32);149	pass_method!(account_balance(collection: CollectionId, account: CrossAccountId) -> u32);150	pass_method!(balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> String => |v| v.to_string());151	pass_method!(allowance(collection: CollectionId, sender: CrossAccountId, spender: CrossAccountId, token: TokenId) -> String => |v| v.to_string());152153	pass_method!(adminlist(collection: CollectionId) -> Vec<AccountId>);154	pass_method!(allowlist(collection: CollectionId) -> Vec<AccountId>);155	pass_method!(last_token_id(collection: CollectionId) -> TokenId);156}
modifiedpallets/common/Cargo.tomldiffbeforeafterboth
--- a/pallets/common/Cargo.toml
+++ b/pallets/common/Cargo.toml
@@ -21,6 +21,9 @@
 
 pallet-evm = { default-features = false, version = "6.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.10" }
 serde = { version = "1.0.130", default-features = false }
+scale-info = { version = "1.0.0", default-features = false, features = [
+    "derive",
+] }
 
 [features]
 default = ["std"]
modifiedpallets/common/src/account.rsdiffbeforeafterboth
--- a/pallets/common/src/account.rs
+++ b/pallets/common/src/account.rs
@@ -20,7 +20,14 @@
 	fn from_eth(account: H160) -> Self;
 }
 
-#[derive(Eq, Serialize, Deserialize)]
+#[derive(Encode, Decode, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+enum BasicCrossAccountIdRepr<AccountId> {
+	Substrate(AccountId),
+	Ethereum(H160),
+}
+
+#[derive(Eq)]
 pub struct BasicCrossAccountId<T: Config> {
 	/// If true - then ethereum is canonical encoding
 	from_ethereum: bool,
@@ -84,12 +91,7 @@
 }
 impl<T: Config> Encode for BasicCrossAccountId<T> {
 	fn encode(&self) -> Vec<u8> {
-		let as_result = if !self.from_ethereum {
-			Ok(self.substrate.clone())
-		} else {
-			Err(self.ethereum)
-		};
-		as_result.encode()
+		BasicCrossAccountIdRepr::from(self.clone()).encode()
 	}
 }
 impl<T: Config> EncodeLike for BasicCrossAccountId<T> {}
@@ -98,12 +100,34 @@
 	where
 		I: codec::Input,
 	{
-		Ok(match <Result<T::AccountId, H160>>::decode(input)? {
-			Ok(s) => Self::from_sub(s),
-			Err(e) => Self::from_eth(e),
-		})
+		Ok(BasicCrossAccountIdRepr::decode(input)?.into())
 	}
 }
+impl<T> Serialize for BasicCrossAccountId<T>
+where
+	T: Config,
+	T::AccountId: Serialize,
+{
+	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+	where
+		S: serde::Serializer,
+	{
+		let repr = BasicCrossAccountIdRepr::from(self.clone());
+		(&repr).serialize(serializer)
+	}
+}
+impl<'de, T> Deserialize<'de> for BasicCrossAccountId<T>
+where
+	T: Config,
+	T::AccountId: Deserialize<'de>,
+{
+	fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+	where
+		D: serde::Deserializer<'de>,
+	{
+		Ok(BasicCrossAccountIdRepr::deserialize(deserializer)?.into())
+	}
+}
 impl<T: Config> CrossAccountId<T::AccountId> for BasicCrossAccountId<T> {
 	fn as_sub(&self) -> &T::AccountId {
 		&self.substrate
@@ -126,6 +150,23 @@
 		}
 	}
 }
+impl<T: Config> From<BasicCrossAccountIdRepr<T::AccountId>> for BasicCrossAccountId<T> {
+	fn from(repr: BasicCrossAccountIdRepr<T::AccountId>) -> Self {
+		match repr {
+			BasicCrossAccountIdRepr::Substrate(s) => Self::from_sub(s),
+			BasicCrossAccountIdRepr::Ethereum(e) => Self::from_eth(e),
+		}
+	}
+}
+impl<T: Config> From<BasicCrossAccountId<T>> for BasicCrossAccountIdRepr<T::AccountId> {
+	fn from(v: BasicCrossAccountId<T>) -> Self {
+		if v.from_ethereum {
+			BasicCrossAccountIdRepr::Ethereum(*v.as_eth())
+		} else {
+			BasicCrossAccountIdRepr::Substrate(v.as_sub().clone())
+		}
+	}
+}
 
 pub trait EvmBackwardsAddressMapping<AccountId> {
 	fn from_account_id(account_id: AccountId) -> H160;