Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

234 refactor dia implementation #387

Merged
merged 41 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
6336a7f
Add re-usable implementation of DIA mock
ebma Aug 21, 2023
1aab6cd
Deduplicate redeem
ebma Aug 23, 2023
d6d75e2
Deduplicate issue
ebma Aug 23, 2023
ed42ca9
Deduplicate nomination
ebma Aug 23, 2023
4179ce9
Deduplicate replace
ebma Aug 23, 2023
91435b0
Deduplicate vault registry
ebma Aug 23, 2023
76f3d04
Change cfg macros
ebma Aug 24, 2023
ff62bd3
Remove `benchmark_utils.rs`
ebma Aug 24, 2023
dd02b8f
WIP
ebma Aug 24, 2023
e2723ff
Fix compilation of runtime _without_ features
ebma Aug 24, 2023
7271b17
Implement oracle mock with no_std dependencies
ebma Aug 24, 2023
0ce16d9
Remove unused `spin` dependency from testchain runtime
ebma Aug 24, 2023
be03684
Amend fix
ebma Aug 24, 2023
d67244a
Re-add cfg_attr
ebma Aug 24, 2023
a3f0022
Fix mock and test cases
ebma Aug 24, 2023
447b712
Cleanup code
ebma Sep 1, 2023
582e64c
Improve `derive_key` function
ebma Sep 1, 2023
13fd08b
Try to fix vault-registry tests
ebma Sep 1, 2023
de0c453
Use `#[serial]` in vault registry tests
ebma Sep 5, 2023
46ca2ab
Add `Mutex` lock to oracle mock
ebma Sep 6, 2023
e03835b
Acquire lock before executing each vault-registry test
ebma Sep 6, 2023
f147337
Revert "Use `#[serial]` in vault registry tests"
ebma Sep 6, 2023
3e5bf4c
WIP
ebma Sep 7, 2023
aee2cda
Use `OnceBox`
ebma Sep 7, 2023
7060cd6
Fix remaining race conditions in vault registry tests
ebma Sep 7, 2023
6c172d9
Fix dependency declaration
ebma Sep 7, 2023
e4a2fd8
Refactor imports
ebma Sep 7, 2023
28ab431
Refactor mock logic into separate files
ebma Sep 7, 2023
ca82896
Declare test dependencies as `optional`
ebma Sep 7, 2023
0e9dff5
Remove `#[serial]` from oracle tests again
ebma Sep 7, 2023
760e28d
Remove `sp-tracing` again
ebma Sep 7, 2023
c2d84b1
Final refactoring
ebma Sep 7, 2023
f95ece5
Rename type and structs
ebma Sep 7, 2023
7999480
Merge branch 'main' into 234-refactor-dia-implementation
ebma Sep 7, 2023
bc9dcae
Merge branch 'main' into 234-refactor-dia-implementation
ebma Oct 5, 2023
b5c4d3c
Rename `clear_values()`
ebma Oct 5, 2023
fccdd9e
Rename `acquire_lock()`
ebma Oct 5, 2023
42f17b6
Rename `feed_values()`
ebma Oct 5, 2023
a164700
Merge branch 'main' into 234-refactor-dia-implementation
ebma Oct 12, 2023
4776e5d
Remove `clone()`
ebma Oct 12, 2023
a1e6d0b
Merge branch 'main' into 234-refactor-dia-implementation
ebma Oct 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

77 changes: 39 additions & 38 deletions clients/vault/src/replace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,47 +248,48 @@ mod tests {
}

mockall::mock! {
Provider {}

#[async_trait]
pub trait VaultRegistryPallet {
async fn get_vault(&self, vault_id: &VaultId) -> Result<SpacewalkVault, RuntimeError>;
async fn get_vaults_by_account_id(&self, account_id: &AccountId) -> Result<Vec<VaultId>, RuntimeError>;
async fn get_all_vaults(&self) -> Result<Vec<SpacewalkVault>, RuntimeError>;
async fn register_vault(&self, vault_id: &VaultId, collateral: u128) -> Result<(), RuntimeError>;
async fn deposit_collateral(&self, vault_id: &VaultId, amount: u128) -> Result<(), RuntimeError>;
async fn withdraw_collateral(&self, vault_id: &VaultId, amount: u128) -> Result<(), RuntimeError>;
async fn get_public_key(&self) -> Result<Option<StellarPublicKeyRaw>, RuntimeError>;
async fn register_public_key(&self, public_key: StellarPublicKeyRaw) -> Result<(), RuntimeError>;
async fn get_required_collateral_for_wrapped(&self, amount: u128, wrapped_currency: CurrencyId, collateral_currency: CurrencyId) -> Result<u128, RuntimeError>;
async fn get_required_collateral_for_vault(&self, vault_id: VaultId) -> Result<u128, RuntimeError>;
async fn get_vault_total_collateral(&self, vault_id: VaultId) -> Result<u128, RuntimeError>;
async fn get_collateralization_from_vault(&self, vault_id: VaultId, only_issued: bool) -> Result<u128, RuntimeError>;
}
Provider {}

#[async_trait]
pub trait VaultRegistryPallet {
async fn get_vault(&self, vault_id: &VaultId) -> Result<SpacewalkVault, RuntimeError>;
async fn get_vaults_by_account_id(&self, account_id: &AccountId) -> Result<Vec<VaultId>, RuntimeError>;
async fn get_all_vaults(&self) -> Result<Vec<SpacewalkVault>, RuntimeError>;
async fn register_vault(&self, vault_id: &VaultId, collateral: u128) -> Result<(), RuntimeError>;
async fn deposit_collateral(&self, vault_id: &VaultId, amount: u128) -> Result<(), RuntimeError>;
async fn withdraw_collateral(&self, vault_id: &VaultId, amount: u128) -> Result<(), RuntimeError>;
async fn get_public_key(&self) -> Result<Option<StellarPublicKeyRaw>, RuntimeError>;
async fn register_public_key(&self, public_key: StellarPublicKeyRaw) -> Result<(), RuntimeError>;
async fn get_required_collateral_for_wrapped(&self, amount: u128, wrapped_currency: CurrencyId, collateral_currency: CurrencyId) -> Result<u128, RuntimeError>;
async fn get_required_collateral_for_vault(&self, vault_id: VaultId) -> Result<u128, RuntimeError>;
async fn get_vault_total_collateral(&self, vault_id: VaultId) -> Result<u128, RuntimeError>;
async fn get_collateralization_from_vault(&self, vault_id: VaultId, only_issued: bool) -> Result<u128, RuntimeError>;
}

#[async_trait]
pub trait ReplacePallet {
async fn request_replace(&self, vault_id: &VaultId, amount: u128) -> Result<(), RuntimeError>;
async fn withdraw_replace(&self, vault_id: &VaultId, amount: u128) -> Result<(), RuntimeError>;
async fn accept_replace(&self, new_vault: &VaultId, old_vault: &VaultId, amount: u128, collateral: u128, stellar_address: StellarPublicKeyRaw) -> Result<(), RuntimeError>;
async fn execute_replace(&self, replace_id: H256, tx_env: &[u8], scp_envs: &[u8], tx_set: &[u8]) -> Result<(), RuntimeError>;
async fn cancel_replace(&self, replace_id: H256) -> Result<(), RuntimeError>;
async fn get_new_vault_replace_requests(&self, account_id: AccountId) -> Result<Vec<(H256, SpacewalkReplaceRequest)>, RuntimeError>;
async fn get_old_vault_replace_requests(&self, account_id: AccountId) -> Result<Vec<(H256, SpacewalkReplaceRequest)>, RuntimeError>;
async fn get_replace_period(&self) -> Result<u32, RuntimeError>;
async fn get_replace_request(&self, replace_id: H256) -> Result<SpacewalkReplaceRequest, RuntimeError>;
async fn get_replace_dust_amount(&self) -> Result<u128, RuntimeError>;
}
#[async_trait]
pub trait ReplacePallet {
async fn request_replace(&self, vault_id: &VaultId, amount: u128) -> Result<(), RuntimeError>;
async fn withdraw_replace(&self, vault_id: &VaultId, amount: u128) -> Result<(), RuntimeError>;
async fn accept_replace(&self, new_vault: &VaultId, old_vault: &VaultId, amount: u128, collateral: u128, stellar_address: StellarPublicKeyRaw) -> Result<(), RuntimeError>;
async fn execute_replace(&self, replace_id: H256, tx_env: &[u8], scp_envs: &[u8], tx_set: &[u8]) -> Result<(), RuntimeError>;
async fn cancel_replace(&self, replace_id: H256) -> Result<(), RuntimeError>;
async fn get_new_vault_replace_requests(&self, account_id: AccountId) -> Result<Vec<(H256, SpacewalkReplaceRequest)>, RuntimeError>;
async fn get_old_vault_replace_requests(&self, account_id: AccountId) -> Result<Vec<(H256, SpacewalkReplaceRequest)>, RuntimeError>;
async fn get_replace_period(&self) -> Result<u32, RuntimeError>;
async fn get_replace_request(&self, replace_id: H256) -> Result<SpacewalkReplaceRequest, RuntimeError>;
async fn get_replace_dust_amount(&self) -> Result<u128, RuntimeError>;
}


#[async_trait]
pub trait CollateralBalancesPallet {
async fn get_free_balance(&self, currency_id: CurrencyId) -> Result<Balance, RuntimeError>;
async fn get_native_balance_for_id(&self, id: &AccountId) -> Result<Balance, RuntimeError>;
async fn get_free_balance_for_id(&self, id: AccountId, currency_id: CurrencyId) -> Result<Balance, RuntimeError>;
async fn get_reserved_balance(&self, currency_id: CurrencyId) -> Result<Balance, RuntimeError>;
async fn get_reserved_balance_for_id(&self, id: AccountId, currency_id: CurrencyId) -> Result<Balance, RuntimeError>;
async fn transfer_to(&self, recipient: &AccountId, amount: u128, currency_id: CurrencyId) -> Result<(), RuntimeError>; }
#[async_trait]
pub trait CollateralBalancesPallet {
async fn get_free_balance(&self, currency_id: CurrencyId) -> Result<Balance, RuntimeError>;
async fn get_native_balance_for_id(&self, id: &AccountId) -> Result<Balance, RuntimeError>;
async fn get_free_balance_for_id(&self, id: AccountId, currency_id: CurrencyId) -> Result<Balance, RuntimeError>;
async fn get_reserved_balance(&self, currency_id: CurrencyId) -> Result<Balance, RuntimeError>;
async fn get_reserved_balance_for_id(&self, id: AccountId, currency_id: CurrencyId) -> Result<Balance, RuntimeError>;
async fn transfer_to(&self, recipient: &AccountId, amount: u128, currency_id: CurrencyId) -> Result<(), RuntimeError>;
}
}

