Newer
Older
mock::{new_test_ext, AccountId, ModuleOracle, OracleCall, Origin, Test, Timestamp},
assert_noop, assert_ok, dispatch,
traits::{ChangeMembers, OnFinalize},
unsigned::ValidateUnsigned,
testing::{TestSignature, UintAuthorityId},
transaction_validity::{InvalidTransaction, TransactionSource, TransactionValidityError},
fn feed_values_from_session_key(
id: UintAuthorityId,
index: u32,
nonce: u32,
values: Vec<(u32, u32)>,
) -> Result<dispatch::DispatchResult, TransactionValidityError> {
let now = <frame_system::Module<Test>>::block_number();
let sig = id.sign(&(nonce, now, &values).encode()).unwrap();
<ModuleOracle as ValidateUnsigned>::validate_unsigned(
TransactionSource::External,
&OracleCall::feed_values(values.clone(), index, now, sig.clone()),
Ok(ModuleOracle::feed_values(Origin::none(), values, index, now, sig))
index: u32,
nonce: u32,
values: Vec<(u32, u32)>,
) -> Result<dispatch::DispatchResult, TransactionValidityError> {
let id = ModuleOracle::session_keys(from).unwrap();
#[test]
fn should_feed_values() {
new_test_ext().execute_with(|| {
let account_id: AccountId = 1;
assert_ok!(feed_values(account_id, 0, 0, vec![(50, 1000), (51, 900), (52, 800)]));
ModuleOracle::raw_values(&account_id, &50),
Some(TimestampedValue {
value: 1000,
timestamp: 12345,
})
);
assert_eq!(
ModuleOracle::raw_values(&account_id, &51),
Some(TimestampedValue {
value: 900,
timestamp: 12345,
})
);
assert_eq!(
ModuleOracle::raw_values(&account_id, &52),
Some(TimestampedValue {
value: 800,
timestamp: 12345,
})
);
});
}
#[test]
fn should_feed_values_from_root() {
new_test_ext().execute_with(|| {
let account_id: AccountId = 1;
assert_ok!(ModuleOracle::feed_values(
vec![(50, 1000), (51, 900), (52, 800)],
0,
TestSignature(0, vec![])
));
assert_eq!(
Some(TimestampedValue {
value: 1000,
timestamp: 12345,
})
);
assert_eq!(
Some(TimestampedValue {
value: 900,
timestamp: 12345,
})
);
assert_eq!(
Some(TimestampedValue {
value: 800,
timestamp: 12345,
})
);
});
}
let key: u32 = 50;
assert_eq!(ModuleOracle::is_updated(key), false);
assert_ok!(feed_values(1, 0, 0, vec![(key, 1000)]));
assert_ok!(feed_values(2, 1, 0, vec![(key, 1000)]));
assert_ok!(feed_values(3, 2, 0, vec![(key, 1000)]));
assert_eq!(ModuleOracle::is_updated(key), false);
assert_eq!(
ModuleOracle::get(&key).unwrap(),
TimestampedValue {
value: 1000,
timestamp: 12345
}
);
assert_eq!(ModuleOracle::is_updated(key), true);
ModuleOracle::on_finalize(1);
assert_ok!(feed_values(1, 0, 1, vec![(key, 1000)]));
assert_eq!(ModuleOracle::is_updated(key), false);
assert_noop!(
feed_values(1, 1, 0, vec![(50, 1000)]),
TransactionValidityError::Invalid(InvalidTransaction::BadProof)
);
assert_noop!(
feed_values(2, 0, 0, vec![(50, 1000)]),
TransactionValidityError::Invalid(InvalidTransaction::BadProof)
);
});
}
#[test]
fn should_validate_nonce() {
new_test_ext().execute_with(|| {
assert_noop!(
feed_values(1, 0, 1, vec![(50, 1000)]),
TransactionValidityError::Invalid(InvalidTransaction::BadProof)
);
assert_eq!(ModuleOracle::nonces(&1), 1);
ModuleOracle::on_finalize(1);
assert_noop!(
feed_values(1, 0, 0, vec![(50, 1000)]),
TransactionValidityError::Invalid(InvalidTransaction::BadProof)
);
assert_ok!(feed_values(1, 0, 1, vec![(50, 1000)]));
assert_eq!(ModuleOracle::nonces(&1), 2);
let raw_values = ModuleOracle::read_raw_values(&key);
assert_eq!(raw_values, vec![]);
assert_ok!(feed_values(1, 0, 0, vec![(key, 1000)]));
assert_ok!(feed_values(2, 1, 0, vec![(key, 1200)]));
let raw_values = ModuleOracle::read_raw_values(&key);
assert_eq!(
raw_values,
vec![
TimestampedValue {
value: 1000,
timestamp: 12345,
},
TimestampedValue {
value: 1200,
timestamp: 12345,
},
]
);
let key: u32 = 50;
assert_ok!(feed_values(1, 0, 0, vec![(key, 1300)]));
assert_ok!(feed_values(2, 1, 0, vec![(key, 1000)]));
assert_ok!(feed_values(3, 2, 0, vec![(key, 1200)]));
let expected = Some(TimestampedValue {
value: 1200,
timestamp: 12345,
});
assert_eq!(ModuleOracle::get(&key), expected);
Timestamp::set_timestamp(23456);
assert_eq!(ModuleOracle::get(&key), expected);
});
}
#[test]
});
}
#[test]
fn multiple_calls_should_fail() {
new_test_ext().execute_with(|| {
feed_values(1, 0, 1, vec![(50, 1300)]),
TransactionValidityError::Invalid(InvalidTransaction::Stale)
ModuleOracle::on_finalize(1);
assert_ok!(feed_values(1, 0, 1, vec![(50, 1300)]));
#[test]
fn get_all_values_should_work() {
new_test_ext().execute_with(|| {
let eur: u32 = 1;
let jpy: u32 = 2;
assert_eq!(ModuleOracle::get_all_values(), vec![]);
// feed eur & jpy
assert_ok!(feed_values(1, 0, 0, vec![(eur, 1300)]));
assert_ok!(feed_values(2, 1, 0, vec![(eur, 1000)]));
assert_ok!(feed_values(3, 2, 0, vec![(jpy, 9000)]));
// not enough eur & jpy prices
assert_eq!(ModuleOracle::get(&eur), None);
assert_eq!(ModuleOracle::get(&jpy), None);
assert_eq!(ModuleOracle::get_all_values(), vec![]);
// finalize block
assert_ok!(feed_values(3, 2, 1, vec![(eur, 1200)]));
assert_ok!(feed_values(1, 0, 1, vec![(jpy, 8000)]));
// enough eur prices
let eur_price = Some(TimestampedValue {
value: 1200,
timestamp: 12345,
});
assert_eq!(ModuleOracle::get(&eur), eur_price);
// not enough jpy prices
assert_eq!(ModuleOracle::get(&jpy), None);
assert_eq!(ModuleOracle::get_all_values(), vec![(eur, eur_price)]);
// feed jpy
// enough jpy prices
let jpy_price = Some(TimestampedValue {
value: 8000,
timestamp: 12345,
});
assert_eq!(ModuleOracle::get(&jpy), jpy_price);
assert_eq!(ModuleOracle::get_all_values(), vec![(eur, eur_price), (jpy, jpy_price)]);
});
}
#[test]
fn bad_index() {
new_test_ext().execute_with(|| {
assert_noop!(
feed_values(1, 255, 0, vec![(50, 1000)]),
TransactionValidityError::Invalid(InvalidTransaction::BadProof)
);
});
}
#[test]
fn change_member_should_work() {
new_test_ext().execute_with(|| {
<ModuleOracle as ChangeMembers<AccountId>>::change_members_sorted(&[4], &[1], &[2, 3, 4]);
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
assert_noop!(
feed_values_from_session_key(10.into(), 0, 0, vec![(50, 1000)]),
TransactionValidityError::Invalid(InvalidTransaction::BadProof)
);
assert_ok!(feed_values(2, 0, 0, vec![(50, 1000)]));
assert_noop!(
feed_values_from_session_key(40.into(), 2, 0, vec![(50, 1000)]),
TransactionValidityError::Invalid(InvalidTransaction::BadProof)
);
assert_eq!(ModuleOracle::session_keys(&4), None);
assert_ok!(ModuleOracle::set_session_key(Origin::signed(4), 40.into()));
assert_ok!(feed_values(4, 2, 0, vec![(50, 1000)]));
});
}
#[test]
fn should_clear_is_updated_on_change_member() {
new_test_ext().execute_with(|| {
assert_ok!(feed_values(1, 0, 0, vec![(50, 1000)]));
assert_ok!(feed_values(2, 1, 0, vec![(50, 1000)]));
assert_ok!(feed_values(3, 2, 0, vec![(50, 1000)]));
assert_eq!(
ModuleOracle::get(&50).unwrap(),
TimestampedValue {
value: 1000,
timestamp: 12345
}
);
assert_eq!(ModuleOracle::is_updated(50), true);
ModuleOracle::change_members_sorted(&[4], &[1], &[2, 3, 4]);
assert_eq!(ModuleOracle::is_updated(50), false);
});
}
#[test]
fn should_clear_data_for_removed_members() {
new_test_ext().execute_with(|| {
assert_ok!(feed_values(1, 0, 0, vec![(50, 1000)]));
assert_ok!(feed_values(2, 1, 0, vec![(50, 1000)]));
ModuleOracle::change_members_sorted(&[4], &[1], &[2, 3, 4]);
assert_eq!(ModuleOracle::raw_values(&1, 50), None);
assert_eq!(ModuleOracle::session_keys(&1), None);
assert_eq!(ModuleOracle::nonces(&1), 0);
});
}
#[test]
fn change_session_key() {
new_test_ext().execute_with(|| {
assert_ok!(ModuleOracle::set_session_key(Origin::signed(1), 11.into()));
assert_noop!(
feed_values_from_session_key(10.into(), 0, 0, vec![(50, 1000)]),
TransactionValidityError::Invalid(InvalidTransaction::BadProof)
);
assert_ok!(feed_values_from_session_key(11.into(), 0, 0, vec![(50, 1000)]));
});
}