Skip to content

Commit

Permalink
234 refactor dia implementation (#387)
Browse files Browse the repository at this point in the history
* Add re-usable implementation of DIA mock

* Deduplicate redeem

* Deduplicate issue

* Deduplicate nomination

* Deduplicate replace

* Deduplicate vault registry

* Change cfg macros

* Remove `benchmark_utils.rs`

* WIP

* Fix compilation of runtime _without_ features

* Implement oracle mock with no_std dependencies

* Remove unused `spin` dependency from testchain runtime

* Amend fix

* Re-add cfg_attr

* Fix mock and test cases

* Cleanup code

* Improve `derive_key` function

* Try to fix vault-registry tests

* Use `#[serial]` in vault registry tests

* Add `Mutex` lock to oracle mock

* Acquire lock before executing each vault-registry test

* Revert "Use `#[serial]` in vault registry tests"

This reverts commit de0c453.

* WIP

* Use `OnceBox`

* Fix remaining race conditions in vault registry tests

* Fix dependency declaration

* Refactor imports

* Refactor mock logic into separate files

* Declare test dependencies as `optional`

* Remove `#[serial]` from oracle tests again

* Remove `sp-tracing` again

* Final refactoring

* Rename type and structs

* Rename `clear_values()`

* Rename `acquire_lock()`

* Rename `feed_values()`

* Remove `clone()`
  • Loading branch information
ebma authored Oct 13, 2023
1 parent 0289e93 commit 91d6ed9
Show file tree
Hide file tree
Showing 19 changed files with 295 additions and 646 deletions.
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.

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

0 comments on commit 91d6ed9

Please sign in to comment.