mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-12 05:44:53 +00:00
Pass the latest active key to the Block's scan function
Effectively necessary for networks on which we utilize account abstraction in order to know what key to associate the received coins with.
This commit is contained in:
parent
118d81bc90
commit
673cf8fd47
9 changed files with 60 additions and 10 deletions
|
@ -91,7 +91,8 @@ async fn main() {
|
||||||
let Ok(_) = socket.read_exact(&mut buf).await else { break };
|
let Ok(_) = socket.read_exact(&mut buf).await else { break };
|
||||||
|
|
||||||
let transaction = db.get(&buf[.. 4]).unwrap_or(vec![]);
|
let transaction = db.get(&buf[.. 4]).unwrap_or(vec![]);
|
||||||
let Ok(()) = socket.write_all(&u32::try_from(transaction.len()).unwrap().to_le_bytes()).await
|
let Ok(()) =
|
||||||
|
socket.write_all(&u32::try_from(transaction.len()).unwrap().to_le_bytes()).await
|
||||||
else {
|
else {
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,7 +43,11 @@ impl<D: Db> primitives::Block for Block<D> {
|
||||||
primitives::BlockHeader::id(&BlockHeader(self.1.header))
|
primitives::BlockHeader::id(&BlockHeader(self.1.header))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scan_for_outputs_unordered(&self, key: Self::Key) -> Vec<Self::Output> {
|
fn scan_for_outputs_unordered(
|
||||||
|
&self,
|
||||||
|
_latest_active_key: Self::Key,
|
||||||
|
key: Self::Key,
|
||||||
|
) -> Vec<Self::Output> {
|
||||||
let scanner = scanner(key);
|
let scanner = scanner(key);
|
||||||
|
|
||||||
let mut res = vec![];
|
let mut res = vec![];
|
||||||
|
|
|
@ -59,8 +59,19 @@ impl primitives::Block for FullEpoch {
|
||||||
self.epoch.end_hash
|
self.epoch.end_hash
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scan_for_outputs_unordered(&self, _key: Self::Key) -> Vec<Self::Output> {
|
fn scan_for_outputs_unordered(
|
||||||
|
&self,
|
||||||
|
latest_active_key: Self::Key,
|
||||||
|
key: Self::Key,
|
||||||
|
) -> Vec<Self::Output> {
|
||||||
// Only return these outputs for the latest key
|
// Only return these outputs for the latest key
|
||||||
|
if latest_active_key != key {
|
||||||
|
return vec![];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Associate all outputs with the latest active key
|
||||||
|
// We don't associate these with the current key within the SC as that'll cause outputs to be
|
||||||
|
// marked for forwarding if the SC is delayed to actually rotate
|
||||||
todo!("TODO")
|
todo!("TODO")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,11 @@ impl primitives::Block for Block {
|
||||||
self.0.block.hash()
|
self.0.block.hash()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scan_for_outputs_unordered(&self, key: Self::Key) -> Vec<Self::Output> {
|
fn scan_for_outputs_unordered(
|
||||||
|
&self,
|
||||||
|
_latest_active_key: Self::Key,
|
||||||
|
key: Self::Key,
|
||||||
|
) -> Vec<Self::Output> {
|
||||||
let mut scanner = GuaranteedScanner::new(view_pair(key));
|
let mut scanner = GuaranteedScanner::new(view_pair(key));
|
||||||
scanner.register_subaddress(EXTERNAL_SUBADDRESS);
|
scanner.register_subaddress(EXTERNAL_SUBADDRESS);
|
||||||
scanner.register_subaddress(BRANCH_SUBADDRESS);
|
scanner.register_subaddress(BRANCH_SUBADDRESS);
|
||||||
|
|
|
@ -43,7 +43,11 @@ pub trait Block: Send + Sync + Sized + Clone + Debug {
|
||||||
/// Scan all outputs within this block to find the outputs spendable by this key.
|
/// Scan all outputs within this block to find the outputs spendable by this key.
|
||||||
///
|
///
|
||||||
/// No assumption on the order of the returned outputs is made.
|
/// No assumption on the order of the returned outputs is made.
|
||||||
fn scan_for_outputs_unordered(&self, key: Self::Key) -> Vec<Self::Output>;
|
fn scan_for_outputs_unordered(
|
||||||
|
&self,
|
||||||
|
latest_active_key: Self::Key,
|
||||||
|
key: Self::Key,
|
||||||
|
) -> Vec<Self::Output>;
|
||||||
|
|
||||||
/// Check if this block resolved any Eventualities.
|
/// Check if this block resolved any Eventualities.
|
||||||
///
|
///
|
||||||
|
|
|
@ -28,6 +28,7 @@ struct SeraiKeyDbEntry<K: Borshy> {
|
||||||
key: K,
|
key: K,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub(crate) struct SeraiKey<K> {
|
pub(crate) struct SeraiKey<K> {
|
||||||
pub(crate) key: K,
|
pub(crate) key: K,
|
||||||
pub(crate) stage: LifetimeStage,
|
pub(crate) stage: LifetimeStage,
|
||||||
|
|
|
@ -273,6 +273,18 @@ impl<D: Db, S: ScannerFeed, Sch: Scheduler<S>> ContinuallyRan for EventualityTas
|
||||||
log::debug!("checking eventuality completions in block: {} ({b})", hex::encode(block.id()));
|
log::debug!("checking eventuality completions in block: {} ({b})", hex::encode(block.id()));
|
||||||
|
|
||||||
let (keys, keys_with_stages) = self.keys_and_keys_with_stages(b);
|
let (keys, keys_with_stages) = self.keys_and_keys_with_stages(b);
|
||||||
|
let latest_active_key = {
|
||||||
|
let mut keys_with_stages = keys_with_stages.clone();
|
||||||
|
loop {
|
||||||
|
// Use the most recent key
|
||||||
|
let (key, stage) = keys_with_stages.pop().unwrap();
|
||||||
|
// Unless this key is active, but not yet reporting
|
||||||
|
if stage == LifetimeStage::ActiveYetNotReporting {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break key;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let mut txn = self.db.txn();
|
let mut txn = self.db.txn();
|
||||||
|
|
||||||
|
@ -307,7 +319,7 @@ impl<D: Db, S: ScannerFeed, Sch: Scheduler<S>> ContinuallyRan for EventualityTas
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch all non-External outputs
|
// Fetch all non-External outputs
|
||||||
let mut non_external_outputs = block.scan_for_outputs(key.key);
|
let mut non_external_outputs = block.scan_for_outputs(latest_active_key, key.key);
|
||||||
non_external_outputs.retain(|output| output.kind() != OutputType::External);
|
non_external_outputs.retain(|output| output.kind() != OutputType::External);
|
||||||
// Drop any outputs less than the dust limit
|
// Drop any outputs less than the dust limit
|
||||||
non_external_outputs.retain(|output| {
|
non_external_outputs.retain(|output| {
|
||||||
|
|
|
@ -46,11 +46,11 @@ pub(crate) fn sort_outputs<K: GroupEncoding, A: Address, O: ReceivedOutput<K, A>
|
||||||
|
|
||||||
/// Extension traits around Block.
|
/// Extension traits around Block.
|
||||||
pub(crate) trait BlockExt: Block {
|
pub(crate) trait BlockExt: Block {
|
||||||
fn scan_for_outputs(&self, key: Self::Key) -> Vec<Self::Output>;
|
fn scan_for_outputs(&self, latest_active_key: Self::Key, key: Self::Key) -> Vec<Self::Output>;
|
||||||
}
|
}
|
||||||
impl<B: Block> BlockExt for B {
|
impl<B: Block> BlockExt for B {
|
||||||
fn scan_for_outputs(&self, key: Self::Key) -> Vec<Self::Output> {
|
fn scan_for_outputs(&self, latest_active_key: Self::Key, key: Self::Key) -> Vec<Self::Output> {
|
||||||
let mut outputs = self.scan_for_outputs_unordered(key);
|
let mut outputs = self.scan_for_outputs_unordered(latest_active_key, key);
|
||||||
outputs.sort_by(sort_outputs);
|
outputs.sort_by(sort_outputs);
|
||||||
outputs
|
outputs
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,19 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for ScanTask<D, S> {
|
||||||
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");
|
||||||
|
|
||||||
|
let latest_active_key = {
|
||||||
|
let mut keys = keys.clone();
|
||||||
|
loop {
|
||||||
|
// Use the most recent key
|
||||||
|
let key = keys.pop().unwrap();
|
||||||
|
// Unless this key is active, but not yet reporting
|
||||||
|
if key.stage == LifetimeStage::ActiveYetNotReporting {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break key.key;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// The scan data for this block
|
// The scan data for this block
|
||||||
let mut scan_data = SenderScanData {
|
let mut scan_data = SenderScanData {
|
||||||
block_number: b,
|
block_number: b,
|
||||||
|
@ -157,7 +170,7 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for ScanTask<D, S> {
|
||||||
|
|
||||||
// Scan for each key
|
// Scan for each key
|
||||||
for key in &keys {
|
for key in &keys {
|
||||||
for output in block.scan_for_outputs(key.key) {
|
for output in block.scan_for_outputs(latest_active_key, key.key) {
|
||||||
assert_eq!(output.key(), key.key);
|
assert_eq!(output.key(), key.key);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue