mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-11 05:14:41 +00:00
Correct misc compilation errors
This commit is contained in:
parent
a2717d73f0
commit
2b47feafed
5 changed files with 70 additions and 27 deletions
|
@ -13,9 +13,9 @@ impl<T: BorshSerialize + BorshDeserialize> Borshy for T {}
|
|||
|
||||
#[derive(BorshSerialize, BorshDeserialize)]
|
||||
pub(crate) struct SeraiKey<K: Borshy> {
|
||||
activation_block_number: u64,
|
||||
retirement_block_number: Option<u64>,
|
||||
key: K,
|
||||
pub(crate) activation_block_number: u64,
|
||||
pub(crate) retirement_block_number: Option<u64>,
|
||||
pub(crate) key: K,
|
||||
}
|
||||
|
||||
create_db!(
|
||||
|
@ -208,7 +208,7 @@ impl<S: ScannerFeed> ScannerDb<S> {
|
|||
SerializedOutputs::set(txn, block_number, &buf);
|
||||
}
|
||||
|
||||
pub(crate) fn is_notable_block(getter: &impl Get, number: u64) -> bool {
|
||||
pub(crate) fn is_block_notable(getter: &impl Get, number: u64) -> bool {
|
||||
NotableBlock::get(getter, number).is_some()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,12 +6,21 @@ use primitives::{ReceivedOutput, Block};
|
|||
|
||||
mod db;
|
||||
mod index;
|
||||
mod scan;
|
||||
mod eventuality;
|
||||
mod report;
|
||||
mod safe;
|
||||
|
||||
/// A feed usable to scan a blockchain.
|
||||
///
|
||||
/// This defines the primitive types used, along with various getters necessary for indexing.
|
||||
#[async_trait::async_trait]
|
||||
pub trait ScannerFeed: Send + Sync {
|
||||
/// The amount of confirmations required for a block to be finalized.
|
||||
///
|
||||
/// This value must be at least `1`.
|
||||
const CONFIRMATIONS: u64;
|
||||
|
||||
/// The type of the key used to receive coins on this blockchain.
|
||||
type Key: group::Group + group::GroupEncoding;
|
||||
|
||||
|
@ -35,11 +44,19 @@ pub trait ScannerFeed: Send + Sync {
|
|||
/// resolve without manual intervention.
|
||||
type EphemeralError: Debug;
|
||||
|
||||
/// Fetch the number of the latest block.
|
||||
///
|
||||
/// The block number is its zero-indexed position within a linear view of the external network's
|
||||
/// consensus. The genesis block accordingly has block number 0.
|
||||
async fn latest_block_number(&self) -> Result<u64, Self::EphemeralError>;
|
||||
|
||||
/// Fetch the number of the latest finalized block.
|
||||
///
|
||||
/// The block number is its zero-indexed position within a linear view of the external network's
|
||||
/// consensus. The genesis block accordingly has block number 0.
|
||||
async fn latest_finalized_block_number(&self) -> Result<u64, Self::EphemeralError>;
|
||||
async fn latest_finalized_block_number(&self) -> Result<u64, Self::EphemeralError> {
|
||||
Ok(self.latest_block_number().await? - Self::CONFIRMATIONS)
|
||||
}
|
||||
|
||||
/// Fetch a block by its number.
|
||||
async fn block_by_number(&self, number: u64) -> Result<Self::Block, Self::EphemeralError>;
|
||||
|
@ -49,7 +66,7 @@ pub trait ScannerFeed: Send + Sync {
|
|||
&self,
|
||||
block: &Self::Block,
|
||||
key: Self::Key,
|
||||
) -> Result<Self::Output, Self::EphemeralError>;
|
||||
) -> Result<Vec<Self::Output>, Self::EphemeralError>;
|
||||
}
|
||||
|
||||
/// A handle to immediately run an iteration of a task.
|
||||
|
|
|
@ -8,7 +8,7 @@ use serai_db::{Db, DbTxn};
|
|||
use primitives::{Id, Block};
|
||||
|
||||
// TODO: Localize to ReportDb?
|
||||
use crate::{db::ScannerDb, ScannerFeed};
|
||||
use crate::{db::ScannerDb, ScannerFeed, ContinuallyRan};
|
||||
|
||||
struct ReportTask<D: Db, S: ScannerFeed> {
|
||||
db: D,
|
||||
|
@ -20,8 +20,10 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for ReportTask<D, S> {
|
|||
async fn run_iteration(&mut self) -> Result<bool, String> {
|
||||
let highest_reportable = {
|
||||
// Fetch the latest scanned and latest checked block
|
||||
let next_to_scan = ScannerDb::<S>::next_to_scan_for_outputs_block(&self.db).expect("ReportTask run before writing the start block");
|
||||
let next_to_check = ScannerDb::<S>::next_to_check_for_eventualities_block(&self.db).expect("ReportTask run before writing the start block");
|
||||
let next_to_scan = ScannerDb::<S>::next_to_scan_for_outputs_block(&self.db)
|
||||
.expect("ReportTask run before writing the start block");
|
||||
let next_to_check = ScannerDb::<S>::next_to_check_for_eventualities_block(&self.db)
|
||||
.expect("ReportTask run before writing the start block");
|
||||
// If we haven't done any work, return
|
||||
if (next_to_scan == 0) || (next_to_check == 0) {
|
||||
return Ok(false);
|
||||
|
@ -31,10 +33,11 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for ReportTask<D, S> {
|
|||
last_scanned.min(last_checked)
|
||||
};
|
||||
|
||||
let next_to_potentially_report = ScannerDb::<S>::next_block_to_potentially_report(&self.db).expect("ReportTask run before writing the start block");
|
||||
let next_to_potentially_report = ScannerDb::<S>::next_to_potentially_report_block(&self.db)
|
||||
.expect("ReportTask run before writing the start block");
|
||||
|
||||
for b in next_to_potentially_report ..= highest_reportable {
|
||||
if ScannerDb::<S>::is_block_notable(b) {
|
||||
if ScannerDb::<S>::is_block_notable(&self.db, b) {
|
||||
todo!("TODO: Make Batches, which requires handling Forwarded within this crate");
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use serai_db::{Db, DbTxn};
|
|||
use primitives::{Id, Block};
|
||||
|
||||
// TODO: Localize to SafeDb?
|
||||
use crate::{db::ScannerDb, ScannerFeed};
|
||||
use crate::{db::ScannerDb, ScannerFeed, ContinuallyRan};
|
||||
|
||||
/*
|
||||
We mark blocks safe to scan when they're no more than `(CONFIRMATIONS - 1)` blocks after the
|
||||
|
@ -27,7 +27,8 @@ struct SafeToScanTask<D: Db, S: ScannerFeed> {
|
|||
impl<D: Db, S: ScannerFeed> ContinuallyRan for SafeToScanTask<D, S> {
|
||||
async fn run_iteration(&mut self) -> Result<bool, String> {
|
||||
// First, we fetch the highest acknowledged block
|
||||
let Some(highest_acknowledged_block) = ScannerDb::<S>::highest_acknowledged_block(&self.db) else {
|
||||
let Some(highest_acknowledged_block) = ScannerDb::<S>::highest_acknowledged_block(&self.db)
|
||||
else {
|
||||
// If no blocks have been acknowledged, we don't mark any safe
|
||||
// Once the start block (implicitly safe) has been acknowledged, we proceed from there
|
||||
return Ok(false);
|
||||
|
@ -38,13 +39,15 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for SafeToScanTask<D, S> {
|
|||
// If we've decided to report (or not report) a block, we know if it needs acknowledgement
|
||||
// (and accordingly is pending acknowledgement)
|
||||
// Accordingly, the block immediately before this is the latest block with a known status
|
||||
ScannerDb::<S>::next_block_to_potentially_report(&self.db).expect("SafeToScanTask run before writing the start block") - 1
|
||||
ScannerDb::<S>::next_to_potentially_report_block(&self.db)
|
||||
.expect("SafeToScanTask run before writing the start block") -
|
||||
1
|
||||
};
|
||||
|
||||
let mut oldest_pending_acknowledgement = None;
|
||||
for b in (highest_acknowledged_block + 1) ..= latest_block_known_if_pending_acknowledgement {
|
||||
// If the block isn't notable, immediately flag it as acknowledged
|
||||
if !ScannerDb::<S>::is_block_notable(b) {
|
||||
if !ScannerDb::<S>::is_block_notable(&self.db, b) {
|
||||
let mut txn = self.db.txn();
|
||||
ScannerDb::<S>::set_highest_acknowledged_block(&mut txn, b);
|
||||
txn.commit();
|
||||
|
@ -61,13 +64,19 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for SafeToScanTask<D, S> {
|
|||
// acknowledgement, and the oldest block still pending acknowledgement is in the future,
|
||||
// we know the safe block to scan to is
|
||||
// `>= latest_block_known_if_pending_acknowledgement + (CONFIRMATIONS - 1)`
|
||||
let oldest_pending_acknowledgement = oldest_pending_acknowledgement.unwrap_or(latest_block_known_if_pending_acknowledgement);
|
||||
let oldest_pending_acknowledgement =
|
||||
oldest_pending_acknowledgement.unwrap_or(latest_block_known_if_pending_acknowledgement);
|
||||
|
||||
let old_safe_block = ScannerDb::<S>::latest_scannable_block(&self.db)
|
||||
.expect("SafeToScanTask run before writing the start block");
|
||||
let new_safe_block = oldest_pending_acknowledgement +
|
||||
(S::CONFIRMATIONS.checked_sub(1).expect("CONFIRMATIONS wasn't at least 1"));
|
||||
|
||||
// Update the latest scannable block
|
||||
let mut txn = self.db.txn();
|
||||
ScannerDb::<S>::set_latest_scannable_block(oldest_pending_acknowledgement + (CONFIRMATIONS - 1));
|
||||
ScannerDb::<S>::set_latest_scannable_block(&mut txn, new_safe_block);
|
||||
txn.commit();
|
||||
|
||||
Ok(next_to_potentially_report <= highest_reportable)
|
||||
Ok(old_safe_block != new_safe_block)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use serai_db::{Db, DbTxn};
|
||||
|
||||
use primitives::{Id, Block};
|
||||
use primitives::{Id, ReceivedOutput, Block};
|
||||
|
||||
// TODO: Localize to ScanDb?
|
||||
use crate::{db::ScannerDb, ScannerFeed};
|
||||
use crate::{db::ScannerDb, ScannerFeed, ContinuallyRan};
|
||||
|
||||
struct ScanForOutputsTask<D: Db, S: ScannerFeed> {
|
||||
db: D,
|
||||
|
@ -14,9 +14,11 @@ struct ScanForOutputsTask<D: Db, S: ScannerFeed> {
|
|||
impl<D: Db, S: ScannerFeed> ContinuallyRan for ScanForOutputsTask<D, S> {
|
||||
async fn run_iteration(&mut self) -> Result<bool, String> {
|
||||
// Fetch the safe to scan block
|
||||
let latest_scannable = ScannerDb::<S>::latest_scannable_block(&self.db).expect("ScanForOutputsTask run before writing the start block");
|
||||
let latest_scannable = ScannerDb::<S>::latest_scannable_block(&self.db)
|
||||
.expect("ScanForOutputsTask run before writing the start block");
|
||||
// Fetch the next block to scan
|
||||
let next_to_scan = ScannerDb::<S>::next_to_scan_for_outputs_block(&self.db).expect("ScanForOutputsTask run before writing the start block");
|
||||
let next_to_scan = ScannerDb::<S>::next_to_scan_for_outputs_block(&self.db)
|
||||
.expect("ScanForOutputsTask run before writing the start block");
|
||||
|
||||
for b in next_to_scan ..= latest_scannable {
|
||||
let block = match self.feed.block_by_number(b).await {
|
||||
|
@ -26,15 +28,22 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for ScanForOutputsTask<D, S> {
|
|||
|
||||
// Check the ID of this block is the expected ID
|
||||
{
|
||||
let expected = ScannerDb::<S>::block_id(b).expect("scannable block didn't have its ID saved");
|
||||
let expected =
|
||||
ScannerDb::<S>::block_id(&self.db, b).expect("scannable block didn't have its ID saved");
|
||||
if block.id() != expected {
|
||||
panic!("finalized chain reorganized from {} to {} at {}", hex::encode(expected), hex::encode(block.id()), b);
|
||||
panic!(
|
||||
"finalized chain reorganized from {} to {} at {}",
|
||||
hex::encode(expected),
|
||||
hex::encode(block.id()),
|
||||
b
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
log::info!("scanning block: {} ({b})", hex::encode(block.id()));
|
||||
|
||||
let keys = ScannerDb::<S>::keys(&self.db).expect("scanning for a blockchain without any keys set");
|
||||
let mut keys =
|
||||
ScannerDb::<S>::keys(&self.db).expect("scanning for a blockchain without any keys set");
|
||||
// Remove all the retired keys
|
||||
while let Some(retire_at) = keys[0].retirement_block_number {
|
||||
if retire_at <= b {
|
||||
|
@ -51,8 +60,13 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for ScanForOutputsTask<D, S> {
|
|||
continue;
|
||||
}
|
||||
|
||||
for output in network.scan_for_outputs(&block, key).awaits {
|
||||
assert_eq!(output.key(), key);
|
||||
for output in self
|
||||
.feed
|
||||
.scan_for_outputs(&block, key.key.0)
|
||||
.await
|
||||
.map_err(|e| format!("failed to scan block {b}: {e:?}"))?
|
||||
{
|
||||
assert_eq!(output.key(), key.key.0);
|
||||
// TODO: Check for dust
|
||||
outputs.push(output);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue