diff --git a/Cargo.lock b/Cargo.lock index 8a1af93e9b2..063eac767c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -526,7 +526,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "basilisk" -version = "9.0.0" +version = "9.0.1" dependencies = [ "basilisk-runtime", "clap", @@ -608,7 +608,7 @@ dependencies = [ [[package]] name = "basilisk-runtime" -version = "96.0.0" +version = "97.0.0" dependencies = [ "common-runtime", "cumulus-pallet-aura-ext", @@ -1299,7 +1299,7 @@ dependencies = [ [[package]] name = "common-runtime" -version = "2.3.10" +version = "2.3.11" dependencies = [ "cumulus-pallet-xcmp-queue", "frame-support", @@ -1314,6 +1314,7 @@ dependencies = [ "pallet-currencies", "pallet-democracy", "pallet-duster", + "pallet-ema-oracle", "pallet-lbp", "pallet-marketplace", "pallet-nft", @@ -9799,7 +9800,7 @@ dependencies = [ [[package]] name = "runtime-integration-tests" -version = "0.9.4" +version = "0.9.5" dependencies = [ "basilisk-runtime", "cumulus-pallet-aura-ext", @@ -12690,7 +12691,7 @@ dependencies = [ [[package]] name = "testing-basilisk-runtime" -version = "96.0.0" +version = "97.0.0" dependencies = [ "common-runtime", "cumulus-pallet-aura-ext", diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index ec40d8304a9..9f4efbd8ac8 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "runtime-integration-tests" -version = "0.9.4" +version = "0.9.5" description = "Integration tests" authors = ["GalacticCouncil"] edition = "2021" diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs index 971bd954427..c9038192d97 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/src/lib.rs @@ -4,6 +4,7 @@ mod kusama_test_net; mod nft; mod nft_marketplace; mod non_native_fee; +mod oracle; mod router; mod vesting; mod xyk; diff --git a/integration-tests/src/oracle.rs b/integration-tests/src/oracle.rs new file mode 100644 index 00000000000..10e0b2c6762 --- /dev/null +++ b/integration-tests/src/oracle.rs @@ -0,0 +1,74 @@ +#![cfg(test)] + +use crate::kusama_test_net::*; + +use basilisk_runtime::{EmaOracle, RuntimeOrigin, XYK}; +use frame_support::{ + assert_ok, + traits::{OnFinalize, OnInitialize}, +}; +use hydradx_traits::{AggregatedPriceOracle, OraclePeriod::*}; +use pallet_ema_oracle::OracleError; +use polkadot_primitives::v2::BlockNumber; +use xcm_emulator::TestExt; + +pub fn basilisk_run_to_block(to: BlockNumber) { + while basilisk_runtime::System::block_number() < to { + let b = basilisk_runtime::System::block_number(); + + basilisk_runtime::System::on_finalize(b); + basilisk_runtime::EmaOracle::on_finalize(b); + + basilisk_runtime::System::on_initialize(b + 1); + basilisk_runtime::EmaOracle::on_initialize(b + 1); + + basilisk_runtime::System::set_block_number(b + 1); + } +} + +use pallet_xyk::SOURCE; + +#[test] +fn xyk_trades_are_ingested_into_oracle() { + TestNet::reset(); + + let asset_a = 1; + let asset_b = 2; + + Basilisk::execute_with(|| { + // arrange + basilisk_run_to_block(2); + + assert_ok!(XYK::create_pool( + RuntimeOrigin::signed(ALICE.into()), + asset_a, + 100 * UNITS, + asset_b, + 200 * UNITS, + )); + assert_ok!(XYK::sell( + RuntimeOrigin::signed(ALICE.into()), + asset_a, + asset_b, + 5 * UNITS, + UNITS, + false, + )); + + // act + // will store the data received in the sell as oracle values + basilisk_run_to_block(3); + + // assert + let expected = ((105000000000000, 190504761904760).into(), 0); + assert_eq!(EmaOracle::get_price(asset_a, asset_b, LastBlock, SOURCE), Ok(expected)); + // ten minutes oracle not configured/supported + assert_eq!( + EmaOracle::get_price(asset_a, asset_b, TenMinutes, SOURCE), + Err(OracleError::NotPresent) + ); + assert_eq!(EmaOracle::get_price(asset_a, asset_b, Hour, SOURCE), Ok(expected)); + assert_eq!(EmaOracle::get_price(asset_a, asset_b, Day, SOURCE), Ok(expected)); + assert_eq!(EmaOracle::get_price(asset_a, asset_b, Week, SOURCE), Ok(expected)); + }); +} diff --git a/node/Cargo.toml b/node/Cargo.toml index 2e6c342ada2..eb620a38a07 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "basilisk" -version = "9.0.0" +version = "9.0.1" description = "Basilisk node" authors = ["GalacticCouncil"] edition = "2021" diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs index 5c7f0bdadf8..e075651bdea 100644 --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -728,6 +728,7 @@ fn parachain_genesis( dust_account: Some(hex!["6d6f646c70792f74727372790000000000000000000000000000000000000000"].into()), }, polkadot_xcm: Default::default(), + ema_oracle: Default::default(), xyk_liquidity_mining: Default::default(), xyk_warehouse_lm: Default::default(), } @@ -830,6 +831,7 @@ fn testnet_parachain_genesis( dust_account: Some(get_account_id_from_seed::("Duster")), }, polkadot_xcm: Default::default(), + ema_oracle: Default::default(), xyk_liquidity_mining: Default::default(), xyk_warehouse_lm: Default::default(), } diff --git a/node/src/testing_chain_spec.rs b/node/src/testing_chain_spec.rs index 5696cc5de80..dc59a58db0c 100644 --- a/node/src/testing_chain_spec.rs +++ b/node/src/testing_chain_spec.rs @@ -484,5 +484,6 @@ fn testnet_parachain_genesis( polkadot_xcm: Default::default(), xyk_liquidity_mining: Default::default(), xyk_warehouse_lm: Default::default(), + ema_oracle: Default::default(), } } diff --git a/runtime/basilisk/Cargo.toml b/runtime/basilisk/Cargo.toml index b35432c3db8..0512e9f6195 100644 --- a/runtime/basilisk/Cargo.toml +++ b/runtime/basilisk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "basilisk-runtime" -version = "96.0.0" +version = "97.0.0" authors = ["GalacticCouncil"] edition = "2021" homepage = "https://github.com/galacticcouncil/Basilisk-node" diff --git a/runtime/basilisk/src/lib.rs b/runtime/basilisk/src/lib.rs index bdba216c09d..3a5d4e8db26 100644 --- a/runtime/basilisk/src/lib.rs +++ b/runtime/basilisk/src/lib.rs @@ -65,8 +65,9 @@ use frame_support::{ constants::{BlockExecutionWeight, RocksDbWeight}, ConstantMultiplier, Weight, WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, }, + BoundedVec, }; -use hydradx_traits::AssetPairAccountIdFor; +use hydradx_traits::{AssetPairAccountIdFor, OraclePeriod}; use pallet_transaction_payment::TargetedFeeAdjustment; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; @@ -112,7 +113,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("basilisk"), impl_name: create_runtime_str!("basilisk"), authoring_version: 1, - spec_version: 96, + spec_version: 97, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -494,7 +495,7 @@ impl pallet_xyk::Config for Runtime { type MaxInRatio = MaxInRatio; type MaxOutRatio = MaxOutRatio; type CanCreatePool = pallet_lbp::DisallowWhenLBPPoolRunning; - type AMMHandler = (); + type AMMHandler = pallet_ema_oracle::OnActivityHandler; type DiscountedFee = DiscountedFee; type NonDustableWhitelistHandler = Duster; } @@ -963,6 +964,26 @@ impl pallet_collator_rewards::Config for Runtime { type SessionManager = CollatorSelection; } +// constants need to be in scope to be used in generics +use pallet_ema_oracle::MAX_PERIODS; + +parameter_types! { + pub SupportedPeriods: BoundedVec> = BoundedVec::truncate_from( + vec![OraclePeriod::LastBlock, OraclePeriod::Hour, OraclePeriod::Day, OraclePeriod::Week] + ); + // There are currently only a few pools, so the number of entries per block is limited. + // NOTE: Needs to be updated once the number of pools grows. + pub MaxUniqueOracleEntries: u32 = 30; +} + +impl pallet_ema_oracle::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::ema_oracle::BasiliskWeight; + type BlockNumberProvider = RelayChainBlockNumberProvider; + type SupportedPeriods = SupportedPeriods; + type MaxUniqueEntries = MaxUniqueOracleEntries; +} + // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime where @@ -1024,6 +1045,8 @@ construct_runtime!( XYKWarehouseLM: warehouse_liquidity_mining:: = 113, CollatorRewards: pallet_collator_rewards = 114, + EmaOracle: pallet_ema_oracle = 120, + // ORML related modules - runtime module index for orml starts at 150 Currencies: pallet_currencies = 150, Tokens: orml_tokens = 151, @@ -1235,6 +1258,7 @@ impl_runtime_apis! { list_benchmark!(list, extra, pallet_asset_registry, AssetRegistry); list_benchmark!(list, extra, pallet_xyk_liquidity_mining, XYKLiquidityMiningBench::); list_benchmark!(list, extra, pallet_transaction_pause, TransactionPause); + list_benchmark!(list, extra, pallet_ema_oracle, EmaOracle); list_benchmark!(list, extra, frame_system, SystemBench::); list_benchmark!(list, extra, pallet_balances, Balances); @@ -1299,6 +1323,7 @@ impl_runtime_apis! { add_benchmark!(params, batches, pallet_asset_registry, AssetRegistry); add_benchmark!(params, batches, pallet_xyk_liquidity_mining, XYKLiquidityMiningBench::); add_benchmark!(params, batches, pallet_transaction_pause, TransactionPause); + add_benchmark!(params, batches, pallet_ema_oracle, EmaOracle); // Substrate pallets add_benchmark!(params, batches, frame_system, SystemBench::); diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index b05d69db471..0c9750b78b6 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "common-runtime" -version = "2.3.10" +version = "2.3.11" authors = ["GalacticCouncil"] edition = "2021" homepage = "https://github.com/galacticcouncil/Basilisk-node" @@ -33,6 +33,7 @@ pallet-transaction-pause = { git = "https://github.com/galacticcouncil/warehouse pallet-currencies = { git = "https://github.com/galacticcouncil/warehouse", rev = "d6a78b5d51bc8af525d2b8f856efcfce2159e334", default-features = false } pallet-route-executor = { git = "https://github.com/galacticcouncil/warehouse", rev = "d6a78b5d51bc8af525d2b8f856efcfce2159e334", default-features = false } pallet-duster = { git = "https://github.com/galacticcouncil/warehouse", rev = "d6a78b5d51bc8af525d2b8f856efcfce2159e334", default-features = false } +pallet-ema-oracle = { git = "https://github.com/galacticcouncil/warehouse", rev = "d6a78b5d51bc8af525d2b8f856efcfce2159e334", default-features = false } # Substrate dependencies sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } diff --git a/runtime/common/src/weights/ema_oracle.rs b/runtime/common/src/weights/ema_oracle.rs new file mode 100644 index 00000000000..f8598ac88f7 --- /dev/null +++ b/runtime/common/src/weights/ema_oracle.rs @@ -0,0 +1,79 @@ +// This file is part of Basilisk-node. + +// Copyright (C) 2020-2023 Intergalactic, Limited (GIB). +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Autogenerated weights for pallet_ema_oracle +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-03-09, STEPS: 10, REPEAT: 30, LOW RANGE: [], HIGH RANGE: [] +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 + +// Executed Command: +// target/release/basilisk +// benchmark +// pallet +// --chain=dev +// --steps=10 +// --repeat=30 +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --template=.maintain/pallet-weight-template-no-back.hbs +// --pallet=pallet_ema_oracle +// --output=oracle.rs +// --extrinsic=* +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{ + traits::Get, + weights::{constants::RocksDbWeight, Weight}, +}; +use sp_std::marker::PhantomData; + +use pallet_ema_oracle::weights::WeightInfo; + +pub struct BasiliskWeight(PhantomData); + +impl WeightInfo for BasiliskWeight { + fn on_finalize_no_entry() -> Weight { + Weight::from_ref_time(4_740_000).saturating_add(T::DbWeight::get().reads(1 as u64)) + } + fn on_finalize_multiple_tokens(b: u32) -> Weight { + Weight::from_ref_time(19_041_000) // Standard Error: 53_000 + .saturating_add(Weight::from_ref_time(43_566_000).saturating_mul(b as u64)) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().reads((4 as u64).saturating_mul(b as u64))) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + .saturating_add(T::DbWeight::get().writes((4 as u64).saturating_mul(b as u64))) + } + fn on_trade_multiple_tokens(b: u32) -> Weight { + Weight::from_ref_time(17_201_000) // Standard Error: 6_000 + .saturating_add(Weight::from_ref_time(712_000).saturating_mul(b as u64)) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + fn on_liquidity_changed_multiple_tokens(b: u32) -> Weight { + Weight::from_ref_time(17_238_000) // Standard Error: 6_000 + .saturating_add(Weight::from_ref_time(704_000).saturating_mul(b as u64)) + .saturating_add(T::DbWeight::get().reads(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + fn get_entry() -> Weight { + Weight::from_ref_time(24_093_000).saturating_add(T::DbWeight::get().reads(2 as u64)) + } +} diff --git a/runtime/common/src/weights/mod.rs b/runtime/common/src/weights/mod.rs index 95b1ce66e0c..7db56452463 100644 --- a/runtime/common/src/weights/mod.rs +++ b/runtime/common/src/weights/mod.rs @@ -4,6 +4,7 @@ pub mod collator_selection; pub mod currencies; pub mod democracy; pub mod duster; +pub mod ema_oracle; pub mod lbp; pub mod marketplace; pub mod nft; diff --git a/runtime/testing-basilisk/Cargo.toml b/runtime/testing-basilisk/Cargo.toml index 4e59b34cead..0ffc0dd7d6a 100644 --- a/runtime/testing-basilisk/Cargo.toml +++ b/runtime/testing-basilisk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "testing-basilisk-runtime" -version = "96.0.0" +version = "97.0.0" authors = ["GalacticCouncil"] edition = "2021" homepage = "https://github.com/galacticcouncil/Basilisk-node" diff --git a/runtime/testing-basilisk/src/lib.rs b/runtime/testing-basilisk/src/lib.rs index 95db1e3906a..3e16f377f0e 100644 --- a/runtime/testing-basilisk/src/lib.rs +++ b/runtime/testing-basilisk/src/lib.rs @@ -63,8 +63,9 @@ use frame_support::{ constants::{BlockExecutionWeight, RocksDbWeight}, ConstantMultiplier, Weight, WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, }, + BoundedVec, }; -use hydradx_traits::AssetPairAccountIdFor; +use hydradx_traits::{AssetPairAccountIdFor, OraclePeriod}; use orml_traits::currency::MutationHooks; use pallet_transaction_payment::TargetedFeeAdjustment; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; @@ -134,7 +135,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("testing-basilisk"), impl_name: create_runtime_str!("testing-basilisk"), authoring_version: 1, - spec_version: 96, + spec_version: 97, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -467,7 +468,7 @@ impl pallet_xyk::Config for Runtime { type MaxInRatio = MaxInRatio; type MaxOutRatio = MaxOutRatio; type CanCreatePool = pallet_lbp::DisallowWhenLBPPoolRunning; - type AMMHandler = (); + type AMMHandler = pallet_ema_oracle::OnActivityHandler; type DiscountedFee = DiscountedFee; type NonDustableWhitelistHandler = Duster; } @@ -936,6 +937,26 @@ impl pallet_collator_rewards::Config for Runtime { type SessionManager = CollatorSelection; } +// constants need to be in scope to be used in generics +use pallet_ema_oracle::MAX_PERIODS; + +parameter_types! { + pub SupportedPeriods: BoundedVec> = BoundedVec::truncate_from( + vec![OraclePeriod::LastBlock, OraclePeriod::Hour, OraclePeriod::Day, OraclePeriod::Week] + ); + // There are currently only a few pools, so the number of entries per block is limited. + // NOTE: Needs to be updated once the number of pools grows. + pub MaxUniqueOracleEntries: u32 = 30; +} + +impl pallet_ema_oracle::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::ema_oracle::BasiliskWeight; + type BlockNumberProvider = cumulus_pallet_parachain_system::RelaychainBlockNumberProvider; + type SupportedPeriods = SupportedPeriods; + type MaxUniqueEntries = MaxUniqueOracleEntries; +} + // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime where @@ -997,6 +1018,8 @@ construct_runtime!( XYKWarehouseLM: warehouse_liquidity_mining:: = 113, CollatorRewards: pallet_collator_rewards = 114, + EmaOracle: pallet_ema_oracle = 120, + // ORML related modules - starts at 150 Currencies: pallet_currencies = 150, Tokens: orml_tokens = 151,