HydraDX-node
HydraDX-node copied to clipboard
EMA oracle events
emit event when oracle price changes on end of the block
Overview
We'll emit event in on_finalize for when price of an oracle is updated, event will include information for the Periods for which it was updated and the updated price for that period.
Event type
We'll introduce one event to emit updates for each (source,assets) pair
/// Oracle price was updated by several entries
OracleUpdated {
source: Source,
assets: (AssetId, AssetId),
update: Vec<(OraclePeriod, OracleEntry<BlockNumberFor<T>>)>,
},
Implementation Spec
fn update_oracle
Change signature of update_oracle. We are interested in the updated price only, so we return only that.
/// Update the oracle of the given source, assets and period with `oracle_entry`.
/// returns the updated price of the oracle
fn update_oracle(
src: Source,
assets: (AssetId, AssetId),
period: OraclePeriod,
incoming_entry: OracleEntry<BlockNumberFor<T>>,
) -> OracleEntry<BlockNumberFor<T>>
fn update_oracles_from_accumulator
Introduce a vector of type Vec<(OraclePeriod, Price)>, catch returned Price from update_oracle, push tuple of (OraclePeriod, Price) to this vec for event construction.
// accumulate updates to oracle for event emission
let mut updates = vec![];
// First we update the non-immediate oracles with the value of the `LastBlock` oracle.
for period in T::SupportedPeriods::get()
.into_iter()
.filter(|p| *p != OraclePeriod::LastBlock)
{
updates.push((
period,
Self::update_oracle(src.clone(), assets.clone(), period, oracle_entry.clone()),
));
}
// As we use (the old value of) the `LastBlock` entry to update the other oracles it
// gets updated last.
updates.push((
OraclePeriod::LastBlock,
Self::update_oracle(src, assets, OraclePeriod::LastBlock, oracle_entry.clone()),
));
Self::deposit_event(Event::<T>::OracleUpdated {
source: src,
assets,
updates,
});
Design Considerations
-
update_oraclereturns updated OracleEntry only not the blocknumber from when its updated - Could considering emitting only a portion of OracleEntry instead of the whole type
- OracleUpdated.updates is a vec of tuples, which is not very descriptive, maybe something like a dictionary type would be more useful, not sure if one is available though