diff --git a/processor/bin/src/lib.rs b/processor/bin/src/lib.rs index 662eafb9..86a3a0cd 100644 --- a/processor/bin/src/lib.rs +++ b/processor/bin/src/lib.rs @@ -270,32 +270,43 @@ pub async fn main_loop< // This is a cheap call signers.retire_session(txn, session, &key) } - messages::substrate::CoordinatorMessage::BlockWithBatchAcknowledgement { - block: _, - batch_id, - in_instruction_succeededs, - burns, + messages::substrate::CoordinatorMessage::Block { + serai_block_number: _, + batches, + mut burns, } => { - let mut txn = txn.take().unwrap(); let scanner = scanner.as_mut().unwrap(); - let key_to_activate = KeyToActivate::>::try_recv(&mut txn).map(|key| key.0); + + // Substrate sets this limit to prevent DoSs from malicious validator sets + // That bound lets us consume this txn in the following loop body, as an optimization + assert!(batches.len() <= 1); + for messages::substrate::ExecutedBatch { id, in_instructions } in batches { + let key_to_activate = + KeyToActivate::>::try_recv(txn.as_mut().unwrap()).map(|key| key.0); + + /* + `acknowledge_batch` takes burns to optimize handling returns with standard payments. + That's why handling these with a Batch (and not waiting until the following potential + `queue_burns` call makes sense. As for which Batch, the first is equally valid unless + we want to start introspecting (and should be our only Batch anyways). + */ + let mut this_batchs_burns = vec![]; + std::mem::swap(&mut burns, &mut this_batchs_burns); + + // This is a cheap call as it internally just queues this to be done later + let _: () = scanner.acknowledge_batch( + txn.take().unwrap(), + id, + in_instructions, + this_batchs_burns, + key_to_activate, + ); + } + // This is a cheap call as it internally just queues this to be done later - scanner.acknowledge_batch( - txn, - batch_id, - in_instruction_succeededs, - burns, - key_to_activate, - ) - } - messages::substrate::CoordinatorMessage::BlockWithoutBatchAcknowledgement { - block: _, - burns, - } => { - let txn = txn.take().unwrap(); - let scanner = scanner.as_mut().unwrap(); - // This is a cheap call as it internally just queues this to be done later - scanner.queue_burns(txn, burns) + if !burns.is_empty() { + let _: () = scanner.queue_burns(txn.take().unwrap(), burns); + } } }, }; diff --git a/processor/messages/src/lib.rs b/processor/messages/src/lib.rs index 080864dc..659491d4 100644 --- a/processor/messages/src/lib.rs +++ b/processor/messages/src/lib.rs @@ -181,7 +181,6 @@ pub mod coordinator { pub mod substrate { use super::*; - /* TODO #[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)] pub enum InInstructionResult { Succeeded, @@ -189,15 +188,9 @@ pub mod substrate { } #[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)] pub struct ExecutedBatch { - batch_id: u32, - in_instructions: Vec, + pub id: u32, + pub in_instructions: Vec, } - Block { - block: u64, - batches: Vec, - burns: Vec, - } - */ #[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)] pub enum CoordinatorMessage { @@ -205,15 +198,12 @@ pub mod substrate { SetKeys { serai_time: u64, session: Session, key_pair: KeyPair }, /// Slashes reported on the Serai blockchain OR the process timed out. SlashesReported { session: Session }, - /// The data from a block which acknowledged a Batch. - BlockWithBatchAcknowledgement { - block: u64, - batch_id: u32, - in_instruction_succeededs: Vec, + /// A block from Serai with relevance to this processor. + Block { + serai_block_number: u64, + batches: Vec, burns: Vec, }, - /// The data from a block which didn't acknowledge a Batch. - BlockWithoutBatchAcknowledgement { block: u64, burns: Vec }, } #[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)] @@ -323,11 +313,8 @@ impl CoordinatorMessage { let (sub, id) = match msg { substrate::CoordinatorMessage::SetKeys { session, .. } => (0, session.encode()), substrate::CoordinatorMessage::SlashesReported { session } => (1, session.encode()), - substrate::CoordinatorMessage::BlockWithBatchAcknowledgement { block, .. } => { - (2, block.encode()) - } - substrate::CoordinatorMessage::BlockWithoutBatchAcknowledgement { block, .. } => { - (3, block.encode()) + substrate::CoordinatorMessage::Block { serai_block_number, .. } => { + (2, serai_block_number.encode()) } }; diff --git a/processor/scanner/Cargo.toml b/processor/scanner/Cargo.toml index 1ff154cd..09a6a937 100644 --- a/processor/scanner/Cargo.toml +++ b/processor/scanner/Cargo.toml @@ -31,6 +31,8 @@ tokio = { version = "1", default-features = false, features = ["rt-multi-thread" serai-db = { path = "../../common/db" } +messages = { package = "serai-processor-messages", path = "../messages" } + serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] } serai-in-instructions-primitives = { path = "../../substrate/in-instructions/primitives", default-features = false, features = ["std", "borsh"] } serai-coins-primitives = { path = "../../substrate/coins/primitives", default-features = false, features = ["std", "borsh"] } diff --git a/processor/scanner/src/lib.rs b/processor/scanner/src/lib.rs index e591d210..72d661a3 100644 --- a/processor/scanner/src/lib.rs +++ b/processor/scanner/src/lib.rs @@ -429,9 +429,6 @@ impl Scanner { /// This means the specified Batch was ordered on Serai in relation to Burn events, and all /// validators have achieved synchrony on it. /// - /// `in_instruction_succeededs` is the result of executing each InInstruction within this batch, - /// true if it succeeded and false if it did not (and did not cause any state changes on Serai). - /// /// `burns` is a list of Burns to queue with the acknowledgement of this Batch for efficiency's /// sake. Any Burns passed here MUST NOT be passed into any other call of `acknowledge_batch` nor /// `queue_burns`. Doing so will cause them to be executed multiple times. @@ -441,7 +438,7 @@ impl Scanner { &mut self, mut txn: impl DbTxn, batch_id: u32, - in_instruction_succeededs: Vec, + in_instruction_results: Vec, burns: Vec, key_to_activate: Option>, ) { @@ -451,7 +448,7 @@ impl Scanner { substrate::queue_acknowledge_batch::( &mut txn, batch_id, - in_instruction_succeededs, + in_instruction_results, burns, key_to_activate, ); diff --git a/processor/scanner/src/substrate/db.rs b/processor/scanner/src/substrate/db.rs index 18435856..c1a1b0e2 100644 --- a/processor/scanner/src/substrate/db.rs +++ b/processor/scanner/src/substrate/db.rs @@ -12,7 +12,7 @@ use crate::{ScannerFeed, KeyFor}; #[derive(BorshSerialize, BorshDeserialize)] struct AcknowledgeBatchEncodable { batch_id: u32, - in_instruction_succeededs: Vec, + in_instruction_results: Vec, burns: Vec, key_to_activate: Option>, } @@ -25,7 +25,7 @@ enum ActionEncodable { pub(crate) struct AcknowledgeBatch { pub(crate) batch_id: u32, - pub(crate) in_instruction_succeededs: Vec, + pub(crate) in_instruction_results: Vec, pub(crate) burns: Vec, pub(crate) key_to_activate: Option>, } @@ -46,7 +46,7 @@ impl SubstrateDb { pub(crate) fn queue_acknowledge_batch( txn: &mut impl DbTxn, batch_id: u32, - in_instruction_succeededs: Vec, + in_instruction_results: Vec, burns: Vec, key_to_activate: Option>, ) { @@ -54,7 +54,7 @@ impl SubstrateDb { txn, &ActionEncodable::AcknowledgeBatch(AcknowledgeBatchEncodable { batch_id, - in_instruction_succeededs, + in_instruction_results, burns, key_to_activate: key_to_activate.map(|key| key.to_bytes().as_ref().to_vec()), }), @@ -69,12 +69,12 @@ impl SubstrateDb { Some(match action_encodable { ActionEncodable::AcknowledgeBatch(AcknowledgeBatchEncodable { batch_id, - in_instruction_succeededs, + in_instruction_results, burns, key_to_activate, }) => Action::AcknowledgeBatch(AcknowledgeBatch { batch_id, - in_instruction_succeededs, + in_instruction_results, burns, key_to_activate: key_to_activate.map(|key| { let mut repr = as GroupEncoding>::Repr::default(); diff --git a/processor/scanner/src/substrate/mod.rs b/processor/scanner/src/substrate/mod.rs index 89186c69..ce28470d 100644 --- a/processor/scanner/src/substrate/mod.rs +++ b/processor/scanner/src/substrate/mod.rs @@ -16,14 +16,14 @@ use db::*; pub(crate) fn queue_acknowledge_batch( txn: &mut impl DbTxn, batch_id: u32, - in_instruction_succeededs: Vec, + in_instruction_results: Vec, burns: Vec, key_to_activate: Option>, ) { SubstrateDb::::queue_acknowledge_batch( txn, batch_id, - in_instruction_succeededs, + in_instruction_results, burns, key_to_activate, ) @@ -67,7 +67,7 @@ impl ContinuallyRan for SubstrateTask { match action { Action::AcknowledgeBatch(AcknowledgeBatch { batch_id, - in_instruction_succeededs, + in_instruction_results, mut burns, key_to_activate, }) => { @@ -127,16 +127,16 @@ impl ContinuallyRan for SubstrateTask { let return_information = report::take_return_information::(&mut txn, batch_id) .expect("didn't save the return information for Batch we published"); assert_eq!( - in_instruction_succeededs.len(), + in_instruction_results.len(), return_information.len(), "amount of InInstruction succeededs differed from amount of return information saved" ); // We map these into standard Burns - for (succeeded, return_information) in - in_instruction_succeededs.into_iter().zip(return_information) + for (result, return_information) in + in_instruction_results.into_iter().zip(return_information) { - if succeeded { + if result == messages::substrate::InInstructionResult::Succeeded { continue; }