Skip to content

Commit 0482bf2

Browse files
authored
Oracle: allow multiple feed values from inner calls (#920)
* move HasDispatched check to the extrinsic * add test * add option account to DataFeeder trait * minor comment change
1 parent 055e7db commit 0482bf2

File tree

3 files changed

+37
-16
lines changed

3 files changed

+37
-16
lines changed

oracle/src/lib.rs

+19-14
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,16 @@ pub mod module {
163163
let feeder = ensure_signed(origin.clone())
164164
.map(Some)
165165
.or_else(|_| ensure_root(origin).map(|_| None))?;
166-
Self::do_feed_values(feeder, values)?;
166+
167+
let who = Self::ensure_account(feeder)?;
168+
169+
// ensure account hasn't dispatched an updated yet
170+
ensure!(
171+
HasDispatched::<T, I>::mutate(|set| set.insert(who.clone())),
172+
Error::<T, I>::AlreadyFeeded
173+
);
174+
175+
Self::do_feed_values(who, values)?;
167176
Ok(Pays::No.into())
168177
}
169178
}
@@ -193,21 +202,17 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
193202
T::CombineData::combine_data(key, values, Self::values(key))
194203
}
195204

196-
fn do_feed_values(who: Option<T::AccountId>, values: Vec<(T::OracleKey, T::OracleValue)>) -> DispatchResult {
205+
fn ensure_account(who: Option<T::AccountId>) -> Result<T::AccountId, DispatchError> {
197206
// ensure feeder is authorized
198-
let who = if let Some(who) = who {
207+
if let Some(who) = who {
199208
ensure!(T::Members::contains(&who), Error::<T, I>::NoPermission);
200-
who
209+
Ok(who)
201210
} else {
202-
T::RootOperatorAccountId::get()
203-
};
204-
205-
// ensure account hasn't dispatched an updated yet
206-
ensure!(
207-
HasDispatched::<T, I>::mutate(|set| set.insert(who.clone())),
208-
Error::<T, I>::AlreadyFeeded
209-
);
211+
Ok(T::RootOperatorAccountId::get())
212+
}
213+
}
210214

215+
fn do_feed_values(who: T::AccountId, values: Vec<(T::OracleKey, T::OracleValue)>) -> DispatchResult {
211216
let now = T::Time::now();
212217
for (key, value) in &values {
213218
let timestamped = TimestampedValue {
@@ -258,7 +263,7 @@ impl<T: Config<I>, I: 'static> DataProviderExtended<T::OracleKey, TimestampedVal
258263
}
259264

260265
impl<T: Config<I>, I: 'static> DataFeeder<T::OracleKey, T::OracleValue, T::AccountId> for Pallet<T, I> {
261-
fn feed_value(who: T::AccountId, key: T::OracleKey, value: T::OracleValue) -> DispatchResult {
262-
Self::do_feed_values(Some(who), vec![(key, value)])
266+
fn feed_value(who: Option<T::AccountId>, key: T::OracleKey, value: T::OracleValue) -> DispatchResult {
267+
Self::do_feed_values(Self::ensure_account(who)?, vec![(key, value)])
263268
}
264269
}

oracle/src/tests.rs

+16
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ fn should_feed_values_from_root() {
6565
vec![(50, 1000), (51, 900), (52, 800)]
6666
));
6767

68+
// Or feed from root using the DataFeeder trait with None
69+
assert_ok!(ModuleOracle::feed_value(None, 53, 700));
70+
6871
assert_eq!(
6972
ModuleOracle::raw_values(&root_feeder, &50),
7073
Some(TimestampedValue {
@@ -88,6 +91,14 @@ fn should_feed_values_from_root() {
8891
timestamp: 12345,
8992
})
9093
);
94+
95+
assert_eq!(
96+
ModuleOracle::raw_values(&root_feeder, &53),
97+
Some(TimestampedValue {
98+
value: 700,
99+
timestamp: 12345,
100+
})
101+
);
91102
});
92103
}
93104

@@ -167,11 +178,16 @@ fn should_return_none_for_non_exist_key() {
167178
fn multiple_calls_should_fail() {
168179
new_test_ext().execute_with(|| {
169180
assert_ok!(ModuleOracle::feed_values(RuntimeOrigin::signed(1), vec![(50, 1300)]));
181+
182+
// Fails feeding by the the extrinsic
170183
assert_noop!(
171184
ModuleOracle::feed_values(RuntimeOrigin::signed(1), vec![(50, 1300)]),
172185
Error::<Test, _>::AlreadyFeeded,
173186
);
174187

188+
// But not if fed thought the trait internally
189+
assert_ok!(ModuleOracle::feed_value(Some(1), 50, 1300));
190+
175191
ModuleOracle::on_finalize(1);
176192

177193
assert_ok!(ModuleOracle::feed_values(RuntimeOrigin::signed(1), vec![(50, 1300)]));

traits/src/data_provider.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ use sp_runtime::DispatchResult;
22
use sp_std::vec::Vec;
33

44
/// Data provider with ability to provide data with no-op, and provide all data.
5-
pub trait DataFeeder<Key, Value, AccountId>: DataProvider<Key, Value> {
5+
pub trait DataFeeder<Key, Value, AccountId> {
66
/// Provide a new value for a given key from an operator
7-
fn feed_value(who: AccountId, key: Key, value: Value) -> DispatchResult;
7+
fn feed_value(who: Option<AccountId>, key: Key, value: Value) -> DispatchResult;
88
}
99

1010
/// A simple trait to provide data

0 commit comments

Comments
 (0)