impl Clone for MockProvider {
Expand Down
90 changes: 8 additions & 82 deletions pallets/issue/src/mock.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
use std::cell::RefCell;

use frame_support::{
assert_ok, parameter_types,
traits::{ConstU32, Everything, GenesisBuild},
PalletId,
};
use mocktopus::{macros::mockable, mocking::clear_mocks};
use oracle::{
dia::DiaOracleAdapter,
oracle_mock::{Data, DataKey, MockConvertMoment, MockConvertPrice, MockOracleKeyConvertor},
CoinInfo, DataFeeder, DataProvider, DiaOracle, PriceInfo, TimestampedValue,
};
use orml_currencies::BasicCurrencyAdapter;
use orml_traits::parameter_type_with_key;
use primitives::oracle::Key;
use sp_arithmetic::{FixedI128, FixedPointNumber, FixedU128};
use sp_core::H256;
use sp_runtime::{
Expand All @@ -27,6 +19,12 @@ pub use currency::{
},
Amount,
};
use oracle::{
dia::DiaOracleAdapter,
testing_utils::{
MockConvertMoment, MockConvertPrice, MockDataFeeder, MockDiaOracle, MockOracleKeyConvertor,
},
};
pub use primitives::CurrencyId;
use primitives::{AmountCompatibility, VaultCurrencyPair, VaultId};

Expand Down Expand Up @@ -289,9 +287,9 @@ impl oracle::Config for Test {
Moment,
MockOracleKeyConvertor,
MockConvertPrice,
MockConvertMoment,
MockConvertMoment<Moment>,
>;
type DataFeedProvider = DataCollector;
type DataFeeder = MockDataFeeder<AccountId, Moment>;
}

parameter_types! {
Expand Down Expand Up @@ -459,75 +457,3 @@ where
test();
});
}

