diff --git a/processor/messages/src/lib.rs b/processor/messages/src/lib.rs index 4a191b68..dc7f2939 100644 --- a/processor/messages/src/lib.rs +++ b/processor/messages/src/lib.rs @@ -9,7 +9,7 @@ use dkg::Participant; use serai_primitives::BlockHash; use in_instructions_primitives::{Batch, SignedBatch}; use coins_primitives::OutInstructionWithBalance; -use validator_sets_primitives::{Session, KeyPair}; +use validator_sets_primitives::{Session, KeyPair, Slash}; #[derive(Clone, Copy, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)] pub struct SubstrateContext { @@ -163,7 +163,7 @@ pub mod coordinator { #[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)] pub enum CoordinatorMessage { CosignSubstrateBlock { session: Session, block_number: u64, block: [u8; 32] }, - SignSlashReport { session: Session, report: Vec<([u8; 32], u32)> }, + SignSlashReport { session: Session, report: Vec<Slash> }, } #[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)] diff --git a/processor/signers/src/db.rs b/processor/signers/src/db.rs index ae62c947..66894621 100644 --- a/processor/signers/src/db.rs +++ b/processor/signers/src/db.rs @@ -1,4 +1,4 @@ -use serai_validator_sets_primitives::Session; +use serai_validator_sets_primitives::{Session, Slash}; use serai_db::{Get, DbTxn, create_db, db_channel}; @@ -15,6 +15,9 @@ create_db! { db_channel! { SignersGlobal { + Cosign: (session: Session) -> (u64, [u8; 32]), + SlashReport: (session: Session) -> Vec<Slash>, + CoordinatorToCosignerMessages: (session: Session) -> CoordinatorMessage, CosignerToCoordinatorMessages: (session: Session) -> ProcessorMessage, diff --git a/processor/signers/src/lib.rs b/processor/signers/src/lib.rs index 36e2db2e..de456296 100644 --- a/processor/signers/src/lib.rs +++ b/processor/signers/src/lib.rs @@ -10,7 +10,7 @@ use zeroize::Zeroizing; use ciphersuite::{group::GroupEncoding, Ciphersuite, Ristretto}; use frost::dkg::{ThresholdCore, ThresholdKeys}; -use serai_validator_sets_primitives::Session; +use serai_validator_sets_primitives::{Session, Slash}; use serai_in_instructions_primitives::SignedBatch; use serai_db::{DbTxn, Db}; @@ -139,6 +139,8 @@ impl<ST: SignableTransaction> Signers<ST> { while scanner::CompletedEventualities::try_recv(&mut txn, &external_key).is_some() {} // Drain our DB channels + while db::Cosign::try_recv(&mut txn, session).is_some() {} + while db::SlashReport::try_recv(&mut txn, session).is_some() {} while db::CoordinatorToCosignerMessages::try_recv(&mut txn, session).is_some() {} while db::CosignerToCoordinatorMessages::try_recv(&mut txn, session).is_some() {} while db::CoordinatorToBatchSignerMessages::try_recv(&mut txn, session).is_some() {} @@ -276,7 +278,7 @@ impl<ST: SignableTransaction> Signers<ST> { /// Queue handling a message. /// - /// This is a cheap call and able to be done inline with a higher-level loop. + /// This is a cheap call and able to be done inline from a higher-level loop. pub fn queue_message(&mut self, txn: &mut impl DbTxn, message: &CoordinatorMessage) { let sign_id = message.sign_id(); let tasks = self.tasks.get(&sign_id.session); @@ -307,4 +309,39 @@ impl<ST: SignableTransaction> Signers<ST> { } } } + + /// Cosign a block. + /// + /// This is a cheap call and able to be done inline from a higher-level loop. + pub fn cosign_block( + &mut self, + mut txn: impl DbTxn, + session: Session, + block_number: u64, + block: [u8; 32], + ) { + db::Cosign::send(&mut txn, session, &(block_number, block)); + txn.commit(); + + if let Some(tasks) = self.tasks.get(&session) { + tasks.cosign.run_now(); + } + } + + /// Sign a slash report. + /// + /// This is a cheap call and able to be done inline from a higher-level loop. + pub fn sign_slash_report( + &mut self, + mut txn: impl DbTxn, + session: Session, + slash_report: Vec<Slash>, + ) { + db::SlashReport::send(&mut txn, session, &slash_report); + txn.commit(); + + if let Some(tasks) = self.tasks.get(&session) { + tasks.slash_report.run_now(); + } + } } diff --git a/substrate/validator-sets/primitives/src/lib.rs b/substrate/validator-sets/primitives/src/lib.rs index 90d58c37..341d211f 100644 --- a/substrate/validator-sets/primitives/src/lib.rs +++ b/substrate/validator-sets/primitives/src/lib.rs @@ -103,7 +103,25 @@ pub fn set_keys_message(set: &ValidatorSet, key_pair: &KeyPair) -> Vec<u8> { (b"ValidatorSets-set_keys", set, key_pair).encode() } -pub fn report_slashes_message(set: &ValidatorSet, slashes: &[(Public, u32)]) -> Vec<u8> { +#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct Slash { + #[cfg_attr( + feature = "borsh", + borsh( + serialize_with = "serai_primitives::borsh_serialize_public", + deserialize_with = "serai_primitives::borsh_deserialize_public" + ) + )] + key: Public, + points: u32, +} +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct SlashReport(pub BoundedVec<Slash, ConstU32<{ MAX_KEY_SHARES_PER_SET / 3 }>>); + +pub fn report_slashes_message(set: &ValidatorSet, slashes: &SlashReport) -> Vec<u8> { (b"ValidatorSets-report_slashes", set, slashes).encode() }