git.delta.rocks / unique-network / refs/commits / f0549a82b0ee

difftreelog

fix backwards compatibility for token_owner rpc

Yaroslav Bolyukin2022-02-14parent: #bcf103b.patch.diff
in: master

2 files changed

modifiedclient/rpc/src/lib.rsdiffbeforeafterboth
--- a/client/rpc/src/lib.rs
+++ b/client/rpc/src/lib.rs
@@ -4,7 +4,7 @@
 use jsonrpc_core::{Error as RpcError, ErrorCode, Result};
 use jsonrpc_derive::rpc;
 use up_data_structs::{Collection, CollectionId, CollectionStats, TokenId};
-use sp_api::{BlockId, BlockT, ProvideRuntimeApi};
+use sp_api::{BlockId, BlockT, ProvideRuntimeApi, ApiExt};
 use sp_blockchain::HeaderBackend;
 use up_rpc::UniqueApi as UniqueRuntimeApi;
 
@@ -132,7 +132,10 @@
 }
 
 macro_rules! pass_method {
-	($method_name:ident($($name:ident: $ty:ty),* $(,)?) -> $result:ty $(=> $mapper:expr)?) => {
+	(
+		$method_name:ident($($name:ident: $ty:ty),* $(,)?) -> $result:ty $(=> $mapper:expr)?
+		$(; changed_in $ver:expr, $changed_method_name:ident ($($changed_name:expr), * $(,)?) => $fixer:expr)*
+	) => {
 		fn $method_name(
 			&self,
 			$(
@@ -142,8 +145,25 @@
 		) -> Result<$result> {
 			let api = self.client.runtime_api();
 			let at = BlockId::hash(at.unwrap_or_else(|| self.client.info().best_hash));
+			let _api_version = if let Ok(Some(api_version)) =
+				api.api_version::<dyn UniqueRuntimeApi<Block, CrossAccountId, AccountId>>(&at)
+			{
+				api_version
+			} else {
+				// unreachable for our runtime
+				return Err(RpcError {
+					code: ErrorCode::InvalidParams,
+					message: "Api is not available".into(),
+					data: None,
+				})
+			};
 
-			let result = api.$method_name(&at, $($name),*).map_err(|e| RpcError {
+			let result = $(if _api_version < $ver {
+				api.$changed_method_name(&at, $($changed_name),*).map(|r| r.map($fixer))
+			} else)*
+			{ api.$method_name(&at, $($name),*) };
+
+			let result = result.map_err(|e| RpcError {
 				code: ErrorCode::ServerError(Error::RuntimeError.into()),
 				message: "Unable to query".into(),
 				data: Some(format!("{:?}", e).into()),
@@ -168,7 +188,10 @@
 {
 	pass_method!(account_tokens(collection: CollectionId, account: CrossAccountId) -> Vec<TokenId>);
 	pass_method!(token_exists(collection: CollectionId, token: TokenId) -> bool);
-	pass_method!(token_owner(collection: CollectionId, token: TokenId) -> Option<CrossAccountId>);
+	pass_method!(
+		token_owner(collection: CollectionId, token: TokenId) -> Option<CrossAccountId>;
+		changed_in 2, token_owner_before_version_2(collection, token) => |u| Some(u)
+	);
 	pass_method!(const_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>);
 	pass_method!(variable_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>);
 	pass_method!(collection_tokens(collection: CollectionId) -> u32);
modifiedprimitives/rpc/src/lib.rsdiffbeforeafterboth
before · primitives/rpc/src/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]23use up_data_structs::{CollectionId, TokenId, Collection, CollectionStats};4use sp_std::vec::Vec;5use sp_core::H160;6use codec::Decode;7use sp_runtime::DispatchError;89type Result<T> = core::result::Result<T, DispatchError>;1011sp_api::decl_runtime_apis! {12	pub trait UniqueApi<CrossAccountId, AccountId> where13		AccountId: Decode,14		CrossAccountId: pallet_common::account::CrossAccountId<AccountId>,15	{16		fn account_tokens(collection: CollectionId, account: CrossAccountId) -> Result<Vec<TokenId>>;17		fn token_exists(collection: CollectionId, token: TokenId) -> Result<bool>;1819		fn token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>>;20		fn const_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>>;21		fn variable_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>>;2223		fn collection_tokens(collection: CollectionId) -> Result<u32>;24		fn account_balance(collection: CollectionId, account: CrossAccountId) -> Result<u32>;25		fn balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<u128>;26		fn allowance(27			collection: CollectionId,28			sender: CrossAccountId,29			spender: CrossAccountId,30			token: TokenId,31		) -> Result<u128>;3233		/// Used for ethereum integration34		fn eth_contract_code(account: H160) -> Option<Vec<u8>>;3536		fn adminlist(collection: CollectionId) -> Result<Vec<CrossAccountId>>;37		fn allowlist(collection: CollectionId) -> Result<Vec<CrossAccountId>>;38		fn allowed(collection: CollectionId, user: CrossAccountId) -> Result<bool>;39		fn last_token_id(collection: CollectionId) -> Result<TokenId>;40		fn collection_by_id(collection: CollectionId) -> Result<Option<Collection<AccountId>>>;41		fn collection_stats() -> Result<CollectionStats>;42	}43}
after · primitives/rpc/src/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]23use up_data_structs::{CollectionId, TokenId, Collection, CollectionStats};4use sp_std::vec::Vec;5use sp_core::H160;6use codec::Decode;7use sp_runtime::DispatchError;89type Result<T> = core::result::Result<T, DispatchError>;1011sp_api::decl_runtime_apis! {12	#[api_version(2)]13	pub trait UniqueApi<CrossAccountId, AccountId> where14		AccountId: Decode,15		CrossAccountId: pallet_common::account::CrossAccountId<AccountId>,16	{17		#[changed_in(2)]18		fn token_owner(collection: CollectionId, token: TokenId) -> Result<CrossAccountId>;1920		fn account_tokens(collection: CollectionId, account: CrossAccountId) -> Result<Vec<TokenId>>;21		fn token_exists(collection: CollectionId, token: TokenId) -> Result<bool>;2223		fn token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>>;24		fn const_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>>;25		fn variable_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>>;2627		fn collection_tokens(collection: CollectionId) -> Result<u32>;28		fn account_balance(collection: CollectionId, account: CrossAccountId) -> Result<u32>;29		fn balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<u128>;30		fn allowance(31			collection: CollectionId,32			sender: CrossAccountId,33			spender: CrossAccountId,34			token: TokenId,35		) -> Result<u128>;3637		/// Used for ethereum integration38		fn eth_contract_code(account: H160) -> Option<Vec<u8>>;3940		fn adminlist(collection: CollectionId) -> Result<Vec<CrossAccountId>>;41		fn allowlist(collection: CollectionId) -> Result<Vec<CrossAccountId>>;42		fn allowed(collection: CollectionId, user: CrossAccountId) -> Result<bool>;43		fn last_token_id(collection: CollectionId) -> Result<TokenId>;44		fn collection_by_id(collection: CollectionId) -> Result<Option<Collection<AccountId>>>;45		fn collection_stats() -> Result<CollectionStats>;46	}47}