thread_local! {
static COINS: RefCell<std::collections::HashMap<DataKey, Data>> = RefCell::new(std::collections::HashMap::<DataKey, Data>::new());
}

pub struct MockDiaOracle;
impl DiaOracle for MockDiaOracle {
fn get_coin_info(
blockchain: Vec<u8>,
symbol: Vec<u8>,
) -> Result<CoinInfo, sp_runtime::DispatchError> {
let key = (blockchain, symbol);
let data_key = DataKey { blockchain: key.0.clone(), symbol: key.1.clone() };
let mut result: Option<Data> = None;
COINS.with(|c| {
let r = c.borrow();

let hash_set = &*r;
let o = hash_set.get(&data_key);
match o {
Some(i) => result = Some(i.clone()),
None => {},
};
});
let Some(result) = result else {
return Err(sp_runtime::DispatchError::Other(""));
};
let mut coin_info = CoinInfo::default();
coin_info.price = result.price;
coin_info.last_update_timestamp = result.timestamp;

Ok(coin_info)
}

//Spacewalk DiaOracleAdapter does not use get_value function. There is no need to implement
// this function.
fn get_value(
_blockchain: Vec<u8>,
_symbol: Vec<u8>,
) -> Result<PriceInfo, sp_runtime::DispatchError> {
unimplemented!(
"DiaOracleAdapter implementation of DataProviderExtended does not use this function."
)
}
}

pub struct DataCollector;
//DataFeeder required to implement DataProvider trait but there no need to implement get function
impl DataProvider<Key, TimestampedValue<UnsignedFixedPoint, Moment>> for DataCollector {
fn get(_key: &Key) -> Option<TimestampedValue<UnsignedFixedPoint, Moment>> {
unimplemented!("Not required to implement DataProvider get function")
}
}
impl DataFeeder<Key, TimestampedValue<UnsignedFixedPoint, Moment>, AccountId> for DataCollector {
fn feed_value(
_who: AccountId,
key: Key,
value: TimestampedValue<UnsignedFixedPoint, Moment>,
) -> sp_runtime::DispatchResult {
let key = MockOracleKeyConvertor::convert(key).unwrap();
let r = value.value.into_inner();

let data_key = DataKey { blockchain: key.0.clone(), symbol: key.1.clone() };
let data = Data { key: data_key.clone(), price: r, timestamp: value.timestamp };

COINS.with(|coins| {
let mut r = coins.borrow_mut();
r.insert(data_key, data);
});
Ok(())
}
}
91 changes: 9 additions & 82 deletions pallets/nomination/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,26 @@ use frame_support::{
PalletId,
};
use mocktopus::{macros::mockable, mocking::clear_mocks};
use oracle::{
dia::DiaOracleAdapter,
oracle_mock::{Data, DataKey, MockConvertMoment, MockConvertPrice, MockOracleKeyConvertor},
CoinInfo, DataFeeder, DataProvider, DiaOracle, PriceInfo, TimestampedValue,
};
use orml_currencies::BasicCurrencyAdapter;
use orml_traits::parameter_type_with_key;
use primitives::oracle::Key;
use sp_arithmetic::{FixedI128, FixedU128};
use sp_core::H256;
use sp_runtime::{
testing::{Header, TestXt},
traits::{BlakeTwo256, Convert, IdentityLookup, One, Zero},
traits::{BlakeTwo256, IdentityLookup, One, Zero},
FixedPointNumber,
};
use std::cell::RefCell;

pub use currency::testing_constants::{
DEFAULT_COLLATERAL_CURRENCY, DEFAULT_NATIVE_CURRENCY, DEFAULT_WRAPPED_CURRENCY,
};
use currency::Amount;
use oracle::{
dia::DiaOracleAdapter,
testing_utils::{
MockConvertMoment, MockConvertPrice, MockDataFeeder, MockDiaOracle, MockOracleKeyConvertor,
},
};
pub use primitives::CurrencyId;
use primitives::{VaultCurrencyPair, VaultId};

