From 08f6af8bb9c54c013824e44a7a41304ae413dd55 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 27 Sep 2025 02:07:18 -0400 Subject: [PATCH] Remove `borsh` from `dkg` It pulls in a lot of bespoke dependencies for little utility directly present. Moves the necessary code into the processor. --- Cargo.lock | 1 - crypto/dkg/Cargo.toml | 7 --- crypto/dkg/src/lib.rs | 21 ------- processor/key-gen/src/db.rs | 8 +++ processor/messages/Cargo.toml | 4 +- processor/messages/src/lib.rs | 109 ++++++++++++++++++++++++++++++---- 6 files changed, 107 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d958063a..3f75344a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2435,7 +2435,6 @@ dependencies = [ name = "dkg" version = "0.6.1" dependencies = [ - "borsh", "ciphersuite 0.4.2", "std-shims 0.1.5", "thiserror 2.0.16", diff --git a/crypto/dkg/Cargo.toml b/crypto/dkg/Cargo.toml index 1c6e3073..86e9ae1c 100644 --- a/crypto/dkg/Cargo.toml +++ b/crypto/dkg/Cargo.toml @@ -23,19 +23,12 @@ thiserror = { version = "2", default-features = false } std-shims = { version = "0.1", path = "../../common/std-shims", default-features = false, features = ["alloc"] } -borsh = { version = "1", default-features = false, features = ["derive", "de_strict_order"], optional = true } - ciphersuite = { path = "../ciphersuite", version = "^0.4.1", default-features = false, features = ["alloc"] } [features] std = [ "thiserror/std", - "std-shims/std", - - "borsh?/std", - "ciphersuite/std", ] -borsh = ["dep:borsh"] default = ["std"] diff --git a/crypto/dkg/src/lib.rs b/crypto/dkg/src/lib.rs index 83700e26..22da54f6 100644 --- a/crypto/dkg/src/lib.rs +++ b/crypto/dkg/src/lib.rs @@ -22,7 +22,6 @@ use ciphersuite::{ /// The ID of a participant, defined as a non-zero u16. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Zeroize)] -#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize))] pub struct Participant(u16); impl Participant { /// Create a new Participant identifier from a u16. @@ -129,18 +128,8 @@ pub enum DkgError { NotParticipating, } -// Manually implements BorshDeserialize so we can enforce it's a valid index -#[cfg(feature = "borsh")] -impl borsh::BorshDeserialize for Participant { - fn deserialize_reader(reader: &mut R) -> io::Result { - Participant::new(u16::deserialize_reader(reader)?) - .ok_or_else(|| io::Error::other("invalid participant")) - } -} - /// Parameters for a multisig. #[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)] -#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize))] pub struct ThresholdParams { /// Participants needed to sign on behalf of the group. t: u16, @@ -210,16 +199,6 @@ impl ThresholdParams { } } -#[cfg(feature = "borsh")] -impl borsh::BorshDeserialize for ThresholdParams { - fn deserialize_reader(reader: &mut R) -> io::Result { - let t = u16::deserialize_reader(reader)?; - let n = u16::deserialize_reader(reader)?; - let i = Participant::deserialize_reader(reader)?; - ThresholdParams::new(t, n, i).map_err(|e| io::Error::other(format!("{e:?}"))) - } -} - /// A method of interpolation. #[derive(Clone, PartialEq, Eq, Debug, Zeroize)] pub enum Interpolation { diff --git a/processor/key-gen/src/db.rs b/processor/key-gen/src/db.rs index 7fc70888..36a9220c 100644 --- a/processor/key-gen/src/db.rs +++ b/processor/key-gen/src/db.rs @@ -31,7 +31,15 @@ struct RawParams { #[derive(BorshSerialize, BorshDeserialize)] pub(crate) struct Participations { + #[borsh( + serialize_with = "messages::borsh_serialize_participant_map", + deserialize_with = "messages::borsh_deserialize_participant_map" + )] pub(crate) substrate_participations: HashMap>, + #[borsh( + serialize_with = "messages::borsh_serialize_participant_map", + deserialize_with = "messages::borsh_deserialize_participant_map" + )] pub(crate) network_participations: HashMap>, } diff --git a/processor/messages/Cargo.toml b/processor/messages/Cargo.toml index f923ef9c..e5cde8e2 100644 --- a/processor/messages/Cargo.toml +++ b/processor/messages/Cargo.toml @@ -19,11 +19,9 @@ workspace = true [dependencies] hex = { version = "0.4", default-features = false, features = ["std"] } - borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] } -dkg = { path = "../../crypto/dkg", default-features = false, features = ["std", "borsh"] } +dkg = { path = "../../crypto/dkg", default-features = false, features = ["std"] } serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] } - serai-cosign = { package = "serai-cosign-types", path = "../../coordinator/cosign/types" } diff --git a/processor/messages/src/lib.rs b/processor/messages/src/lib.rs index 6734302d..30d2d31e 100644 --- a/processor/messages/src/lib.rs +++ b/processor/messages/src/lib.rs @@ -20,6 +20,44 @@ pub struct SubstrateContext { pub network_latest_finalized_block: BlockHash, } +pub fn borsh_serialize_participant( + value: &Participant, + writer: &mut W, +) -> borsh::io::Result<()> { + u16::from(*value).serialize(writer) +} +pub fn borsh_deserialize_participant( + reader: &mut R, +) -> borsh::io::Result { + u16::deserialize_reader(reader).and_then(|p| { + Participant::new(p) + .ok_or_else(|| borsh::io::Error::other("invalid `Participant` despite valid `u16`")) + }) +} + +pub fn borsh_serialize_participant_map( + value: &HashMap>, + writer: &mut W, +) -> borsh::io::Result<()> { + value + .iter() + .map(|(key, value)| (u16::from(*key), value)) + .collect::>>() + .serialize(writer) +} +pub fn borsh_deserialize_participant_map( + reader: &mut R, +) -> borsh::io::Result>> { + HashMap::>::deserialize_reader(reader)? + .into_iter() + .map(|(key, value)| { + Participant::new(key) + .ok_or_else(|| borsh::io::Error::other("invalid `Participant` despite valid `u16` in map")) + .map(|key| (key, value)) + }) + .collect() +} + pub mod key_gen { use super::*; @@ -32,7 +70,15 @@ pub mod key_gen { /// Received participations for the specified key generation protocol. /// /// This is sent by the Coordinator's Tributary scanner. - Participation { session: Session, participant: Participant, participation: Vec }, + Participation { + session: Session, + #[borsh( + serialize_with = "borsh_serialize_participant", + deserialize_with = "borsh_deserialize_participant" + )] + participant: Participant, + participation: Vec, + }, } impl core::fmt::Debug for CoordinatorMessage { @@ -57,11 +103,25 @@ pub mod key_gen { #[derive(Clone, BorshSerialize, BorshDeserialize)] pub enum ProcessorMessage { // Participated in the specified key generation protocol. - Participation { session: Session, participation: Vec }, + Participation { + session: Session, + participation: Vec, + }, // Resulting keys from the specified key generation protocol. - GeneratedKeyPair { session: Session, substrate_key: [u8; 32], network_key: Vec }, + GeneratedKeyPair { + session: Session, + substrate_key: [u8; 32], + network_key: Vec, + }, // Blame this participant. - Blame { session: Session, participant: Participant }, + Blame { + session: Session, + #[borsh( + serialize_with = "borsh_serialize_participant", + deserialize_with = "borsh_deserialize_participant" + )] + participant: Participant, + }, } impl core::fmt::Debug for ProcessorMessage { @@ -124,11 +184,25 @@ pub mod sign { /// Received preprocesses for the specified signing protocol. /// /// This is sent by the Coordinator's Tributary scanner. - Preprocesses { id: SignId, preprocesses: HashMap> }, + Preprocesses { + id: SignId, + #[borsh( + serialize_with = "borsh_serialize_participant_map", + deserialize_with = "borsh_deserialize_participant_map" + )] + preprocesses: HashMap>, + }, // Received shares for the specified signing protocol. /// /// This is sent by the Coordinator's Tributary scanner. - Shares { id: SignId, shares: HashMap> }, + Shares { + id: SignId, + #[borsh( + serialize_with = "borsh_serialize_participant_map", + deserialize_with = "borsh_deserialize_participant_map" + )] + shares: HashMap>, + }, // Re-attempt a signing protocol. /// /// This is sent by the Coordinator's Tributary re-attempt scheduling logic. @@ -149,11 +223,24 @@ pub mod sign { #[derive(Clone, Debug, BorshSerialize, BorshDeserialize)] pub enum ProcessorMessage { // Participant sent an invalid message during the sign protocol. - InvalidParticipant { session: Session, participant: Participant }, + InvalidParticipant { + session: Session, + #[borsh( + serialize_with = "borsh_serialize_participant", + deserialize_with = "borsh_deserialize_participant" + )] + participant: Participant, + }, // Created preprocesses for the specified signing protocol. - Preprocesses { id: SignId, preprocesses: Vec> }, + Preprocesses { + id: SignId, + preprocesses: Vec>, + }, // Signed shares for the specified signing protocol. - Shares { id: SignId, shares: Vec> }, + Shares { + id: SignId, + shares: Vec>, + }, } } @@ -298,7 +385,7 @@ impl CoordinatorMessage { } // Unique since one participation per participant per session key_gen::CoordinatorMessage::Participation { session, participant, .. } => { - (1, borsh::to_vec(&(session, participant)).unwrap()) + (1, borsh::to_vec(&(session, u16::from(*participant))).unwrap()) } }; @@ -375,7 +462,7 @@ impl ProcessorMessage { } // Unique since we only blame a participant once (as this is fatal) key_gen::ProcessorMessage::Blame { session, participant } => { - (2, borsh::to_vec(&(session, participant)).unwrap()) + (2, borsh::to_vec(&(session, u16::from(*participant))).unwrap()) } };