From ce805c8cc860e2598c24c98561cd5f8bf57d9252 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Fri, 23 Aug 2024 21:21:02 -0400 Subject: [PATCH] Correct compilation errors --- Cargo.lock | 1 + processor/primitives/src/block.rs | 4 +-- processor/primitives/src/output.rs | 7 ++-- processor/scanner/Cargo.toml | 1 + processor/scanner/src/db.rs | 27 ++++++++++----- processor/scanner/src/lib.rs | 16 +++++---- processor/scanner/src/report.rs | 18 ++-------- processor/scanner/src/scan.rs | 53 ++++++++++++++++++++---------- 8 files changed, 77 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e3e6f378..f887bd8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8669,6 +8669,7 @@ dependencies = [ "log", "parity-scale-codec", "serai-db", + "serai-in-instructions-primitives", "serai-primitives", "serai-processor-messages", "serai-processor-primitives", diff --git a/processor/primitives/src/block.rs b/processor/primitives/src/block.rs index 22f0b998..1fc92c3a 100644 --- a/processor/primitives/src/block.rs +++ b/processor/primitives/src/block.rs @@ -2,7 +2,7 @@ use core::fmt::Debug; use group::{Group, GroupEncoding}; -use crate::{Id, ReceivedOutput}; +use crate::{Id, Address, ReceivedOutput}; /// A block header from an external network. pub trait BlockHeader: Send + Sync + Sized + Clone + Debug { @@ -28,7 +28,7 @@ pub trait Block: Send + Sync + Sized + Clone + Debug { /// The type used to represent keys on this external network. type Key: Group + GroupEncoding; /// The type used to represent addresses on this external network. - type Address; + type Address: Address; /// The type used to represent received outputs on this external network. type Output: ReceivedOutput; diff --git a/processor/primitives/src/output.rs b/processor/primitives/src/output.rs index 1dd186aa..2b96d229 100644 --- a/processor/primitives/src/output.rs +++ b/processor/primitives/src/output.rs @@ -3,10 +3,13 @@ use std::io; use group::GroupEncoding; -use serai_primitives::Balance; +use serai_primitives::{ExternalAddress, Balance}; use crate::Id; +/// An address on the external network. +pub trait Address: Send + Sync + TryFrom {} + /// The type of the output. #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] pub enum OutputType { @@ -81,7 +84,7 @@ impl OutputType { } /// A received output. -pub trait ReceivedOutput: +pub trait ReceivedOutput: Send + Sync + Sized + Clone + PartialEq + Eq + Debug { /// The type used to identify this output. diff --git a/processor/scanner/Cargo.toml b/processor/scanner/Cargo.toml index 82de4de1..a16b55f2 100644 --- a/processor/scanner/Cargo.toml +++ b/processor/scanner/Cargo.toml @@ -36,6 +36,7 @@ tokio = { version = "1", default-features = false, features = ["rt-multi-thread" serai-db = { path = "../../common/db" } serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] } +serai-in-instructions-primitives = { path = "../../substrate/in-instructions/primitives", default-features = false, features = ["std"] } messages = { package = "serai-processor-messages", path = "../messages" } primitives = { package = "serai-processor-primitives", path = "../primitives" } diff --git a/processor/scanner/src/db.rs b/processor/scanner/src/db.rs index 2e462712..7eb276ce 100644 --- a/processor/scanner/src/db.rs +++ b/processor/scanner/src/db.rs @@ -1,11 +1,17 @@ use core::marker::PhantomData; +use std::io; +use group::GroupEncoding; + +use scale::{Encode, Decode}; use borsh::{BorshSerialize, BorshDeserialize}; use serai_db::{Get, DbTxn, create_db}; +use serai_in_instructions_primitives::InInstructionWithBalance; + use primitives::{Id, ReceivedOutput, Block, BorshG}; -use crate::{lifetime::LifetimeStage, ScannerFeed, BlockIdFor, KeyFor, OutputFor}; +use crate::{lifetime::LifetimeStage, ScannerFeed, BlockIdFor, KeyFor, AddressFor, OutputFor}; // The DB macro doesn't support `BorshSerialize + BorshDeserialize` as a bound, hence this. trait Borshy: BorshSerialize + BorshDeserialize {} @@ -22,16 +28,16 @@ pub(crate) struct SeraiKey { pub(crate) key: K, } -pub(crate) struct OutputWithInInstruction> { - output: O, - refund_address: A, - in_instruction: InInstructionWithBalance, +pub(crate) struct OutputWithInInstruction { + pub(crate) output: OutputFor, + pub(crate) return_address: Option>, + pub(crate) in_instruction: InInstructionWithBalance, } -impl> OutputWithInInstruction { +impl OutputWithInInstruction { fn write(&self, writer: &mut impl io::Write) -> io::Result<()> { self.output.write(writer)?; - // TODO self.refund_address.write(writer)?; + // TODO self.return_address.write(writer)?; self.in_instruction.encode_to(writer); Ok(()) } @@ -172,6 +178,7 @@ impl ScannerDb { // 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 // See `eventuality.rs` for more info + // TODO: Adjust based on register eventualities NextToCheckForEventualitiesBlock::get(getter).map(|b| b + S::WINDOW_LENGTH - 1) } @@ -219,7 +226,11 @@ impl ScannerDb { HighestAcknowledgedBlock::get(getter) } - pub(crate) fn set_in_instructions(txn: &mut impl DbTxn, block_number: u64, outputs: Vec, AddressFor, OutputFor>>) { + pub(crate) fn set_in_instructions( + txn: &mut impl DbTxn, + block_number: u64, + outputs: Vec>, + ) { if outputs.is_empty() { return; } diff --git a/processor/scanner/src/lib.rs b/processor/scanner/src/lib.rs index 04366dff..7bd8cc2e 100644 --- a/processor/scanner/src/lib.rs +++ b/processor/scanner/src/lib.rs @@ -1,4 +1,4 @@ -use core::{fmt::Debug, time::Duration}; +use core::{marker::PhantomData, fmt::Debug, time::Duration}; use tokio::sync::mpsc; @@ -86,6 +86,7 @@ pub trait ScannerFeed: Send + Sync { type BlockIdFor = <<::Block as Block>::Header as BlockHeader>::Id; type KeyFor = <::Block as Block>::Key; +type AddressFor = <::Block as Block>::Address; type OutputFor = <::Block as Block>::Output; /// A handle to immediately run an iteration of a task. @@ -171,8 +172,8 @@ pub(crate) trait ContinuallyRan: Sized { } /// A representation of a scanner. -pub struct Scanner; -impl Scanner { +pub struct Scanner(PhantomData); +impl Scanner { /// Create a new scanner. /// /// This will begin its execution, spawning several asynchronous tasks. @@ -189,9 +190,12 @@ impl Scanner { &mut self, block_number: u64, key_to_activate: Option<()>, - forwarded_outputs: Vec<()>, - eventualities_created: Vec<()>, - ) { + ) -> Vec> { + todo!("TODO") + } + + /// Register the Eventualities caused by a block. + pub fn register_eventualities(&mut self, block_number: u64, eventualities: Vec<()>) { todo!("TODO") } } diff --git a/processor/scanner/src/report.rs b/processor/scanner/src/report.rs index b2220895..3c22556c 100644 --- a/processor/scanner/src/report.rs +++ b/processor/scanner/src/report.rs @@ -5,7 +5,7 @@ use serai_db::{Db, DbTxn}; -use primitives::{Id, Block}; +use primitives::{Id, OutputType, Block}; // TODO: Localize to ReportDb? use crate::{db::ScannerDb, ScannerFeed, ContinuallyRan}; @@ -40,20 +40,8 @@ impl ContinuallyRan for ReportTask { for b in next_to_potentially_report ..= highest_reportable { if ScannerDb::::is_block_notable(&self.db, b) { - let outputs = todo!("TODO"); - let in_instructions_to_report = vec![]; - for output in outputs { - match output.kind() { - // These do get reported since the scanner eliminates any which shouldn't be reported - OutputType::External => todo!("TODO"), - // These do not get reported in Batches - OutputType::Branch | OutputType::Change => {} - // These now get reported if they're legitimately forwarded - OutputType::Forwarded => { - todo!("TODO") - } - } - } + let in_instructions = todo!("TODO"); + // TODO: Also pull the InInstructions from forwarding todo!("TODO: Make Batches, which requires handling Forwarded within this crate"); } diff --git a/processor/scanner/src/scan.rs b/processor/scanner/src/scan.rs index 137f708a..13332586 100644 --- a/processor/scanner/src/scan.rs +++ b/processor/scanner/src/scan.rs @@ -1,16 +1,28 @@ +use group::GroupEncoding; + +use scale::{Encode, Decode}; use serai_db::{Db, DbTxn}; -use primitives::{Id, ReceivedOutput, Block}; +use serai_primitives::{MAX_DATA_LEN, ExternalAddress}; +use serai_in_instructions_primitives::{ + Shorthand, RefundableInInstruction, InInstruction, InInstructionWithBalance, +}; + +use primitives::{Id, OutputType, ReceivedOutput, Block}; // TODO: Localize to ScanDb? -use crate::{db::ScannerDb, ScannerFeed, ContinuallyRan}; +use crate::{ + lifetime::LifetimeStage, + db::{OutputWithInInstruction, ScannerDb}, + ScannerFeed, AddressFor, OutputFor, ContinuallyRan, +}; // Construct an InInstruction from an external output. // -// Also returns the address to refund the coins to upon error. -fn in_instruction_from_output( - output: &impl ReceivedOutput, -) -> (Option, Option) { +// Also returns the address to return the coins to upon error. +fn in_instruction_from_output( + output: &OutputFor, +) -> (Option>, Option) { assert_eq!(output.kind(), OutputType::External); let presumed_origin = output.presumed_origin(); @@ -18,7 +30,7 @@ fn in_instruction_from_output( let mut data = output.data(); let max_data_len = usize::try_from(MAX_DATA_LEN).unwrap(); if data.len() > max_data_len { - error!( + log::info!( "data in output {} exceeded MAX_DATA_LEN ({MAX_DATA_LEN}): {}. skipping", hex::encode(output.id()), data.len(), @@ -29,14 +41,14 @@ fn in_instruction_from_output( let shorthand = match Shorthand::decode(&mut data) { Ok(shorthand) => shorthand, Err(e) => { - info!("data in output {} wasn't valid shorthand: {e:?}", hex::encode(output.id())); + log::info!("data in output {} wasn't valid shorthand: {e:?}", hex::encode(output.id())); return (presumed_origin, None); } }; let instruction = match RefundableInInstruction::try_from(shorthand) { Ok(instruction) => instruction, Err(e) => { - info!( + log::info!( "shorthand in output {} wasn't convertible to a RefundableInInstruction: {e:?}", hex::encode(output.id()) ); @@ -45,7 +57,7 @@ fn in_instruction_from_output( }; ( - instruction.origin.and_then(|addr| A::try_from(addr).ok()).or(presumed_origin), + instruction.origin.and_then(|addr| AddressFor::::try_from(addr).ok()).or(presumed_origin), Some(instruction.instruction), ) } @@ -174,18 +186,25 @@ impl ContinuallyRan for ScanForOutputsTask { if balance.amount.0 < self.feed.dust(balance.coin).0 { continue; } + + balance }; - // Decode and save the InInstruction/refund addr for this output - match in_instruction_from_output::(output) { - (refund_addr, Some(instruction)) => { - let instruction = InInstructionWithBalance { instruction, balance: balance_to_use }; + // Decode and save the InInstruction/return addr for this output + match in_instruction_from_output::(&output) { + (return_address, Some(instruction)) => { + let in_instruction = + InInstructionWithBalance { instruction, balance: balance_to_use }; // TODO: Make a proper struct out of this - in_instructions.push((output.id(), refund_addr, instruction)); + in_instructions.push(OutputWithInInstruction { + output, + return_address, + in_instruction, + }); todo!("TODO: Save to be reported") } - (Some(refund_addr), None) => todo!("TODO: Queue refund"), - // Since we didn't receive an instruction nor can we refund this, accumulate it + (Some(return_addr), None) => todo!("TODO: Queue return"), + // Since we didn't receive an instruction nor can we return this, accumulate it (None, None) => {} } }