From 4122560dd68e58e40c96375f92d20e7f2eb02503 Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Fri, 10 Feb 2023 18:46:50 +0100 Subject: [PATCH 01/14] feat(vault): Lend Token collateral --- Cargo.lock | 145 ++++++++++++++++++++---------------------- runtime/src/assets.rs | 43 ++++++++++++- runtime/src/error.rs | 2 + runtime/src/rpc.rs | 33 ++++++++++ runtime/src/types.rs | 11 ++-- vault/src/system.rs | 6 ++ 6 files changed, 160 insertions(+), 80 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5db0d51fa..2cbee9d46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -136,9 +136,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" +checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" [[package]] name = "approx" @@ -537,9 +537,9 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.60.1" +version = "0.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6" +checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" dependencies = [ "bitflags", "cexpr", @@ -552,6 +552,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", + "syn", ] [[package]] @@ -681,24 +682,24 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72936ee4afc7f8f736d1c38383b56480b5497b4617b4a77bdbf1d2ababc76127" +checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" dependencies = [ "arrayref", "arrayvec 0.7.2", - "constant_time_eq 0.1.5", + "constant_time_eq", ] [[package]] name = "blake2s_simd" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db539cc2b5f6003621f1cd9ef92d7ded8ea5232c7de0f9faa2de251cd98730d4" +checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f" dependencies = [ "arrayref", "arrayvec 0.7.2", - "constant_time_eq 0.1.5", + "constant_time_eq", ] [[package]] @@ -711,7 +712,7 @@ dependencies = [ "arrayvec 0.7.2", "cc", "cfg-if 1.0.0", - "constant_time_eq 0.2.4", + "constant_time_eq", "digest 0.10.6", ] @@ -1187,12 +1188,6 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - [[package]] name = "constant_time_eq" version = "0.2.4" @@ -2077,9 +2072,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +checksum = "c0808e1bd8671fb44a113a14e13497557533369847788fa2ae912b6ebfce9fa8" dependencies = [ "darling_core", "darling_macro", @@ -2087,9 +2082,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +checksum = "001d80444f28e193f30c2f293455da62dcf9a6b29918a4253152ae2b1de592cb" dependencies = [ "fnv", "ident_case", @@ -2101,9 +2096,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685" dependencies = [ "darling_core", "quote", @@ -2919,14 +2914,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.19" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e884668cd0c7480504233e951174ddc3b382f7c2666e3b7310b5c4e7b0c37f9" +checksum = "8a3de6e8d11b22ff9edc6d916f890800597d60f8b2da1caf2955c274638d6412" dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -3328,12 +3323,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "fs_extra" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" - [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -3700,7 +3689,7 @@ dependencies = [ "indexmap", "slab", "tokio", - "tokio-util 0.7.4", + "tokio-util 0.7.6", "tracing", ] @@ -3791,6 +3780,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hex" version = "0.4.3" @@ -4448,14 +4443,14 @@ checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" [[package]] name = "is-terminal" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi 0.3.1", "io-lifetimes 1.0.5", - "rustix 0.36.7", - "windows-sys 0.42.0", + "rustix 0.36.8", + "windows-sys 0.45.0", ] [[package]] @@ -4687,7 +4682,7 @@ dependencies = [ "thiserror", "tokio", "tokio-rustls", - "tokio-util 0.7.4", + "tokio-util 0.7.6", "tracing", "webpki-roots", ] @@ -4770,7 +4765,7 @@ dependencies = [ "soketto", "tokio", "tokio-stream", - "tokio-util 0.7.4", + "tokio-util 0.7.6", "tower", "tracing", ] @@ -5476,9 +5471,9 @@ dependencies = [ [[package]] name = "librocksdb-sys" -version = "0.8.0+7.4.4" +version = "0.8.3+7.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611804e4666a25136fcc5f8cf425ab4d26c7f74ea245ffe92ea23b85b6420b5d" +checksum = "557b255ff04123fcc176162f56ed0c9cd42d8f357cf55b3fabeb60f7413741b3" dependencies = [ "bindgen", "bzip2-sys", @@ -5767,7 +5762,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b20a59d985586e4a5aef64564ac77299f8586d8be6cf9106a5a40207e8908efb" dependencies = [ - "rustix 0.36.7", + "rustix 0.36.8", ] [[package]] @@ -7857,9 +7852,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.5.4" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab62d2fa33726dbe6321cc97ef96d8cde531e3eeaf858a058de53a8a6d40d8f" +checksum = "028accff104c4e513bad663bbcd2ad7cfd5304144404c31ed0a77ac103d00660" dependencies = [ "thiserror", "ucd-trie", @@ -7867,9 +7862,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.5.4" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf026e2d0581559db66d837fe5242320f525d85c76283c61f4d51a1238d65ea" +checksum = "2ac3922aac69a40733080f53c1ce7f91dcf57e1a5f6c52f421fadec7fbdc4b69" dependencies = [ "pest", "pest_generator", @@ -7877,9 +7872,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.5.4" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b27bd18aa01d91c8ed2b61ea23406a676b42d82609c6e2581fba42f0c15f17f" +checksum = "d06646e185566b5961b4058dd107e0a7f56e77c3f484549fb119867773c0f202" dependencies = [ "pest", "pest_meta", @@ -7890,9 +7885,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.5.4" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f02b677c1859756359fc9983c2e56a0237f18624a3789528804406b7e915e5d" +checksum = "e6f60b2ba541577e2a0c307c8f39d1439108120eb7903adeb6497fa880c59616" dependencies = [ "once_cell", "pest", @@ -7901,9 +7896,9 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" +checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" dependencies = [ "fixedbitset", "indexmap", @@ -9259,9 +9254,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.50" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" dependencies = [ "unicode-ident", ] @@ -9595,9 +9590,9 @@ dependencies = [ [[package]] name = "raw-cpuid" -version = "10.6.0" +version = "10.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6823ea29436221176fe662da99998ad3b4db2c7f31e7b6f5fe43adccd6320bb" +checksum = "c307f7aacdbab3f0adee67d52739a1d71112cc068d6fab169ddeb18e48877fad" dependencies = [ "bitflags", ] @@ -10159,16 +10154,16 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.7" +version = "0.36.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" +checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" dependencies = [ "bitflags", "errno", "io-lifetimes 1.0.5", "libc", "linux-raw-sys 0.1.4", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -11625,9 +11620,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.91" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" +checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76" dependencies = [ "itoa", "ryu", @@ -13548,10 +13543,11 @@ checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" [[package]] name = "thread_local" -version = "1.1.4" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +checksum = "50f297120ff9d4efe680df143d5631bba9c75fa371992b7fcb33eb3453cb0a07" dependencies = [ + "cfg-if 1.0.0", "once_cell", ] @@ -13590,12 +13586,11 @@ dependencies = [ [[package]] name = "tikv-jemalloc-sys" -version = "0.5.2+5.3.0-patched" +version = "0.5.3+5.3.0-patched" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec45c14da997d0925c7835883e4d5c181f196fa142f8c19d7643d1e9af2592c3" +checksum = "a678df20055b43e57ef8cddde41cdfda9a3c1a060b67f4c5836dfb1d78543ba8" dependencies = [ "cc", - "fs_extra", "libc", ] @@ -13687,9 +13682,9 @@ dependencies = [ [[package]] name = "tokio-native-tls" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", "tokio", @@ -13715,7 +13710,7 @@ dependencies = [ "futures-core", "pin-project-lite 0.2.9", "tokio", - "tokio-util 0.7.4", + "tokio-util 0.7.6", ] [[package]] @@ -13746,9 +13741,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +checksum = "bc6a3b08b64e6dfad376fa2432c7b1f01522e37a623c3050bc95db2d3ff21583" dependencies = [ "bytes", "futures-core", @@ -14457,7 +14452,7 @@ dependencies = [ "tokio", "tokio-stream", "tokio-tungstenite", - "tokio-util 0.7.4", + "tokio-util 0.7.6", "tower-service", "tracing", ] @@ -15229,9 +15224,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.6+zstd.1.5.2" +version = "2.0.7+zstd.1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a3f9792c0c3dc6c165840a75f47ae1f4da402c2d006881129579f6597e801b" +checksum = "94509c3ba2fe55294d752b79842c530ccfab760192521df74a081a78d2b3c7f5" dependencies = [ "cc", "libc", diff --git a/runtime/src/assets.rs b/runtime/src/assets.rs index ef87bacc5..2a4bc12ef 100644 --- a/runtime/src/assets.rs +++ b/runtime/src/assets.rs @@ -1,4 +1,4 @@ -use crate::{types::*, AssetMetadata, Error}; +use crate::{metadata::runtime_types::loans::types::Market, types::*, AssetMetadata, Error}; use lazy_static::lazy_static; use primitives::{CurrencyId, CurrencyInfo}; use std::{ @@ -67,6 +67,41 @@ impl AssetRegistry { } } +lazy_static! { + // NOTE: restrict access to the lock to ensure that no async code yields while holding the mutex + static ref LENDING_ASSETS: Mutex = Mutex::new(LendingAssets::default()); +} + +#[derive(Debug, Clone, Default)] +pub struct LendingAssets { + // Mapping from underlying currency to LendToken + underlying_to_lend_token: BTreeMap, +} + +impl LendingAssets { + /// Fetch the global, mutable singleton + fn global() -> Result, Error> { + LENDING_ASSETS.lock().map_err(|_| Error::CannotOpenAssetRegistry) + } + + pub(crate) fn insert(underlying_id: CurrencyId, market: LendingMarket) -> Result<(), Error> { + let mut lending_assets = Self::global()?; + lending_assets + .underlying_to_lend_token + .insert(underlying_id, market.lend_token_id); + Ok(()) + } + + /// Fetch the currency for a ticker symbol + pub fn get_lend_token_id(underlying_id: CurrencyId) -> Result { + Self::global()? + .underlying_to_lend_token + .get(&underlying_id) + .cloned() + .ok_or(Error::AssetNotFound) + } +} + /// Convert a ticker symbol into a `CurrencyId` at runtime pub trait TryFromSymbol: Sized { fn try_from_symbol(symbol: String) -> Result; @@ -83,6 +118,12 @@ impl TryFromSymbol for CurrencyId { id if id == KSM.symbol() => Ok(Token(KSM)), id if id == KBTC.symbol() => Ok(Token(KBTC)), id if id == KINT.symbol() => Ok(Token(KINT)), + // Lend Tokens are prefixed with Q for end users. Example: QDOT is + // the DOT lend token. + id if id.chars().nth(0) == Some('Q') => { + let underlying_id = Self::try_from_symbol(id[1..].to_string())?; + LendingAssets::get_lend_token_id(underlying_id) + } _ => AssetRegistry::get_foreign_asset_by_symbol(uppercase_symbol), } } diff --git a/runtime/src/error.rs b/runtime/src/error.rs index cdea3531b..8b3633dc9 100644 --- a/runtime/src/error.rs +++ b/runtime/src/error.rs @@ -35,6 +35,8 @@ pub enum Error { AssetNotFound, #[error("Could not unlock local asset registry")] CannotOpenAssetRegistry, + #[error("Cannot acquire lock for lending assets")] + CannotAccessLendingAssets, #[error("Could not get vault")] VaultNotFound, #[error("Vault has been liquidated")] diff --git a/runtime/src/rpc.rs b/runtime/src/rpc.rs index 636459537..bf7ad0e7e 100644 --- a/runtime/src/rpc.rs +++ b/runtime/src/rpc.rs @@ -1,4 +1,5 @@ use crate::{ + assets::LendingAssets, conn::{new_websocket_client, new_websocket_client_with_retry}, metadata, notify_retry, types::*, @@ -598,6 +599,38 @@ impl InterBtcParachain { Ok(()) } + /// Cache new markets and updates + pub async fn listen_for_lending_markets(&self) -> Result<(), Error> { + futures::future::try_join( + self.on_event::( + |event| async move { + if let Err(err) = LendingAssets::insert(event.underlying_currency_id, event.market) { + log::error!( + "Failed to register lending market {:?}: {}", + event.underlying_currency_id, + err + ); + } + }, + |_| {}, + ), + self.on_event::( + |event| async move { + if let Err(err) = LendingAssets::insert(event.underlying_currency_id, event.market) { + log::error!( + "Failed to update lending market {:?}: {}", + event.underlying_currency_id, + err + ); + } + }, + |_| {}, + ), + ) + .await?; + Ok(()) + } + /// Listen to fee_rate changes and broadcast new values on the fee_rate_update_tx channel pub async fn listen_for_fee_rate_changes(&self) -> Result<(), Error> { self.on_event::( diff --git a/runtime/src/types.rs b/runtime/src/types.rs index 1de457c2f..9b353c7a7 100644 --- a/runtime/src/types.rs +++ b/runtime/src/types.rs @@ -27,6 +27,8 @@ pub type BtcAddress = module_btc_relay::BtcAddress; pub type FixedU128 = sp_arithmetic::FixedU128; mod metadata_aliases { + use crate::metadata::runtime_types::loans::types::Market; + use super::*; pub use metadata::runtime_types::bitcoin::address::PublicKey as BtcPublicKey; @@ -43,12 +45,12 @@ mod metadata_aliases { pub type InterBtcRichBlockHeader = metadata::runtime_types::btc_relay::types::RichBlockHeader; pub type BitcoinBlockHeight = u32; - pub use metadata::asset_registry::events::{ - RegisteredAsset as RegisteredAssetEvent, UpdatedAsset as UpdatedAssetEvent, + pub use metadata::{ + asset_registry::events::{RegisteredAsset as RegisteredAssetEvent, UpdatedAsset as UpdatedAssetEvent}, + loans::events::{NewMarket as NewMarketEvent, UpdatedMarket as UpdatedMarketEvent}, + oracle::events::FeedValues as FeedValuesEvent, }; - pub use metadata::oracle::events::FeedValues as FeedValuesEvent; - pub use metadata::issue::events::{ CancelIssue as CancelIssueEvent, ExecuteIssue as ExecuteIssueEvent, RequestIssue as RequestIssueEvent, }; @@ -77,6 +79,7 @@ mod metadata_aliases { orml_traits::asset_registry::AssetMetadata as GenericAssetMetadata, }; pub type AssetMetadata = GenericAssetMetadata; + pub type LendingMarket = metadata::runtime_types::loans::types::Market; pub use metadata::runtime_types::{ btc_relay::pallet::Error as BtcRelayPalletError, frame_system::pallet::Error as SystemPalletError, diff --git a/vault/src/system.rs b/vault/src/system.rs index 090078ea1..a88091a75 100644 --- a/vault/src/system.rs +++ b/vault/src/system.rs @@ -604,6 +604,8 @@ impl VaultService { let listen_for_registered_assets = |rpc: InterBtcParachain| async move { rpc.listen_for_registered_assets().await }; + let listen_for_lending_markets = |rpc: InterBtcParachain| async move { rpc.listen_for_lending_markets().await }; + let listen_for_fee_rate_estimate_changes = |rpc: InterBtcParachain| async move { rpc.listen_for_fee_rate_changes().await }; @@ -613,6 +615,10 @@ impl VaultService { "Registered Asset Listener", run(listen_for_registered_assets(self.btc_parachain.clone())), ), + ( + "Lending Market Listener", + run(listen_for_lending_markets(self.btc_parachain.clone())), + ), ( "Fee Estimate Listener", run(listen_for_fee_rate_estimate_changes(self.btc_parachain.clone())), From f3a9a25c4f590fe139ea3e026b950d9f5551e1a3 Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Mon, 13 Feb 2023 17:49:21 +0100 Subject: [PATCH 02/14] feat(loans): read lend tokens from storage --- Cargo.lock | 10 +++++----- runtime/src/assets.rs | 13 +++++++++++-- runtime/src/rpc.rs | 33 +++++++++++++++++++++++++++++---- vault/README.md | 2 +- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2cbee9d46..470d923f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15233,12 +15233,12 @@ dependencies = [ "pkg-config", ] -[[patch.unused]] -name = "orml-xcm" -version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=24f0a8b6e04e1078f70d0437fb816337cdf4f64c#24f0a8b6e04e1078f70d0437fb816337cdf4f64c" - [[patch.unused]] name = "sp-serializer" version = "4.0.0-dev" source = "git+https://github.com/paritytech//substrate?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" + +[[patch.unused]] +name = "orml-xcm" +version = "0.4.1-dev" +source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=24f0a8b6e04e1078f70d0437fb816337cdf4f64c#24f0a8b6e04e1078f70d0437fb816337cdf4f64c" diff --git a/runtime/src/assets.rs b/runtime/src/assets.rs index 2a4bc12ef..b220c6942 100644 --- a/runtime/src/assets.rs +++ b/runtime/src/assets.rs @@ -84,16 +84,25 @@ impl LendingAssets { LENDING_ASSETS.lock().map_err(|_| Error::CannotOpenAssetRegistry) } - pub(crate) fn insert(underlying_id: CurrencyId, market: LendingMarket) -> Result<(), Error> { + pub(crate) fn insert(underlying_id: CurrencyId, lend_token_id: CurrencyId) -> Result<(), Error> { let mut lending_assets = Self::global()?; lending_assets .underlying_to_lend_token - .insert(underlying_id, market.lend_token_id); + .insert(underlying_id, lend_token_id); + Ok(()) + } + + pub(crate) fn extend(assets: Vec<(CurrencyId, CurrencyId)>) -> Result<(), Error> { + for (underlying_id, lend_token_id) in assets { + // TODO: check for duplicates? + Self::insert(underlying_id, lend_token_id)?; + } Ok(()) } /// Fetch the currency for a ticker symbol pub fn get_lend_token_id(underlying_id: CurrencyId) -> Result { + log::info!("in get_lend_token {:?}", underlying_id); Self::global()? .underlying_to_lend_token .get(&underlying_id) diff --git a/runtime/src/rpc.rs b/runtime/src/rpc.rs index bf7ad0e7e..6773a5751 100644 --- a/runtime/src/rpc.rs +++ b/runtime/src/rpc.rs @@ -135,6 +135,7 @@ impl InterBtcParachain { // TODO: refresh on registration parachain_rpc.store_assets_metadata().await?; + parachain_rpc.store_lend_tokens().await?; Ok(parachain_rpc) } @@ -575,6 +576,10 @@ impl InterBtcParachain { AssetRegistry::extend(self.get_foreign_assets_metadata().await?) } + pub async fn store_lend_tokens(&self) -> Result<(), Error> { + LendingAssets::extend(self.get_lend_tokens().await?) + } + /// Cache registered assets and updates pub async fn listen_for_registered_assets(&self) -> Result<(), Error> { futures::future::try_join( @@ -604,9 +609,9 @@ impl InterBtcParachain { futures::future::try_join( self.on_event::( |event| async move { - if let Err(err) = LendingAssets::insert(event.underlying_currency_id, event.market) { + if let Err(err) = LendingAssets::insert(event.underlying_currency_id, event.market.lend_token_id) { log::error!( - "Failed to register lending market {:?}: {}", + "Failed to register lend token {:?}: {}", event.underlying_currency_id, err ); @@ -616,9 +621,9 @@ impl InterBtcParachain { ), self.on_event::( |event| async move { - if let Err(err) = LendingAssets::insert(event.underlying_currency_id, event.market) { + if let Err(err) = LendingAssets::insert(event.underlying_currency_id, event.market.lend_token_id) { log::error!( - "Failed to update lending market {:?}: {}", + "Failed to update lend token {:?}: {}", event.underlying_currency_id, err ); @@ -671,6 +676,8 @@ pub trait UtilFuncs { async fn get_foreign_assets_metadata(&self) -> Result, Error>; async fn get_foreign_asset_metadata(&self, id: u32) -> Result; + + async fn get_lend_tokens(&self) -> Result, Error>; } #[async_trait] @@ -714,6 +721,24 @@ impl UtilFuncs for InterBtcParachain { Ok(ret) } + async fn get_lend_tokens(&self) -> Result, Error> { + let head = self.get_finalized_block_hash().await?; + let key_addr = metadata::storage().loans().markets_root(); + let mut iter = self.api.storage().iter(key_addr, DEFAULT_PAGE_SIZE, head).await?; + + let mut ret = Vec::new(); + while let Some((key, value)) = iter.next().await? { + let raw_key = key.0.clone(); + + // last bytes are the raw key + let mut key = &raw_key[raw_key.len() - 4..]; + + let decoded_key: CurrencyId = Decode::decode(&mut key)?; + ret.push((decoded_key, value.lend_token_id)); + } + Ok(ret) + } + async fn get_foreign_asset_metadata(&self, id: u32) -> Result { self.query_finalized(metadata::storage().asset_registry().metadata(&id)) .await? diff --git a/vault/README.md b/vault/README.md index fa17b4c2d..3036a5830 100644 --- a/vault/README.md +++ b/vault/README.md @@ -50,7 +50,7 @@ cargo run --bin vault --features parachain-metadata-kintsugi vault generate-bitcoin-key private-key.wif --network bitcoin # parachain sr25519 key -vault generate-parachain-key keyfile.json +vault generate-parachain-key --output keyfile.json # start the vault client vault \ From bc7c022b0d0c35e70967d6b9aaa882f3675f76b5 Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Mon, 13 Feb 2023 18:26:20 +0000 Subject: [PATCH 03/14] fix(vault): loans markets key decoding --- Cargo.lock | 10 +++++----- runtime/src/assets.rs | 5 +++++ runtime/src/rpc.rs | 12 ++++++++++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 470d923f3..2cbee9d46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15233,12 +15233,12 @@ dependencies = [ "pkg-config", ] -[[patch.unused]] -name = "sp-serializer" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech//substrate?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" - [[patch.unused]] name = "orml-xcm" version = "0.4.1-dev" source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=24f0a8b6e04e1078f70d0437fb816337cdf4f64c#24f0a8b6e04e1078f70d0437fb816337cdf4f64c" + +[[patch.unused]] +name = "sp-serializer" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech//substrate?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" diff --git a/runtime/src/assets.rs b/runtime/src/assets.rs index b220c6942..e991e68b6 100644 --- a/runtime/src/assets.rs +++ b/runtime/src/assets.rs @@ -85,6 +85,11 @@ impl LendingAssets { } pub(crate) fn insert(underlying_id: CurrencyId, lend_token_id: CurrencyId) -> Result<(), Error> { + log::info!( + "Found loans market: {:?}, with lend token: {:?}", + underlying_id, + lend_token_id + ); let mut lending_assets = Self::global()?; lending_assets .underlying_to_lend_token diff --git a/runtime/src/rpc.rs b/runtime/src/rpc.rs index 6773a5751..3e44aa353 100644 --- a/runtime/src/rpc.rs +++ b/runtime/src/rpc.rs @@ -36,6 +36,15 @@ const BLOCK_WAIT_TIMEOUT: Duration = Duration::from_secs(6); // number of storage entries to fetch at a time const DEFAULT_PAGE_SIZE: u32 = 10; +// TODO: Convert to a utility function +/// Keys in storage maps are prefixed by two `twox_128` hashes: the pallet name and the +/// storage item names. Then, assuming the map uses the `Blake2_128Concat` hasher, the layout +/// looks as follows: +/// `twox_128("PalletName") ++ twox_128("ItemName") ++ Blake2_128Concat(key) ++ key` +/// So to get the actual value of the key from a raw key, we need to ignore the first +/// `3 * 128 / 8` bytes, or `48` bytes. +const STORAGE_KEY_HASH_PREFIX_LENGTH: usize = 48; + // sanity check to be sure that testing-utils is not accidentally selected #[cfg(all( any(test, feature = "testing-utils"), @@ -730,8 +739,7 @@ impl UtilFuncs for InterBtcParachain { while let Some((key, value)) = iter.next().await? { let raw_key = key.0.clone(); - // last bytes are the raw key - let mut key = &raw_key[raw_key.len() - 4..]; + let mut key = &raw_key[STORAGE_KEY_HASH_PREFIX_LENGTH..]; let decoded_key: CurrencyId = Decode::decode(&mut key)?; ret.push((decoded_key, value.lend_token_id)); From 2facff48c1897a8070072e959c181a40f5de275c Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Tue, 14 Feb 2023 17:48:34 +0100 Subject: [PATCH 04/14] feat(runtime): name, symbol, decimals for lend tokens --- Cargo.lock | 10 +++++----- runtime/src/assets.rs | 29 ++++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2cbee9d46..470d923f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15233,12 +15233,12 @@ dependencies = [ "pkg-config", ] -[[patch.unused]] -name = "orml-xcm" -version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=24f0a8b6e04e1078f70d0437fb816337cdf4f64c#24f0a8b6e04e1078f70d0437fb816337cdf4f64c" - [[patch.unused]] name = "sp-serializer" version = "4.0.0-dev" source = "git+https://github.com/paritytech//substrate?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" + +[[patch.unused]] +name = "orml-xcm" +version = "0.4.1-dev" +source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=24f0a8b6e04e1078f70d0437fb816337cdf4f64c#24f0a8b6e04e1078f70d0437fb816337cdf4f64c" diff --git a/runtime/src/assets.rs b/runtime/src/assets.rs index e991e68b6..5c33c1019 100644 --- a/runtime/src/assets.rs +++ b/runtime/src/assets.rs @@ -74,8 +74,8 @@ lazy_static! { #[derive(Debug, Clone, Default)] pub struct LendingAssets { - // Mapping from underlying currency to LendToken underlying_to_lend_token: BTreeMap, + lend_token_to_underlying: BTreeMap, } impl LendingAssets { @@ -94,6 +94,9 @@ impl LendingAssets { lending_assets .underlying_to_lend_token .insert(underlying_id, lend_token_id); + lending_assets + .lend_token_to_underlying + .insert(lend_token_id, underlying_id); Ok(()) } @@ -105,15 +108,23 @@ impl LendingAssets { Ok(()) } - /// Fetch the currency for a ticker symbol + /// Fetch the lend token id associated with an underlying currency pub fn get_lend_token_id(underlying_id: CurrencyId) -> Result { - log::info!("in get_lend_token {:?}", underlying_id); Self::global()? .underlying_to_lend_token .get(&underlying_id) .cloned() .ok_or(Error::AssetNotFound) } + + /// Fetch the lend token id associated with an underlying currency + pub fn get_underlying_id(lend_token_id: CurrencyId) -> Result { + Self::global()? + .lend_token_to_underlying + .get(&lend_token_id) + .cloned() + .ok_or(Error::AssetNotFound) + } } /// Convert a ticker symbol into a `CurrencyId` at runtime @@ -157,6 +168,10 @@ impl RuntimeCurrencyInfo for CurrencyId { CurrencyId::Token(token_symbol) => Ok(token_symbol.name().to_string()), CurrencyId::ForeignAsset(foreign_asset_id) => AssetRegistry::get_asset_metadata_by_id(*foreign_asset_id) .and_then(|asset_metadata| String::from_utf8(asset_metadata.name).map_err(|_| Error::InvalidCurrency)), + CurrencyId::LendToken(id) => { + let underlying_currency = LendingAssets::get_underlying_id(CurrencyId::LendToken(*id))?; + Ok(format!("Lend{}", underlying_currency.name()?)) + } _ => Err(Error::TokenUnsupported), } } @@ -168,6 +183,10 @@ impl RuntimeCurrencyInfo for CurrencyId { .and_then(|asset_metadata| { String::from_utf8(asset_metadata.symbol).map_err(|_| Error::InvalidCurrency) }), + CurrencyId::LendToken(id) => { + let underlying_currency = LendingAssets::get_underlying_id(CurrencyId::LendToken(*id))?; + Ok(format!("Q{}", underlying_currency.symbol()?)) + } _ => Err(Error::TokenUnsupported), } } @@ -178,6 +197,10 @@ impl RuntimeCurrencyInfo for CurrencyId { CurrencyId::ForeignAsset(foreign_asset_id) => { AssetRegistry::get_asset_metadata_by_id(*foreign_asset_id).map(|asset_metadata| asset_metadata.decimals) } + CurrencyId::LendToken(id) => { + let underlying_currency = LendingAssets::get_underlying_id(CurrencyId::LendToken(*id))?; + underlying_currency.decimals() + } _ => Err(Error::TokenUnsupported), } } From 81399f563b9779f5cf72ed12826826d7fed2a013 Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Wed, 15 Feb 2023 13:56:27 +0100 Subject: [PATCH 05/14] fix(runtime): qtoken parsing test --- Cargo.lock | 10 ++++---- runtime/src/assets.rs | 2 +- runtime/src/lib.rs | 3 +++ runtime/src/rpc.rs | 49 ++++++++++++++++++++++++++++++++++++++- runtime/src/tests.rs | 6 +++++ runtime/src/types.rs | 3 +-- vault/Untitled-1 | 8 +++++++ vault/src/cancellation.rs | 1 + vault/src/execution.rs | 1 + vault/src/metrics.rs | 1 + 10 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 vault/Untitled-1 diff --git a/Cargo.lock b/Cargo.lock index 470d923f3..2cbee9d46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15233,12 +15233,12 @@ dependencies = [ "pkg-config", ] -[[patch.unused]] -name = "sp-serializer" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech//substrate?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" - [[patch.unused]] name = "orml-xcm" version = "0.4.1-dev" source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=24f0a8b6e04e1078f70d0437fb816337cdf4f64c#24f0a8b6e04e1078f70d0437fb816337cdf4f64c" + +[[patch.unused]] +name = "sp-serializer" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech//substrate?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" diff --git a/runtime/src/assets.rs b/runtime/src/assets.rs index 5c33c1019..ab1b07374 100644 --- a/runtime/src/assets.rs +++ b/runtime/src/assets.rs @@ -1,4 +1,4 @@ -use crate::{metadata::runtime_types::loans::types::Market, types::*, AssetMetadata, Error}; +use crate::{types::*, AssetMetadata, Error}; use lazy_static::lazy_static; use primitives::{CurrencyId, CurrencyInfo}; use std::{ diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index c1ddf1bc7..ca0a4be2a 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -108,6 +108,9 @@ pub mod metadata { #[subxt(substitute_type = "sp_arithmetic::fixed_point::FixedU128")] use crate::FixedU128; + #[subxt(substitute_type = "sp_arithmetic::per_things::Permill")] + use crate::Ratio; + #[subxt(substitute_type = "bitcoin::address::Address")] use crate::BtcAddress; diff --git a/runtime/src/rpc.rs b/runtime/src/rpc.rs index 3e44aa353..91cabacc5 100644 --- a/runtime/src/rpc.rs +++ b/runtime/src/rpc.rs @@ -581,12 +581,59 @@ impl InterBtcParachain { Ok(()) } + #[cfg(test)] + fn lending_mock_market_from_id(&self, id: u32) -> metadata::runtime_types::loans::types::Market { + use primitives::{Rate, Ratio}; + use sp_runtime::FixedPointNumber; + + metadata::runtime_types::loans::types::Market:: { + close_factor: Ratio::from_percent(50), + collateral_factor: Ratio::from_percent(50), + liquidation_threshold: Ratio::from_percent(55), + liquidate_incentive: Rate::from_inner(Rate::DIV / 100 * 110), + state: metadata::runtime_types::loans::types::MarketState::Pending, + rate_model: metadata::runtime_types::loans::rate_model::InterestRateModel::Jump( + metadata::runtime_types::loans::rate_model::JumpModel { + base_rate: Rate::from_inner(Rate::DIV / 100 * 2), + jump_rate: Rate::from_inner(Rate::DIV / 100 * 10), + full_rate: Rate::from_inner(Rate::DIV / 100 * 32), + jump_utilization: Ratio::from_percent(80), + }, + ), + reserve_factor: Ratio::from_percent(15), + liquidate_incentive_reserved_factor: Ratio::from_percent(3), + supply_cap: 1_000_000_000_000_000_000_000u128, + borrow_cap: 1_000_000_000_000_000_000_000u128, + lend_token_id: CurrencyId::LendToken(id), + } + } + + #[cfg(test)] + pub async fn register_markets(&self) -> Result<(), Error> { + let add_market_txs = [ForeignAsset(1), Token(KINT)] + .iter() + .enumerate() + .map(|(i, asset_id)| { + EncodedCall::Loans(metadata::runtime_types::loans::pallet::Call::add_market { + asset_id: *asset_id, + market: self.lending_mock_market_from_id(i as u32), + }) + }) + .collect(); + let batch = EncodedCall::Utility(metadata::runtime_types::pallet_utility::pallet::Call::batch { + calls: add_market_txs, + }); + self.with_unique_signer(metadata::tx().sudo().sudo(batch)).await?; + Ok(()) + } + pub async fn store_assets_metadata(&self) -> Result<(), Error> { AssetRegistry::extend(self.get_foreign_assets_metadata().await?) } pub async fn store_lend_tokens(&self) -> Result<(), Error> { - LendingAssets::extend(self.get_lend_tokens().await?) + let lend_tokens = self.get_lend_tokens().await?; + LendingAssets::extend(lend_tokens) } /// Cache registered assets and updates diff --git a/runtime/src/tests.rs b/runtime/src/tests.rs index c959e1416..8bdf056a5 100644 --- a/runtime/src/tests.rs +++ b/runtime/src/tests.rs @@ -10,6 +10,7 @@ use super::{ use crate::{integration::*, FeedValuesEvent, OracleKey, RuntimeCurrencyInfo, VaultId, H160, U256}; use module_bitcoin::{formatter::TryFormattable, types::BlockBuilder}; pub use primitives::CurrencyId::ForeignAsset; +use primitives::CurrencyId::LendToken; use sp_keyring::AccountKeyring; use std::{convert::TryInto, time::Duration}; @@ -170,10 +171,15 @@ async fn test_currency_id_parsing() { let parachain_rpc = setup_provider(client.clone(), AccountKeyring::Alice).await; parachain_rpc.register_dummy_assets().await.unwrap(); parachain_rpc.store_assets_metadata().await.unwrap(); + parachain_rpc.register_markets().await.unwrap(); + parachain_rpc.store_lend_tokens().await.unwrap(); // test with different capitalization to make sure the check is not case sensitive assert_eq!(CurrencyId::try_from_symbol("KiNt".to_string()).unwrap(), Token(KINT)); + assert_eq!(CurrencyId::try_from_symbol("abc".to_string()).unwrap(), ForeignAsset(1)); + assert_eq!(CurrencyId::try_from_symbol("qabC".to_string()).unwrap(), LendToken(0)); + assert_eq!(CurrencyId::try_from_symbol("qkInt".to_string()).unwrap(), LendToken(1)); assert_eq!( CurrencyId::try_from_symbol("TeSt".to_string()).unwrap(), ForeignAsset(2) diff --git a/runtime/src/types.rs b/runtime/src/types.rs index 9b353c7a7..662015712 100644 --- a/runtime/src/types.rs +++ b/runtime/src/types.rs @@ -19,6 +19,7 @@ pub type BlockNumber = u32; pub type H160 = subxt::ext::sp_core::H160; pub type H256 = subxt::ext::sp_core::H256; pub type U256 = subxt::ext::sp_core::U256; +pub type Ratio = primitives::Ratio; pub type InterBtcSigner = subxt::tx::PairSigner; @@ -27,8 +28,6 @@ pub type BtcAddress = module_btc_relay::BtcAddress; pub type FixedU128 = sp_arithmetic::FixedU128; mod metadata_aliases { - use crate::metadata::runtime_types::loans::types::Market; - use super::*; pub use metadata::runtime_types::bitcoin::address::PublicKey as BtcPublicKey; diff --git a/vault/Untitled-1 b/vault/Untitled-1 new file mode 100644 index 000000000..4d703bdce --- /dev/null +++ b/vault/Untitled-1 @@ -0,0 +1,8 @@ +--parachain-ws=wss://api-dev-kintsugi.interlay.io:443/parachain +-- +--btc-parachain-url=ws://kintnet-rpc:9944 +--faucet-url=http://kintnet-faucet:3033 +--auto-register=QKSM=1000 +--keyfile=keyfile.json +--keyname $(cat keyfile.json | jq -r 'keys[0]') +--bitcoin-rpc-url=kintnet-api.interlay.io/parachain \ No newline at end of file diff --git a/vault/src/cancellation.rs b/vault/src/cancellation.rs index 18c800e1d..4272c0be5 100644 --- a/vault/src/cancellation.rs +++ b/vault/src/cancellation.rs @@ -373,6 +373,7 @@ mod tests { fn is_this_vault(&self, vault_id: &VaultId) -> bool; async fn get_foreign_assets_metadata(&self) -> Result, RuntimeError>; async fn get_foreign_asset_metadata(&self, id: u32) -> Result; + async fn get_lend_tokens(&self) -> Result, RuntimeError>; } #[async_trait] diff --git a/vault/src/execution.rs b/vault/src/execution.rs index 70bdb791f..847a34b4f 100644 --- a/vault/src/execution.rs +++ b/vault/src/execution.rs @@ -642,6 +642,7 @@ mod tests { fn is_this_vault(&self, vault_id: &VaultId) -> bool; async fn get_foreign_assets_metadata(&self) -> Result, RuntimeError>; async fn get_foreign_asset_metadata(&self, id: u32) -> Result; + async fn get_lend_tokens(&self) -> Result, RuntimeError>; } #[async_trait] pub trait VaultRegistryPallet { diff --git a/vault/src/metrics.rs b/vault/src/metrics.rs index c5844aedb..0379d23c8 100644 --- a/vault/src/metrics.rs +++ b/vault/src/metrics.rs @@ -701,6 +701,7 @@ mod tests { fn is_this_vault(&self, vault_id: &VaultId) -> bool; async fn get_foreign_assets_metadata(&self) -> Result, RuntimeError>; async fn get_foreign_asset_metadata(&self, id: u32) -> Result; + async fn get_lend_tokens(&self) -> Result, RuntimeError>; } #[async_trait] From 831c0eecca8d9e0f0fd8b875d19af4a76825d690 Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Thu, 16 Feb 2023 13:30:13 +0100 Subject: [PATCH 06/14] chore(runtime): refactor lend token prefixes --- Cargo.lock | 10 +++++----- runtime/src/assets.rs | 17 +++++++++++------ runtime/src/rpc.rs | 2 +- runtime/src/tests.rs | 2 +- vault/Untitled-1 | 8 -------- 5 files changed, 18 insertions(+), 21 deletions(-) delete mode 100644 vault/Untitled-1 diff --git a/Cargo.lock b/Cargo.lock index 2cbee9d46..470d923f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15233,12 +15233,12 @@ dependencies = [ "pkg-config", ] -[[patch.unused]] -name = "orml-xcm" -version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=24f0a8b6e04e1078f70d0437fb816337cdf4f64c#24f0a8b6e04e1078f70d0437fb816337cdf4f64c" - [[patch.unused]] name = "sp-serializer" version = "4.0.0-dev" source = "git+https://github.com/paritytech//substrate?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" + +[[patch.unused]] +name = "orml-xcm" +version = "0.4.1-dev" +source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=24f0a8b6e04e1078f70d0437fb816337cdf4f64c#24f0a8b6e04e1078f70d0437fb816337cdf4f64c" diff --git a/runtime/src/assets.rs b/runtime/src/assets.rs index ab1b07374..a3fae3031 100644 --- a/runtime/src/assets.rs +++ b/runtime/src/assets.rs @@ -11,6 +11,13 @@ lazy_static! { static ref ASSET_REGISTRY: Mutex = Mutex::new(AssetRegistry::default()); } +/// The symbol of Lend Tokens is the symbol of their underlying currency, +/// prefixed by `Q`. Example: `QDOT` is the `DOT` lend token symbol. +const LEND_TOKEN_SYMBOL_PREFIX: char = 'Q'; +/// The name of Lend Tokens is the name of their underlying currency, +/// prefixed by `Lend`. Example: `LendPolkadot` is the `Polkadot` lend token name. +const LEND_TOKEN_NAME_PREFIX: &str = "Lend"; + #[derive(Debug, Clone, Default)] pub struct AssetRegistry { symbol_lookup: BTreeMap, @@ -117,7 +124,7 @@ impl LendingAssets { .ok_or(Error::AssetNotFound) } - /// Fetch the lend token id associated with an underlying currency + /// Fetch the underlying id associated with a lend token currency pub fn get_underlying_id(lend_token_id: CurrencyId) -> Result { Self::global()? .lend_token_to_underlying @@ -143,9 +150,7 @@ impl TryFromSymbol for CurrencyId { id if id == KSM.symbol() => Ok(Token(KSM)), id if id == KBTC.symbol() => Ok(Token(KBTC)), id if id == KINT.symbol() => Ok(Token(KINT)), - // Lend Tokens are prefixed with Q for end users. Example: QDOT is - // the DOT lend token. - id if id.chars().nth(0) == Some('Q') => { + id if id.chars().nth(0) == Some(LEND_TOKEN_SYMBOL_PREFIX) => { let underlying_id = Self::try_from_symbol(id[1..].to_string())?; LendingAssets::get_lend_token_id(underlying_id) } @@ -170,7 +175,7 @@ impl RuntimeCurrencyInfo for CurrencyId { .and_then(|asset_metadata| String::from_utf8(asset_metadata.name).map_err(|_| Error::InvalidCurrency)), CurrencyId::LendToken(id) => { let underlying_currency = LendingAssets::get_underlying_id(CurrencyId::LendToken(*id))?; - Ok(format!("Lend{}", underlying_currency.name()?)) + Ok(format!("{}{}", LEND_TOKEN_NAME_PREFIX, underlying_currency.name()?)) } _ => Err(Error::TokenUnsupported), } @@ -185,7 +190,7 @@ impl RuntimeCurrencyInfo for CurrencyId { }), CurrencyId::LendToken(id) => { let underlying_currency = LendingAssets::get_underlying_id(CurrencyId::LendToken(*id))?; - Ok(format!("Q{}", underlying_currency.symbol()?)) + Ok(format!("{}{}", LEND_TOKEN_SYMBOL_PREFIX, underlying_currency.symbol()?)) } _ => Err(Error::TokenUnsupported), } diff --git a/runtime/src/rpc.rs b/runtime/src/rpc.rs index 91cabacc5..c3437046b 100644 --- a/runtime/src/rpc.rs +++ b/runtime/src/rpc.rs @@ -609,7 +609,7 @@ impl InterBtcParachain { } #[cfg(test)] - pub async fn register_markets(&self) -> Result<(), Error> { + pub async fn register_lending_markets(&self) -> Result<(), Error> { let add_market_txs = [ForeignAsset(1), Token(KINT)] .iter() .enumerate() diff --git a/runtime/src/tests.rs b/runtime/src/tests.rs index 8bdf056a5..6e24d53d5 100644 --- a/runtime/src/tests.rs +++ b/runtime/src/tests.rs @@ -171,7 +171,7 @@ async fn test_currency_id_parsing() { let parachain_rpc = setup_provider(client.clone(), AccountKeyring::Alice).await; parachain_rpc.register_dummy_assets().await.unwrap(); parachain_rpc.store_assets_metadata().await.unwrap(); - parachain_rpc.register_markets().await.unwrap(); + parachain_rpc.register_lending_markets().await.unwrap(); parachain_rpc.store_lend_tokens().await.unwrap(); // test with different capitalization to make sure the check is not case sensitive diff --git a/vault/Untitled-1 b/vault/Untitled-1 deleted file mode 100644 index 4d703bdce..000000000 --- a/vault/Untitled-1 +++ /dev/null @@ -1,8 +0,0 @@ ---parachain-ws=wss://api-dev-kintsugi.interlay.io:443/parachain --- ---btc-parachain-url=ws://kintnet-rpc:9944 ---faucet-url=http://kintnet-faucet:3033 ---auto-register=QKSM=1000 ---keyfile=keyfile.json ---keyname $(cat keyfile.json | jq -r 'keys[0]') ---bitcoin-rpc-url=kintnet-api.interlay.io/parachain \ No newline at end of file From bfddbfccabf6cfd792fd3d63370345aa40c381e5 Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Thu, 16 Feb 2023 14:19:52 +0100 Subject: [PATCH 07/14] fix(runtime): lend token parsing clippy warning --- Cargo.lock | 74 +++++++++++++++++++++---------------------- runtime/src/assets.rs | 3 +- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 470d923f3..58f07d4c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,7 +27,7 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ - "gimli 0.27.1", + "gimli 0.27.2", ] [[package]] @@ -1064,9 +1064,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.1.4" +version = "4.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76" +checksum = "ec0b0588d44d4d63a87dbd75c136c166bbfd9a86a31cb89e09906521c7d3f5e3" dependencies = [ "bitflags", "clap_derive", @@ -2028,9 +2028,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.89" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc831ee6a32dd495436e317595e639a587aa9907bef96fe6e6abc290ab6204e9" +checksum = "86d3488e7665a7a483b57e25bdd90d0aeb2bc7608c8d0346acf2ad3f1caf1d62" dependencies = [ "cc", "cxxbridge-flags", @@ -2040,9 +2040,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.89" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94331d54f1b1a8895cd81049f7eaaaef9d05a7dcb4d1fd08bf3ff0806246789d" +checksum = "48fcaf066a053a41a81dfb14d57d99738b767febb8b735c3016e469fac5da690" dependencies = [ "cc", "codespan-reporting", @@ -2055,15 +2055,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.89" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48dcd35ba14ca9b40d6e4b4b39961f23d835dbb8eed74565ded361d93e1feb8a" +checksum = "a2ef98b8b717a829ca5603af80e1f9e2e48013ab227b68ef37872ef84ee479bf" [[package]] name = "cxxbridge-macro" -version = "1.0.89" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bbeb29798b407ccd82a3324ade1a7286e0d29851475990b612670f6f5124d2" +checksum = "086c685979a698443656e5cf7856c95c642295a38599f12fb1ff76fb28d19892" dependencies = [ "proc-macro2", "quote", @@ -2798,9 +2798,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] @@ -3555,9 +3555,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" [[package]] name = "git-version" @@ -3689,7 +3689,7 @@ dependencies = [ "indexmap", "slab", "tokio", - "tokio-util 0.7.6", + "tokio-util 0.7.7", "tracing", ] @@ -4682,7 +4682,7 @@ dependencies = [ "thiserror", "tokio", "tokio-rustls", - "tokio-util 0.7.6", + "tokio-util 0.7.7", "tracing", "webpki-roots", ] @@ -4765,7 +4765,7 @@ dependencies = [ "soketto", "tokio", "tokio-stream", - "tokio-util 0.7.6", + "tokio-util 0.7.7", "tower", "tracing", ] @@ -5873,14 +5873,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log 0.4.17", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -6477,9 +6477,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "opaque-debug" @@ -7692,9 +7692,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3840933452adf7b3b9145e27086a5a3376c619dca1a21b1e5a5af0d54979bed" +checksum = "637935964ff85a605d114591d4d2c13c5d1ba2806dae97cea6bf180238a749ac" dependencies = [ "arrayvec 0.7.2", "bitvec", @@ -11797,9 +11797,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "signal-hook" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" +checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" dependencies = [ "libc", "signal-hook-registry", @@ -11807,9 +11807,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ "libc", ] @@ -13254,9 +13254,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.5" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "8ae9980cab1db3fceee2f6c6f643d5d8de2997c58ee8d25fb0cc8a9e9e7348e5" [[package]] name = "tempdir" @@ -13543,9 +13543,9 @@ checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" [[package]] name = "thread_local" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f297120ff9d4efe680df143d5631bba9c75fa371992b7fcb33eb3453cb0a07" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ "cfg-if 1.0.0", "once_cell", @@ -13710,7 +13710,7 @@ dependencies = [ "futures-core", "pin-project-lite 0.2.9", "tokio", - "tokio-util 0.7.6", + "tokio-util 0.7.7", ] [[package]] @@ -13741,9 +13741,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6a3b08b64e6dfad376fa2432c7b1f01522e37a623c3050bc95db2d3ff21583" +checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" dependencies = [ "bytes", "futures-core", @@ -14452,7 +14452,7 @@ dependencies = [ "tokio", "tokio-stream", "tokio-tungstenite", - "tokio-util 0.7.6", + "tokio-util 0.7.7", "tower-service", "tracing", ] diff --git a/runtime/src/assets.rs b/runtime/src/assets.rs index a3fae3031..1acd26f75 100644 --- a/runtime/src/assets.rs +++ b/runtime/src/assets.rs @@ -150,7 +150,8 @@ impl TryFromSymbol for CurrencyId { id if id == KSM.symbol() => Ok(Token(KSM)), id if id == KBTC.symbol() => Ok(Token(KBTC)), id if id == KINT.symbol() => Ok(Token(KINT)), - id if id.chars().nth(0) == Some(LEND_TOKEN_SYMBOL_PREFIX) => { + // Does the first character match the lend token prefix? + id if id.chars().next() == Some(LEND_TOKEN_SYMBOL_PREFIX) => { let underlying_id = Self::try_from_symbol(id[1..].to_string())?; LendingAssets::get_lend_token_id(underlying_id) } From 6d6bc799c995c54aa2e07e1e8970ff49c5500d73 Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Thu, 16 Feb 2023 14:30:43 +0100 Subject: [PATCH 08/14] chore: bump cargo lock --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 58f07d4c5..a63a0ac5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15233,12 +15233,12 @@ dependencies = [ "pkg-config", ] -[[patch.unused]] -name = "sp-serializer" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech//substrate?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" - [[patch.unused]] name = "orml-xcm" version = "0.4.1-dev" source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=24f0a8b6e04e1078f70d0437fb816337cdf4f64c#24f0a8b6e04e1078f70d0437fb816337cdf4f64c" + +[[patch.unused]] +name = "sp-serializer" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech//substrate?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" From a739d37476644416b514b9bb0b936e8b69345361 Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Thu, 16 Feb 2023 19:50:50 +0100 Subject: [PATCH 09/14] fix(runtime): keep matching if symbol is not lend token --- Cargo.lock | 10 +++++----- runtime/src/assets.rs | 19 ++++++++++++++----- runtime/src/lib.rs | 1 + runtime/src/rpc.rs | 1 - runtime/src/tests.rs | 4 ++++ 5 files changed, 24 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a63a0ac5e..58f07d4c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15233,12 +15233,12 @@ dependencies = [ "pkg-config", ] -[[patch.unused]] -name = "orml-xcm" -version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=24f0a8b6e04e1078f70d0437fb816337cdf4f64c#24f0a8b6e04e1078f70d0437fb816337cdf4f64c" - [[patch.unused]] name = "sp-serializer" version = "4.0.0-dev" source = "git+https://github.com/paritytech//substrate?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" + +[[patch.unused]] +name = "orml-xcm" +version = "0.4.1-dev" +source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=24f0a8b6e04e1078f70d0437fb816337cdf4f64c#24f0a8b6e04e1078f70d0437fb816337cdf4f64c" diff --git a/runtime/src/assets.rs b/runtime/src/assets.rs index 1acd26f75..b8adcaada 100644 --- a/runtime/src/assets.rs +++ b/runtime/src/assets.rs @@ -137,6 +137,7 @@ impl LendingAssets { /// Convert a ticker symbol into a `CurrencyId` at runtime pub trait TryFromSymbol: Sized { fn try_from_symbol(symbol: String) -> Result; + fn from_lend_token_symbol(symbol: &str) -> Option; } impl TryFromSymbol for CurrencyId { @@ -150,14 +151,22 @@ impl TryFromSymbol for CurrencyId { id if id == KSM.symbol() => Ok(Token(KSM)), id if id == KBTC.symbol() => Ok(Token(KBTC)), id if id == KINT.symbol() => Ok(Token(KINT)), - // Does the first character match the lend token prefix? - id if id.chars().next() == Some(LEND_TOKEN_SYMBOL_PREFIX) => { - let underlying_id = Self::try_from_symbol(id[1..].to_string())?; - LendingAssets::get_lend_token_id(underlying_id) - } + id if let Some(currency_id) = Self::from_lend_token_symbol(id) => + Ok(currency_id), _ => AssetRegistry::get_foreign_asset_by_symbol(uppercase_symbol), } } + + fn from_lend_token_symbol(symbol: &str) -> Option { + let uppercase_symbol = symbol.to_uppercase(); + // Does the first character match the lend token prefix? + if uppercase_symbol.as_str().chars().next() == Some(LEND_TOKEN_SYMBOL_PREFIX) { + return Self::try_from_symbol(uppercase_symbol[1..].to_string()) + .ok() + .and_then(|underlying_id| LendingAssets::get_lend_token_id(underlying_id).ok()); + } + None + } } /// Fallible operations on currencies diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index ca0a4be2a..37c0fb8e7 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -1,4 +1,5 @@ #![allow(clippy::too_many_arguments)] +#![feature(if_let_guard)] pub mod cli; diff --git a/runtime/src/rpc.rs b/runtime/src/rpc.rs index c3437046b..c7bef0e13 100644 --- a/runtime/src/rpc.rs +++ b/runtime/src/rpc.rs @@ -142,7 +142,6 @@ impl InterBtcParachain { wrapped_currency_id, }; - // TODO: refresh on registration parachain_rpc.store_assets_metadata().await?; parachain_rpc.store_lend_tokens().await?; Ok(parachain_rpc) diff --git a/runtime/src/tests.rs b/runtime/src/tests.rs index 6e24d53d5..d33d9dcd8 100644 --- a/runtime/src/tests.rs +++ b/runtime/src/tests.rs @@ -180,6 +180,10 @@ async fn test_currency_id_parsing() { assert_eq!(CurrencyId::try_from_symbol("abc".to_string()).unwrap(), ForeignAsset(1)); assert_eq!(CurrencyId::try_from_symbol("qabC".to_string()).unwrap(), LendToken(0)); assert_eq!(CurrencyId::try_from_symbol("qkInt".to_string()).unwrap(), LendToken(1)); + // Even if matching as a qToken fails, the foreign asset should still be found. + // Matching "QQQ" will recursively call `try_from_symbol` function three more times (including + // with an empty string), because `Q` matches the lend token prefix each time. + assert_eq!(CurrencyId::try_from_symbol("qQQ".to_string()).unwrap(), ForeignAsset(3)); assert_eq!( CurrencyId::try_from_symbol("TeSt".to_string()).unwrap(), ForeignAsset(2) From a9e2fda84470bbb1a8ba437b99617b1da7adff12 Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Fri, 17 Feb 2023 13:36:56 +0100 Subject: [PATCH 10/14] chore(runtime): remove `name()` currency trait fn --- runtime/src/assets.rs | 19 ------------------- runtime/src/rpc.rs | 2 +- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/runtime/src/assets.rs b/runtime/src/assets.rs index b8adcaada..2606ecaf1 100644 --- a/runtime/src/assets.rs +++ b/runtime/src/assets.rs @@ -14,9 +14,6 @@ lazy_static! { /// The symbol of Lend Tokens is the symbol of their underlying currency, /// prefixed by `Q`. Example: `QDOT` is the `DOT` lend token symbol. const LEND_TOKEN_SYMBOL_PREFIX: char = 'Q'; -/// The name of Lend Tokens is the name of their underlying currency, -/// prefixed by `Lend`. Example: `LendPolkadot` is the `Polkadot` lend token name. -const LEND_TOKEN_NAME_PREFIX: &str = "Lend"; #[derive(Debug, Clone, Default)] pub struct AssetRegistry { @@ -171,26 +168,12 @@ impl TryFromSymbol for CurrencyId { /// Fallible operations on currencies pub trait RuntimeCurrencyInfo { - fn name(&self) -> Result; fn symbol(&self) -> Result; fn decimals(&self) -> Result; fn coingecko_id(&self) -> Result; } impl RuntimeCurrencyInfo for CurrencyId { - fn name(&self) -> Result { - match self { - CurrencyId::Token(token_symbol) => Ok(token_symbol.name().to_string()), - CurrencyId::ForeignAsset(foreign_asset_id) => AssetRegistry::get_asset_metadata_by_id(*foreign_asset_id) - .and_then(|asset_metadata| String::from_utf8(asset_metadata.name).map_err(|_| Error::InvalidCurrency)), - CurrencyId::LendToken(id) => { - let underlying_currency = LendingAssets::get_underlying_id(CurrencyId::LendToken(*id))?; - Ok(format!("{}{}", LEND_TOKEN_NAME_PREFIX, underlying_currency.name()?)) - } - _ => Err(Error::TokenUnsupported), - } - } - fn symbol(&self) -> Result { match self { CurrencyId::Token(token_symbol) => Ok(token_symbol.symbol().to_string()), @@ -268,7 +251,6 @@ mod tests { #[test] fn should_get_runtime_info_for_token_symbol() -> Result<(), Error> { - assert_eq!(Token(DOT).name()?, "Polkadot"); assert_eq!(Token(DOT).symbol()?, "DOT"); assert_eq!(Token(DOT).decimals()?, 10); Ok(()) @@ -311,7 +293,6 @@ mod tests { }, )?; - assert_eq!(ForeignAsset(0).name()?, "Asset 1"); assert_eq!(ForeignAsset(0).symbol()?, "AST1"); assert_eq!(ForeignAsset(0).decimals()?, 10); Ok(()) diff --git a/runtime/src/rpc.rs b/runtime/src/rpc.rs index c7bef0e13..9c75b0c27 100644 --- a/runtime/src/rpc.rs +++ b/runtime/src/rpc.rs @@ -40,7 +40,7 @@ const DEFAULT_PAGE_SIZE: u32 = 10; /// Keys in storage maps are prefixed by two `twox_128` hashes: the pallet name and the /// storage item names. Then, assuming the map uses the `Blake2_128Concat` hasher, the layout /// looks as follows: -/// `twox_128("PalletName") ++ twox_128("ItemName") ++ Blake2_128Concat(key) ++ key` +/// `twox_128("PalletName") ++ twox_128("ItemName") ++ Blake2_128(key) ++ key` /// So to get the actual value of the key from a raw key, we need to ignore the first /// `3 * 128 / 8` bytes, or `48` bytes. const STORAGE_KEY_HASH_PREFIX_LENGTH: usize = 48; From 46f13d49f36609c7b3c80160b6a952647469224c Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Mon, 20 Feb 2023 13:56:49 +0100 Subject: [PATCH 11/14] chore(runtime): refactor stoeage key decoding --- Cargo.lock | 10 +++---- runtime/src/rpc.rs | 71 ++++++++++++++++++++++++++++++-------------- runtime/src/types.rs | 5 ++++ 3 files changed, 58 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 58f07d4c5..a63a0ac5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15233,12 +15233,12 @@ dependencies = [ "pkg-config", ] -[[patch.unused]] -name = "sp-serializer" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech//substrate?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" - [[patch.unused]] name = "orml-xcm" version = "0.4.1-dev" source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=24f0a8b6e04e1078f70d0437fb816337cdf4f64c#24f0a8b6e04e1078f70d0437fb816337cdf4f64c" + +[[patch.unused]] +name = "sp-serializer" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech//substrate?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" diff --git a/runtime/src/rpc.rs b/runtime/src/rpc.rs index 9c75b0c27..a6460691f 100644 --- a/runtime/src/rpc.rs +++ b/runtime/src/rpc.rs @@ -36,14 +36,12 @@ const BLOCK_WAIT_TIMEOUT: Duration = Duration::from_secs(6); // number of storage entries to fetch at a time const DEFAULT_PAGE_SIZE: u32 = 10; -// TODO: Convert to a utility function /// Keys in storage maps are prefixed by two `twox_128` hashes: the pallet name and the -/// storage item names. Then, assuming the map uses the `Blake2_128Concat` hasher, the layout +/// storage item names. Then, depending on the `hash_fn` hasher the map uses, the layout /// looks as follows: -/// `twox_128("PalletName") ++ twox_128("ItemName") ++ Blake2_128(key) ++ key` -/// So to get the actual value of the key from a raw key, we need to ignore the first -/// `3 * 128 / 8` bytes, or `48` bytes. -const STORAGE_KEY_HASH_PREFIX_LENGTH: usize = 48; +/// `twox_128("PalletName") ++ twox_128("ItemName") ++ hash_fn(key) ++ key` +const BLAKE2_128_HASH_PREFIX_LENGTH: usize = 48; +const TWOX_64_HASH_PREFIX_LENGTH: usize = 40; // sanity check to be sure that testing-utils is not accidentally selected #[cfg(all( @@ -711,6 +709,14 @@ impl InterBtcParachain { .await?; Ok(()) } + + fn strip_blake2_key_prefix(raw_key: &[u8]) -> &[u8] { + &raw_key[BLAKE2_128_HASH_PREFIX_LENGTH..] + } + + fn strip_twox64_key_prefix(raw_key: &[u8]) -> &[u8] { + &raw_key[TWOX_64_HASH_PREFIX_LENGTH..] + } } #[async_trait] @@ -733,6 +739,16 @@ pub trait UtilFuncs { async fn get_foreign_asset_metadata(&self, id: u32) -> Result; async fn get_lend_tokens(&self) -> Result, Error>; + + async fn get_decoded_storage_keys( + &self, + key_addr: KeyStorageAddress, + get_raw_key: F, + ) -> Result, Error> + where + T: Decode + Send + 'static, + U: Decode + Send, + F: Fn(&[u8]) -> &[u8] + Send; } #[async_trait] @@ -758,9 +774,17 @@ impl UtilFuncs for InterBtcParachain { &vault_id.account_id == self.get_account_id() } - async fn get_foreign_assets_metadata(&self) -> Result, Error> { + async fn get_decoded_storage_keys( + &self, + key_addr: KeyStorageAddress, + get_raw_key: F, + ) -> Result, Error> + where + T: Decode + Send + 'static, + U: Decode + Send, + F: Fn(&[u8]) -> &[u8] + Send, + { let head = self.get_finalized_block_hash().await?; - let key_addr = metadata::storage().asset_registry().metadata_root(); let mut iter = self.api.storage().iter(key_addr, DEFAULT_PAGE_SIZE, head).await?; let mut ret = Vec::new(); @@ -768,28 +792,29 @@ impl UtilFuncs for InterBtcParachain { let raw_key = key.0.clone(); // last bytes are the raw key - let mut key = &raw_key[raw_key.len() - 4..]; + let mut key = get_raw_key(raw_key.as_slice()); - let decoded_key: u32 = Decode::decode(&mut key)?; + let decoded_key = U::decode(&mut key)?; ret.push((decoded_key, value)); } Ok(ret) } + async fn get_foreign_assets_metadata(&self) -> Result, Error> { + let key_addr = metadata::storage().asset_registry().metadata_root(); + self.get_decoded_storage_keys(key_addr, Self::strip_twox64_key_prefix) + .await + } + async fn get_lend_tokens(&self) -> Result, Error> { - let head = self.get_finalized_block_hash().await?; let key_addr = metadata::storage().loans().markets_root(); - let mut iter = self.api.storage().iter(key_addr, DEFAULT_PAGE_SIZE, head).await?; - - let mut ret = Vec::new(); - while let Some((key, value)) = iter.next().await? { - let raw_key = key.0.clone(); - - let mut key = &raw_key[STORAGE_KEY_HASH_PREFIX_LENGTH..]; - - let decoded_key: CurrencyId = Decode::decode(&mut key)?; - ret.push((decoded_key, value.lend_token_id)); - } + let markets = self + .get_decoded_storage_keys::<_, CurrencyId, _>(key_addr, Self::strip_blake2_key_prefix) + .await?; + let ret = markets + .into_iter() + .map(|(underlying_currency_id, market)| (underlying_currency_id, market.lend_token_id)) + .collect(); Ok(ret) } @@ -1275,7 +1300,7 @@ impl IssuePallet for InterBtcParachain { if request.status == IssueRequestStatus::Pending && request.opentime + issue_period > current_height { let key_hash = issue_id.0.as_slice(); // last bytes are the raw key - let key = &key_hash[key_hash.len() - 32..]; + let key = Self::strip_blake2_key_prefix(key_hash); issue_requests.push((H256::from_slice(key), request)); } } diff --git a/runtime/src/types.rs b/runtime/src/types.rs index 662015712..9ce44600b 100644 --- a/runtime/src/types.rs +++ b/runtime/src/types.rs @@ -1,6 +1,10 @@ use crate::{metadata, Config, InterBtcRuntime, RuntimeCurrencyInfo, SS58_PREFIX}; pub use metadata_aliases::*; pub use subxt::ext::sp_core::{crypto::Ss58Codec, sr25519::Pair as KeyPair}; +use subxt::{ + metadata::DecodeStaticType, + storage::{address::Yes, StaticStorageAddress}, +}; pub use primitives::{ CurrencyId, @@ -79,6 +83,7 @@ mod metadata_aliases { }; pub type AssetMetadata = GenericAssetMetadata; pub type LendingMarket = metadata::runtime_types::loans::types::Market; + pub type KeyStorageAddress = StaticStorageAddress, (), (), Yes>; pub use metadata::runtime_types::{ btc_relay::pallet::Error as BtcRelayPalletError, frame_system::pallet::Error as SystemPalletError, From 49b7676c94574ef51b2b083809c2f3baeb1d0c33 Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Mon, 20 Feb 2023 14:28:49 +0100 Subject: [PATCH 12/14] fix: compilation flags for qtoken vault --- Cargo.lock | 24 ++++++++++++------------ runtime/src/rpc.rs | 20 ++++++++++++++++++++ runtime/src/types.rs | 11 ++++++++++- vault/src/system.rs | 8 ++++++++ 4 files changed, 50 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a63a0ac5e..dea98e109 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -786,9 +786,9 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bstr" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f0778972c64420fdedc63f09919c8a88bda7b25135357fd25a5d9f3257e832" +checksum = "5ffdb39cb703212f3c11973452c2861b972f757b021158f3516ba10f2fa8b2c1" dependencies = [ "memchr", "serde", @@ -1053,9 +1053,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.4.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" +checksum = "77ed9a53e5d4d9c573ae844bfac6872b159cb1d1585a83b29e7a64b7eef7332a" dependencies = [ "glob", "libc", @@ -3870,9 +3870,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", @@ -5767,9 +5767,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "2af2c65375e552a67fe3829ca63e8a7c27a378a62824594f43b2851d682b5ec2" dependencies = [ "libc", ] @@ -11850,9 +11850,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg", ] @@ -13703,9 +13703,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" +checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313" dependencies = [ "futures-core", "pin-project-lite 0.2.9", diff --git a/runtime/src/rpc.rs b/runtime/src/rpc.rs index a6460691f..125b8fdaf 100644 --- a/runtime/src/rpc.rs +++ b/runtime/src/rpc.rs @@ -141,6 +141,10 @@ impl InterBtcParachain { }; parachain_rpc.store_assets_metadata().await?; + #[cfg(any( + feature = "parachain-metadata-kintsugi-testnet", + feature = "parachain-metadata-interlay-testnet" + ))] parachain_rpc.store_lend_tokens().await?; Ok(parachain_rpc) } @@ -628,6 +632,10 @@ impl InterBtcParachain { AssetRegistry::extend(self.get_foreign_assets_metadata().await?) } + #[cfg(any( + feature = "parachain-metadata-kintsugi-testnet", + feature = "parachain-metadata-interlay-testnet" + ))] pub async fn store_lend_tokens(&self) -> Result<(), Error> { let lend_tokens = self.get_lend_tokens().await?; LendingAssets::extend(lend_tokens) @@ -658,6 +666,10 @@ impl InterBtcParachain { } /// Cache new markets and updates + #[cfg(any( + feature = "parachain-metadata-kintsugi-testnet", + feature = "parachain-metadata-interlay-testnet" + ))] pub async fn listen_for_lending_markets(&self) -> Result<(), Error> { futures::future::try_join( self.on_event::( @@ -738,6 +750,10 @@ pub trait UtilFuncs { async fn get_foreign_asset_metadata(&self, id: u32) -> Result; + #[cfg(any( + feature = "parachain-metadata-kintsugi-testnet", + feature = "parachain-metadata-interlay-testnet" + ))] async fn get_lend_tokens(&self) -> Result, Error>; async fn get_decoded_storage_keys( @@ -806,6 +822,10 @@ impl UtilFuncs for InterBtcParachain { .await } + #[cfg(any( + feature = "parachain-metadata-kintsugi-testnet", + feature = "parachain-metadata-interlay-testnet" + ))] async fn get_lend_tokens(&self) -> Result, Error> { let key_addr = metadata::storage().loans().markets_root(); let markets = self diff --git a/runtime/src/types.rs b/runtime/src/types.rs index 9ce44600b..88e2313dc 100644 --- a/runtime/src/types.rs +++ b/runtime/src/types.rs @@ -50,10 +50,15 @@ mod metadata_aliases { pub use metadata::{ asset_registry::events::{RegisteredAsset as RegisteredAssetEvent, UpdatedAsset as UpdatedAssetEvent}, - loans::events::{NewMarket as NewMarketEvent, UpdatedMarket as UpdatedMarketEvent}, oracle::events::FeedValues as FeedValuesEvent, }; + #[cfg(any( + feature = "parachain-metadata-kintsugi-testnet", + feature = "parachain-metadata-interlay-testnet" + ))] + pub use metadata::loans::events::{NewMarket as NewMarketEvent, UpdatedMarket as UpdatedMarketEvent}; + pub use metadata::issue::events::{ CancelIssue as CancelIssueEvent, ExecuteIssue as ExecuteIssueEvent, RequestIssue as RequestIssueEvent, }; @@ -82,6 +87,10 @@ mod metadata_aliases { orml_traits::asset_registry::AssetMetadata as GenericAssetMetadata, }; pub type AssetMetadata = GenericAssetMetadata; + #[cfg(any( + feature = "parachain-metadata-kintsugi-testnet", + feature = "parachain-metadata-interlay-testnet" + ))] pub type LendingMarket = metadata::runtime_types::loans::types::Market; pub type KeyStorageAddress = StaticStorageAddress, (), (), Yes>; diff --git a/vault/src/system.rs b/vault/src/system.rs index a88091a75..0021d68c6 100644 --- a/vault/src/system.rs +++ b/vault/src/system.rs @@ -604,6 +604,10 @@ impl VaultService { let listen_for_registered_assets = |rpc: InterBtcParachain| async move { rpc.listen_for_registered_assets().await }; + #[cfg(any( + feature = "parachain-metadata-kintsugi-testnet", + feature = "parachain-metadata-interlay-testnet" + ))] let listen_for_lending_markets = |rpc: InterBtcParachain| async move { rpc.listen_for_lending_markets().await }; let listen_for_fee_rate_estimate_changes = @@ -615,6 +619,10 @@ impl VaultService { "Registered Asset Listener", run(listen_for_registered_assets(self.btc_parachain.clone())), ), + #[cfg(any( + feature = "parachain-metadata-kintsugi-testnet", + feature = "parachain-metadata-interlay-testnet" + ))] ( "Lending Market Listener", run(listen_for_lending_markets(self.btc_parachain.clone())), From e004a4beea95176212d864ba349d4a94ada9108f Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Mon, 20 Feb 2023 15:15:44 +0100 Subject: [PATCH 13/14] chore: fix mock errors --- runtime/src/rpc.rs | 8 ++++---- vault/src/cancellation.rs | 13 ++++++++++++- vault/src/execution.rs | 14 ++++++++++++-- vault/src/metrics.rs | 12 +++++++++++- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/runtime/src/rpc.rs b/runtime/src/rpc.rs index 125b8fdaf..e81c71fb0 100644 --- a/runtime/src/rpc.rs +++ b/runtime/src/rpc.rs @@ -763,8 +763,8 @@ pub trait UtilFuncs { ) -> Result, Error> where T: Decode + Send + 'static, - U: Decode + Send, - F: Fn(&[u8]) -> &[u8] + Send; + U: Decode + Send + 'static, + F: Fn(&[u8]) -> &[u8] + Send + 'static; } #[async_trait] @@ -797,8 +797,8 @@ impl UtilFuncs for InterBtcParachain { ) -> Result, Error> where T: Decode + Send + 'static, - U: Decode + Send, - F: Fn(&[u8]) -> &[u8] + Send, + U: Decode + Send + 'static, + F: Fn(&[u8]) -> &[u8] + Send + 'static, { let head = self.get_finalized_block_hash().await?; let mut iter = self.api.storage().iter(key_addr, DEFAULT_PAGE_SIZE, head).await?; diff --git a/vault/src/cancellation.rs b/vault/src/cancellation.rs index 4272c0be5..405164753 100644 --- a/vault/src/cancellation.rs +++ b/vault/src/cancellation.rs @@ -319,9 +319,11 @@ mod tests { use async_trait::async_trait; use futures::channel::mpsc; use jsonrpc_core::serde_json::{Map, Value}; + use parity_scale_codec::Decode; use runtime::{ AccountId, AssetMetadata, BtcAddress, BtcPublicKey, CurrencyId, ErrorCode, InterBtcIssueRequest, - InterBtcReplaceRequest, IssueRequestStatus, RequestIssueEvent, StatusCode, Token, VaultId, DOT, IBTC, + InterBtcReplaceRequest, IssueRequestStatus, KeyStorageAddress, RequestIssueEvent, StatusCode, Token, VaultId, + DOT, IBTC, }; use std::collections::BTreeSet; @@ -374,6 +376,15 @@ mod tests { async fn get_foreign_assets_metadata(&self) -> Result, RuntimeError>; async fn get_foreign_asset_metadata(&self, id: u32) -> Result; async fn get_lend_tokens(&self) -> Result, RuntimeError>; + async fn get_decoded_storage_keys( + &self, + key_addr: KeyStorageAddress, + get_raw_key: F, + ) -> Result, RuntimeError> + where + T: Decode + Send + 'static, + U: Decode + Send + 'static, + F: Fn(&[u8]) -> &[u8] + Send + 'static; } #[async_trait] diff --git a/vault/src/execution.rs b/vault/src/execution.rs index 847a34b4f..b5e85435a 100644 --- a/vault/src/execution.rs +++ b/vault/src/execution.rs @@ -610,10 +610,11 @@ mod tests { PrivateKey, PublicKey, Transaction, TransactionMetadata, Txid, }; use jsonrpc_core::serde_json::{Map, Value}; + use parity_scale_codec::Decode; use runtime::{ sp_core::H160, AccountId, AssetMetadata, BitcoinBlockHeight, BlockNumber, BtcPublicKey, CurrencyId, - Error as RuntimeError, ErrorCode, FeeRateUpdateReceiver, InterBtcRichBlockHeader, InterBtcVault, OracleKey, - RawBlockHeader, StatusCode, Token, DOT, IBTC, + Error as RuntimeError, ErrorCode, FeeRateUpdateReceiver, InterBtcRichBlockHeader, InterBtcVault, + KeyStorageAddress, OracleKey, RawBlockHeader, StatusCode, Token, DOT, IBTC, }; use std::{collections::BTreeSet, sync::Arc}; @@ -643,6 +644,15 @@ mod tests { async fn get_foreign_assets_metadata(&self) -> Result, RuntimeError>; async fn get_foreign_asset_metadata(&self, id: u32) -> Result; async fn get_lend_tokens(&self) -> Result, RuntimeError>; + async fn get_decoded_storage_keys( + &self, + key_addr: KeyStorageAddress, + get_raw_key: F, + ) -> Result, RuntimeError> + where + T: Decode + Send + 'static, + U: Decode + Send + 'static, + F: Fn(&[u8]) -> &[u8] + Send + 'static; } #[async_trait] pub trait VaultRegistryPallet { diff --git a/vault/src/metrics.rs b/vault/src/metrics.rs index 0379d23c8..48aef4c27 100644 --- a/vault/src/metrics.rs +++ b/vault/src/metrics.rs @@ -681,10 +681,11 @@ mod tests { PrivateKey, PublicKey, SatPerVbyte, Transaction, TransactionMetadata, Txid, }; use jsonrpc_core::serde_json::{Map, Value}; + use parity_scale_codec::Decode; use runtime::{ AccountId, AssetMetadata, Balance, BlockNumber, BtcAddress, BtcPublicKey, CurrencyId, Error as RuntimeError, ErrorCode, InterBtcIssueRequest, InterBtcRedeemRequest, InterBtcReplaceRequest, InterBtcVault, - RequestIssueEvent, StatusCode, Token, VaultId, VaultStatus, DOT, H256, IBTC, INTR, + KeyStorageAddress, RequestIssueEvent, StatusCode, Token, VaultId, VaultStatus, DOT, H256, IBTC, INTR, }; use service::DynBitcoinCoreApi; use std::collections::BTreeSet; @@ -702,6 +703,15 @@ mod tests { async fn get_foreign_assets_metadata(&self) -> Result, RuntimeError>; async fn get_foreign_asset_metadata(&self, id: u32) -> Result; async fn get_lend_tokens(&self) -> Result, RuntimeError>; + async fn get_decoded_storage_keys( + &self, + key_addr: KeyStorageAddress, + get_raw_key: F, + ) -> Result, RuntimeError> + where + T: Decode + Send + 'static, + U: Decode + Send + 'static, + F: Fn(&[u8]) -> &[u8] + Send + 'static; } #[async_trait] From fb6117de4455e0d087fad0cd884b81c4fef985f4 Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Wed, 22 Feb 2023 12:35:31 +0100 Subject: [PATCH 14/14] chore(runtime): simplify `get_decoded_storage_keys` signature --- runtime/src/rpc.rs | 69 +++++++++++++++++---------------------- runtime/src/types.rs | 5 +++ vault/src/cancellation.rs | 9 ----- vault/src/execution.rs | 9 ----- vault/src/metrics.rs | 9 ----- 5 files changed, 35 insertions(+), 66 deletions(-) diff --git a/runtime/src/rpc.rs b/runtime/src/rpc.rs index e81c71fb0..08de1a174 100644 --- a/runtime/src/rpc.rs +++ b/runtime/src/rpc.rs @@ -722,6 +722,34 @@ impl InterBtcParachain { Ok(()) } + async fn get_decoded_storage_keys( + &self, + key_addr: KeyStorageAddress, + hasher: StorageMapHasher, + ) -> Result, Error> + where + T: Decode + Send + 'static, + U: Decode + Send + 'static, + { + let head = self.get_finalized_block_hash().await?; + let mut iter = self.api.storage().iter(key_addr, DEFAULT_PAGE_SIZE, head).await?; + + let mut ret = Vec::new(); + while let Some((key, value)) = iter.next().await? { + let raw_key = key.0.clone(); + + // last bytes are the raw key + let mut key = match hasher { + StorageMapHasher::Blake2_128 => Self::strip_blake2_key_prefix(raw_key.as_slice()), + StorageMapHasher::Twox_64 => Self::strip_twox64_key_prefix(raw_key.as_slice()), + }; + + let decoded_key = U::decode(&mut key)?; + ret.push((decoded_key, value)); + } + Ok(ret) + } + fn strip_blake2_key_prefix(raw_key: &[u8]) -> &[u8] { &raw_key[BLAKE2_128_HASH_PREFIX_LENGTH..] } @@ -755,16 +783,6 @@ pub trait UtilFuncs { feature = "parachain-metadata-interlay-testnet" ))] async fn get_lend_tokens(&self) -> Result, Error>; - - async fn get_decoded_storage_keys( - &self, - key_addr: KeyStorageAddress, - get_raw_key: F, - ) -> Result, Error> - where - T: Decode + Send + 'static, - U: Decode + Send + 'static, - F: Fn(&[u8]) -> &[u8] + Send + 'static; } #[async_trait] @@ -790,36 +808,9 @@ impl UtilFuncs for InterBtcParachain { &vault_id.account_id == self.get_account_id() } - async fn get_decoded_storage_keys( - &self, - key_addr: KeyStorageAddress, - get_raw_key: F, - ) -> Result, Error> - where - T: Decode + Send + 'static, - U: Decode + Send + 'static, - F: Fn(&[u8]) -> &[u8] + Send + 'static, - { - let head = self.get_finalized_block_hash().await?; - let mut iter = self.api.storage().iter(key_addr, DEFAULT_PAGE_SIZE, head).await?; - - let mut ret = Vec::new(); - while let Some((key, value)) = iter.next().await? { - let raw_key = key.0.clone(); - - // last bytes are the raw key - let mut key = get_raw_key(raw_key.as_slice()); - - let decoded_key = U::decode(&mut key)?; - ret.push((decoded_key, value)); - } - Ok(ret) - } - async fn get_foreign_assets_metadata(&self) -> Result, Error> { let key_addr = metadata::storage().asset_registry().metadata_root(); - self.get_decoded_storage_keys(key_addr, Self::strip_twox64_key_prefix) - .await + self.get_decoded_storage_keys(key_addr, StorageMapHasher::Twox_64).await } #[cfg(any( @@ -829,7 +820,7 @@ impl UtilFuncs for InterBtcParachain { async fn get_lend_tokens(&self) -> Result, Error> { let key_addr = metadata::storage().loans().markets_root(); let markets = self - .get_decoded_storage_keys::<_, CurrencyId, _>(key_addr, Self::strip_blake2_key_prefix) + .get_decoded_storage_keys::<_, CurrencyId>(key_addr, StorageMapHasher::Blake2_128) .await?; let ret = markets .into_iter() diff --git a/runtime/src/types.rs b/runtime/src/types.rs index 88e2313dc..5204a63d5 100644 --- a/runtime/src/types.rs +++ b/runtime/src/types.rs @@ -31,6 +31,11 @@ pub type BtcAddress = module_btc_relay::BtcAddress; pub type FixedU128 = sp_arithmetic::FixedU128; +pub(crate) enum StorageMapHasher { + Blake2_128, + Twox_64, +} + mod metadata_aliases { use super::*; diff --git a/vault/src/cancellation.rs b/vault/src/cancellation.rs index 405164753..5da2bd9f9 100644 --- a/vault/src/cancellation.rs +++ b/vault/src/cancellation.rs @@ -376,15 +376,6 @@ mod tests { async fn get_foreign_assets_metadata(&self) -> Result, RuntimeError>; async fn get_foreign_asset_metadata(&self, id: u32) -> Result; async fn get_lend_tokens(&self) -> Result, RuntimeError>; - async fn get_decoded_storage_keys( - &self, - key_addr: KeyStorageAddress, - get_raw_key: F, - ) -> Result, RuntimeError> - where - T: Decode + Send + 'static, - U: Decode + Send + 'static, - F: Fn(&[u8]) -> &[u8] + Send + 'static; } #[async_trait] diff --git a/vault/src/execution.rs b/vault/src/execution.rs index b5e85435a..a56c28cea 100644 --- a/vault/src/execution.rs +++ b/vault/src/execution.rs @@ -644,15 +644,6 @@ mod tests { async fn get_foreign_assets_metadata(&self) -> Result, RuntimeError>; async fn get_foreign_asset_metadata(&self, id: u32) -> Result; async fn get_lend_tokens(&self) -> Result, RuntimeError>; - async fn get_decoded_storage_keys( - &self, - key_addr: KeyStorageAddress, - get_raw_key: F, - ) -> Result, RuntimeError> - where - T: Decode + Send + 'static, - U: Decode + Send + 'static, - F: Fn(&[u8]) -> &[u8] + Send + 'static; } #[async_trait] pub trait VaultRegistryPallet { diff --git a/vault/src/metrics.rs b/vault/src/metrics.rs index 48aef4c27..f596d0609 100644 --- a/vault/src/metrics.rs +++ b/vault/src/metrics.rs @@ -703,15 +703,6 @@ mod tests { async fn get_foreign_assets_metadata(&self) -> Result, RuntimeError>; async fn get_foreign_asset_metadata(&self, id: u32) -> Result; async fn get_lend_tokens(&self) -> Result, RuntimeError>; - async fn get_decoded_storage_keys( - &self, - key_addr: KeyStorageAddress, - get_raw_key: F, - ) -> Result, RuntimeError> - where - T: Decode + Send + 'static, - U: Decode + Send + 'static, - F: Fn(&[u8]) -> &[u8] + Send + 'static; } #[async_trait]