Expand Down Expand Up @@ -285,9 +284,9 @@ impl oracle::Config for Test {
Moment,
MockOracleKeyConvertor,
MockConvertPrice,
MockConvertMoment,
MockConvertMoment<Moment>,
>;
type DataFeedProvider = DataCollector;
type DataFeeder = MockDataFeeder<AccountId, Moment>;
}

impl Config for Test {
Expand Down Expand Up @@ -409,75 +408,3 @@ where
test();
});
}

thread_local! {
static COINS: RefCell<std::collections::HashMap<DataKey, Data>> = RefCell::new(std::collections::HashMap::<DataKey, Data>::new());
}

pub struct MockDiaOracle;
impl DiaOracle for MockDiaOracle {
fn get_coin_info(
blockchain: Vec<u8>,
symbol: Vec<u8>,
) -> Result<CoinInfo, sp_runtime::DispatchError> {
let key = (blockchain, symbol);
let data_key = DataKey { blockchain: key.0.clone(), symbol: key.1.clone() };
let mut result: Option<Data> = None;
COINS.with(|c| {
let r = c.borrow();

let hash_set = &*r;
let o = hash_set.get(&data_key);
match o {
Some(i) => result = Some(i.clone()),
None => {},
};
});
let Some(result) = result else {
return Err(sp_runtime::DispatchError::Other(""));
};
let mut coin_info = CoinInfo::default();
coin_info.price = result.price;
coin_info.last_update_timestamp = result.timestamp;

Ok(coin_info)
}

//Spacewalk DiaOracleAdapter does not use get_value function. There is no need to implement
// this function.
fn get_value(
_blockchain: Vec<u8>,
_symbol: Vec<u8>,
) -> Result<PriceInfo, sp_runtime::DispatchError> {
unimplemented!(
"DiaOracleAdapter implementation of DataProviderExtended does not use this function."
)
}
}

pub struct DataCollector;
//DataFeeder required to implement DataProvider trait but there no need to implement get function
impl DataProvider<Key, TimestampedValue<UnsignedFixedPoint, Moment>> for DataCollector {
fn get(_key: &Key) -> Option<TimestampedValue<UnsignedFixedPoint, Moment>> {
unimplemented!("Not required to implement DataProvider get function")
}
}
impl DataFeeder<Key, TimestampedValue<UnsignedFixedPoint, Moment>, AccountId> for DataCollector {
fn feed_value(
_who: AccountId,
key: Key,
value: TimestampedValue<UnsignedFixedPoint, Moment>,
) -> sp_runtime::DispatchResult {
let key = MockOracleKeyConvertor::convert(key).unwrap();
let r = value.value.into_inner();

let data_key = DataKey { blockchain: key.0.clone(), symbol: key.1.clone() };
let data = Data { key: data_key.clone(), price: r, timestamp: value.timestamp };

COINS.with(|coins| {
let mut r = coins.borrow_mut();
r.insert(data_key, data);
});
Ok(())
}
}
12 changes: 8 additions & 4 deletions pallets/oracle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ primitives = { package = "spacewalk-primitives", path = "../../primitives", defa
staking = { path = "../staking", default-features = false }
currency = { path = "../currency", default-features = false }

# Testing dependencies
spin = { version = "0.9.4", features = ["mutex"], optional = true }
once_cell = { version = "1.18.0", default-features = false, features = ["alloc", "race"], optional = true }

[dev-dependencies]
mocktopus = "0.8.0"
frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false }
Expand All @@ -42,7 +46,6 @@ orml-currencies = { git = "https://github.com/open-web3-stack/open-runtime-modul
orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.40", default-features = false }
orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.40", default-features = false }


[features]
default = ["std"]
std = [
Expand All @@ -65,8 +68,9 @@ std = [
"orml-tokens/std",
"orml-traits/std",
"orml-oracle/std",
"dia-oracle/std"

"dia-oracle/std",
"once_cell/std"

]
runtime-benchmarks = [
"frame-benchmarking",
Expand All @@ -77,4 +81,4 @@ runtime-benchmarks = [
"security/testing-utils",
"testing-utils"
]
testing-utils = []
testing-utils = ["spin", "once_cell"]
Loading