mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Call tidy_keys upon queue_key
Prevents the potential case of the substrate task and the scan task writing to the same storage slot at once.
This commit is contained in:
@@ -116,6 +116,28 @@ impl<S: ScannerFeed> ScannerGlobalDb<S> {
|
|||||||
StartBlock::set(txn, &block)
|
StartBlock::set(txn, &block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tidy_keys(txn: &mut impl DbTxn) {
|
||||||
|
let mut keys: Vec<SeraiKeyDbEntry<EncodableG<KeyFor<S>>>> =
|
||||||
|
ActiveKeys::get(txn).expect("retiring key yet no active keys");
|
||||||
|
let Some(key) = keys.first() else { return };
|
||||||
|
|
||||||
|
// Get the block we're scanning for next
|
||||||
|
let block_number = next_to_scan_for_outputs_block::<S>(txn).expect(
|
||||||
|
"tidying keys despite never setting the next to scan for block (done on initialization)",
|
||||||
|
);
|
||||||
|
// If this key is scheduled for retiry...
|
||||||
|
if let Some(retire_at) = RetireAt::get(txn, key.key) {
|
||||||
|
// And is retired by/at this block...
|
||||||
|
if retire_at <= block_number {
|
||||||
|
// Remove it from the list of keys
|
||||||
|
let key = keys.remove(0);
|
||||||
|
ActiveKeys::set(txn, &keys);
|
||||||
|
// Also clean up the retiry block
|
||||||
|
RetireAt::del(txn, key.key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Queue a key.
|
/// Queue a key.
|
||||||
///
|
///
|
||||||
/// Keys may be queued whenever, so long as they're scheduled to activate `WINDOW_LENGTH` blocks
|
/// Keys may be queued whenever, so long as they're scheduled to activate `WINDOW_LENGTH` blocks
|
||||||
@@ -165,6 +187,9 @@ impl<S: ScannerFeed> ScannerGlobalDb<S> {
|
|||||||
// Push and save the next key
|
// Push and save the next key
|
||||||
keys.push(SeraiKeyDbEntry { activation_block_number, key: EncodableG(key) });
|
keys.push(SeraiKeyDbEntry { activation_block_number, key: EncodableG(key) });
|
||||||
ActiveKeys::set(txn, &keys);
|
ActiveKeys::set(txn, &keys);
|
||||||
|
|
||||||
|
// Now tidy the keys, ensuring this has a maximum length of 2
|
||||||
|
Self::tidy_keys(txn);
|
||||||
}
|
}
|
||||||
/// Retire a key.
|
/// Retire a key.
|
||||||
///
|
///
|
||||||
@@ -181,27 +206,6 @@ impl<S: ScannerFeed> ScannerGlobalDb<S> {
|
|||||||
|
|
||||||
RetireAt::set(txn, EncodableG(key), &at_block);
|
RetireAt::set(txn, EncodableG(key), &at_block);
|
||||||
}
|
}
|
||||||
pub(crate) fn tidy_keys(txn: &mut impl DbTxn) {
|
|
||||||
let mut keys: Vec<SeraiKeyDbEntry<EncodableG<KeyFor<S>>>> =
|
|
||||||
ActiveKeys::get(txn).expect("retiring key yet no active keys");
|
|
||||||
let Some(key) = keys.first() else { return };
|
|
||||||
|
|
||||||
// Get the block we're scanning for next
|
|
||||||
let block_number = next_to_scan_for_outputs_block::<S>(txn).expect(
|
|
||||||
"tidying keys despite never setting the next to scan for block (done on initialization)",
|
|
||||||
);
|
|
||||||
// If this key is scheduled for retiry...
|
|
||||||
if let Some(retire_at) = RetireAt::get(txn, key.key) {
|
|
||||||
// And is retired by/at this block...
|
|
||||||
if retire_at <= block_number {
|
|
||||||
// Remove it from the list of keys
|
|
||||||
let key = keys.remove(0);
|
|
||||||
ActiveKeys::set(txn, &keys);
|
|
||||||
// Also clean up the retiry block
|
|
||||||
RetireAt::del(txn, key.key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// Fetch the active keys, as of the next-to-scan-for-outputs Block.
|
/// Fetch the active keys, as of the next-to-scan-for-outputs Block.
|
||||||
///
|
///
|
||||||
/// This means the scan task should scan for all keys returned by this.
|
/// This means the scan task should scan for all keys returned by this.
|
||||||
|
|||||||
@@ -116,9 +116,6 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for ScanTask<D, S> {
|
|||||||
|
|
||||||
assert_eq!(ScanDb::<S>::next_to_scan_for_outputs_block(&txn).unwrap(), b);
|
assert_eq!(ScanDb::<S>::next_to_scan_for_outputs_block(&txn).unwrap(), b);
|
||||||
|
|
||||||
// Tidy the keys, then fetch them
|
|
||||||
// We don't have to tidy them here, we just have to somewhere, so why not here?
|
|
||||||
ScannerGlobalDb::<S>::tidy_keys(&mut txn);
|
|
||||||
let keys = ScannerGlobalDb::<S>::active_keys_as_of_next_to_scan_for_outputs_block(&txn)
|
let keys = ScannerGlobalDb::<S>::active_keys_as_of_next_to_scan_for_outputs_block(&txn)
|
||||||
.expect("scanning for a blockchain without any keys set");
|
.expect("scanning for a blockchain without any keys set");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user