Make a dedicated IndexDb

This commit is contained in:
Luke Parker 2024-08-26 23:24:49 -04:00
parent 66f3428051
commit 1e8f4e6156
4 changed files with 47 additions and 34 deletions

View file

@ -44,13 +44,8 @@ impl<S: ScannerFeed> OutputWithInInstruction<S> {
create_db!(
Scanner {
BlockId: (number: u64) -> [u8; 32],
BlockNumber: (id: [u8; 32]) -> u64,
ActiveKeys: <K: Borshy>() -> Vec<SeraiKeyDbEntry<K>>,
// The latest finalized block to appear of a blockchain
LatestFinalizedBlock: () -> u64,
// The next block to scan for received outputs
NextToScanForOutputsBlock: () -> u64,
// The next block to check for resolving eventualities
@ -89,17 +84,6 @@ create_db!(
pub(crate) struct ScannerDb<S: ScannerFeed>(PhantomData<S>);
impl<S: ScannerFeed> ScannerDb<S> {
pub(crate) fn set_block(txn: &mut impl DbTxn, number: u64, id: [u8; 32]) {
BlockId::set(txn, number, &id);
BlockNumber::set(txn, id, &number);
}
pub(crate) fn block_id(getter: &impl Get, number: u64) -> Option<[u8; 32]> {
BlockId::get(getter, number)
}
pub(crate) fn block_number(getter: &impl Get, id: [u8; 32]) -> Option<u64> {
BlockNumber::get(getter, id)
}
// activation_block_number is inclusive, so the key will be scanned for starting at the specified
// block
pub(crate) fn queue_key(txn: &mut impl DbTxn, activation_block_number: u64, key: KeyFor<S>) {
@ -155,13 +139,13 @@ impl<S: ScannerFeed> ScannerDb<S> {
pub(crate) fn set_start_block(txn: &mut impl DbTxn, start_block: u64, id: [u8; 32]) {
assert!(
LatestFinalizedBlock::get(txn).is_none(),
NextToScanForOutputsBlock::get(txn).is_none(),
"setting start block but prior set start block"
);
Self::set_block(txn, start_block, id);
crate::index::IndexDb::set_block(txn, start_block, id);
crate::index::IndexDb::set_latest_finalized_block(txn, start_block);
LatestFinalizedBlock::set(txn, &start_block);
NextToScanForOutputsBlock::set(txn, &start_block);
// We can receive outputs in this block, but any descending transactions will be in the next
// block. This, with the check on-set, creates a bound that this value in the DB is non-zero.
@ -169,13 +153,6 @@ impl<S: ScannerFeed> ScannerDb<S> {
NextToPotentiallyReportBlock::set(txn, &start_block);
}
pub(crate) fn set_latest_finalized_block(txn: &mut impl DbTxn, latest_finalized_block: u64) {
LatestFinalizedBlock::set(txn, &latest_finalized_block);
}
pub(crate) fn latest_finalized_block(getter: &impl Get) -> Option<u64> {
LatestFinalizedBlock::get(getter)
}
pub(crate) fn latest_scannable_block(getter: &impl Get) -> Option<u64> {
// We can only scan up to whatever block we've checked the Eventualities of, plus the window
// length. Since this returns an inclusive bound, we need to subtract 1

View file

@ -0,0 +1,34 @@
use serai_db::{Get, DbTxn, create_db};
create_db!(
ScannerIndex {
// A lookup of a block's number to its ID
BlockId: (number: u64) -> [u8; 32],
// A lookup of a block's ID to its number
BlockNumber: (id: [u8; 32]) -> u64,
// The latest finalized block to appear on the blockchain
LatestFinalizedBlock: () -> u64,
}
);
pub(crate) struct IndexDb;
impl IndexDb {
pub(crate) fn set_block(txn: &mut impl DbTxn, number: u64, id: [u8; 32]) {
BlockId::set(txn, number, &id);
BlockNumber::set(txn, id, &number);
}
pub(crate) fn block_id(getter: &impl Get, number: u64) -> Option<[u8; 32]> {
BlockId::get(getter, number)
}
pub(crate) fn block_number(getter: &impl Get, id: [u8; 32]) -> Option<u64> {
BlockNumber::get(getter, id)
}
pub(crate) fn set_latest_finalized_block(txn: &mut impl DbTxn, latest_finalized_block: u64) {
LatestFinalizedBlock::set(txn, &latest_finalized_block);
}
pub(crate) fn latest_finalized_block(getter: &impl Get) -> Option<u64> {
LatestFinalizedBlock::get(getter)
}
}

View file

@ -1,9 +1,11 @@
use serai_db::{DbTxn, Db};
use primitives::BlockHeader;
use primitives::{task::ContinuallyRan, BlockHeader};
// TODO: Localize to IndexDb?
use crate::{db::ScannerDb, ScannerFeed, ContinuallyRan};
use crate::ScannerFeed;
mod db;
pub(crate) use db::IndexDb;
/*
This processor should build its own index of the blockchain, yet only for finalized blocks which
@ -22,7 +24,7 @@ struct IndexFinalizedTask<D: Db, S: ScannerFeed> {
impl<D: Db, S: ScannerFeed> ContinuallyRan for IndexFinalizedTask<D, S> {
async fn run_iteration(&mut self) -> Result<bool, String> {
// Fetch the latest finalized block
let our_latest_finalized = ScannerDb::<S>::latest_finalized_block(&self.db)
let our_latest_finalized = IndexDb::latest_finalized_block(&self.db)
.expect("IndexTask run before writing the start block");
let latest_finalized = match self.feed.latest_finalized_block_number().await {
Ok(latest_finalized) => latest_finalized,
@ -51,7 +53,7 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for IndexFinalizedTask<D, S> {
// Check this descends from our indexed chain
{
let expected_parent =
ScannerDb::<S>::block_id(&self.db, b - 1).expect("didn't have the ID of the prior block");
IndexDb::block_id(&self.db, b - 1).expect("didn't have the ID of the prior block");
if block.parent() != expected_parent {
panic!(
"current finalized block (#{b}, {}) doesn't build off finalized block (#{}, {})",
@ -64,8 +66,8 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for IndexFinalizedTask<D, S> {
// Update the latest finalized block
let mut txn = self.db.txn();
ScannerDb::<S>::set_block(&mut txn, b, block.id());
ScannerDb::<S>::set_latest_finalized_block(&mut txn, b);
IndexDb::set_block(&mut txn, b, block.id());
IndexDb::set_latest_finalized_block(&mut txn, b);
txn.commit();
}

View file

@ -112,7 +112,7 @@ pub trait ScannerFeed: Send + Sync {
// Check the ID of this block is the expected ID
{
let expected =
ScannerDb::<S>::block_id(&self.db, number).expect("requested a block which wasn't indexed");
crate::index::IndexDb::block_id(&self.db, number).expect("requested a block which wasn't indexed");
if block.id() != expected {
panic!(
"finalized chain reorganized from {} to {} at {}",