Remove borsh from dkg

It pulls in a lot of bespoke dependencies for little utility directly present.

Moves the necessary code into the processor.
This commit is contained in:
Luke Parker
2025-09-27 02:07:18 -04:00
parent 3512b3832d
commit 08f6af8bb9
6 changed files with 107 additions and 43 deletions

1
Cargo.lock generated
View File

@@ -2435,7 +2435,6 @@ dependencies = [
name = "dkg" name = "dkg"
version = "0.6.1" version = "0.6.1"
dependencies = [ dependencies = [
"borsh",
"ciphersuite 0.4.2", "ciphersuite 0.4.2",
"std-shims 0.1.5", "std-shims 0.1.5",
"thiserror 2.0.16", "thiserror 2.0.16",

View File

@@ -23,19 +23,12 @@ thiserror = { version = "2", default-features = false }
std-shims = { version = "0.1", path = "../../common/std-shims", default-features = false, features = ["alloc"] } 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"] } ciphersuite = { path = "../ciphersuite", version = "^0.4.1", default-features = false, features = ["alloc"] }
[features] [features]
std = [ std = [
"thiserror/std", "thiserror/std",
"std-shims/std", "std-shims/std",
"borsh?/std",
"ciphersuite/std", "ciphersuite/std",
] ]
borsh = ["dep:borsh"]
default = ["std"] default = ["std"]

View File

@@ -22,7 +22,6 @@ use ciphersuite::{
/// The ID of a participant, defined as a non-zero u16. /// The ID of a participant, defined as a non-zero u16.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Zeroize)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Zeroize)]
#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize))]
pub struct Participant(u16); pub struct Participant(u16);
impl Participant { impl Participant {
/// Create a new Participant identifier from a u16. /// Create a new Participant identifier from a u16.
@@ -129,18 +128,8 @@ pub enum DkgError {
NotParticipating, NotParticipating,
} }
// Manually implements BorshDeserialize so we can enforce it's a valid index
#[cfg(feature = "borsh")]
impl borsh::BorshDeserialize for Participant {
fn deserialize_reader<R: io::Read>(reader: &mut R) -> io::Result<Self> {
Participant::new(u16::deserialize_reader(reader)?)
.ok_or_else(|| io::Error::other("invalid participant"))
}
}
/// Parameters for a multisig. /// Parameters for a multisig.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)] #[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)]
#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize))]
pub struct ThresholdParams { pub struct ThresholdParams {
/// Participants needed to sign on behalf of the group. /// Participants needed to sign on behalf of the group.
t: u16, t: u16,
@@ -210,16 +199,6 @@ impl ThresholdParams {
} }
} }
#[cfg(feature = "borsh")]
impl borsh::BorshDeserialize for ThresholdParams {
fn deserialize_reader<R: io::Read>(reader: &mut R) -> io::Result<Self> {
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. /// A method of interpolation.
#[derive(Clone, PartialEq, Eq, Debug, Zeroize)] #[derive(Clone, PartialEq, Eq, Debug, Zeroize)]
pub enum Interpolation<F: Zeroize + PrimeField> { pub enum Interpolation<F: Zeroize + PrimeField> {

View File

@@ -31,7 +31,15 @@ struct RawParams {
#[derive(BorshSerialize, BorshDeserialize)] #[derive(BorshSerialize, BorshDeserialize)]
pub(crate) struct Participations { pub(crate) struct Participations {
#[borsh(
serialize_with = "messages::borsh_serialize_participant_map",
deserialize_with = "messages::borsh_deserialize_participant_map"
)]
pub(crate) substrate_participations: HashMap<Participant, Vec<u8>>, pub(crate) substrate_participations: HashMap<Participant, Vec<u8>>,
#[borsh(
serialize_with = "messages::borsh_serialize_participant_map",
deserialize_with = "messages::borsh_deserialize_participant_map"
)]
pub(crate) network_participations: HashMap<Participant, Vec<u8>>, pub(crate) network_participations: HashMap<Participant, Vec<u8>>,
} }

View File

@@ -19,11 +19,9 @@ workspace = true
[dependencies] [dependencies]
hex = { version = "0.4", default-features = false, features = ["std"] } hex = { version = "0.4", default-features = false, features = ["std"] }
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] } 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-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
serai-cosign = { package = "serai-cosign-types", path = "../../coordinator/cosign/types" } serai-cosign = { package = "serai-cosign-types", path = "../../coordinator/cosign/types" }

View File

@@ -20,6 +20,44 @@ pub struct SubstrateContext {
pub network_latest_finalized_block: BlockHash, pub network_latest_finalized_block: BlockHash,
} }
pub fn borsh_serialize_participant<W: borsh::io::Write>(
value: &Participant,
writer: &mut W,
) -> borsh::io::Result<()> {
u16::from(*value).serialize(writer)
}
pub fn borsh_deserialize_participant<R: borsh::io::Read>(
reader: &mut R,
) -> borsh::io::Result<Participant> {
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<W: borsh::io::Write>(
value: &HashMap<Participant, Vec<u8>>,
writer: &mut W,
) -> borsh::io::Result<()> {
value
.iter()
.map(|(key, value)| (u16::from(*key), value))
.collect::<HashMap<u16, &Vec<u8>>>()
.serialize(writer)
}
pub fn borsh_deserialize_participant_map<R: borsh::io::Read>(
reader: &mut R,
) -> borsh::io::Result<HashMap<Participant, Vec<u8>>> {
HashMap::<u16, Vec<u8>>::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 { pub mod key_gen {
use super::*; use super::*;
@@ -32,7 +70,15 @@ pub mod key_gen {
/// Received participations for the specified key generation protocol. /// Received participations for the specified key generation protocol.
/// ///
/// This is sent by the Coordinator's Tributary scanner. /// This is sent by the Coordinator's Tributary scanner.
Participation { session: Session, participant: Participant, participation: Vec<u8> }, Participation {
session: Session,
#[borsh(
serialize_with = "borsh_serialize_participant",
deserialize_with = "borsh_deserialize_participant"
)]
participant: Participant,
participation: Vec<u8>,
},
} }
impl core::fmt::Debug for CoordinatorMessage { impl core::fmt::Debug for CoordinatorMessage {
@@ -57,11 +103,25 @@ pub mod key_gen {
#[derive(Clone, BorshSerialize, BorshDeserialize)] #[derive(Clone, BorshSerialize, BorshDeserialize)]
pub enum ProcessorMessage { pub enum ProcessorMessage {
// Participated in the specified key generation protocol. // Participated in the specified key generation protocol.
Participation { session: Session, participation: Vec<u8> }, Participation {
session: Session,
participation: Vec<u8>,
},
// Resulting keys from the specified key generation protocol. // Resulting keys from the specified key generation protocol.
GeneratedKeyPair { session: Session, substrate_key: [u8; 32], network_key: Vec<u8> }, GeneratedKeyPair {
session: Session,
substrate_key: [u8; 32],
network_key: Vec<u8>,
},
// Blame this participant. // 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 { impl core::fmt::Debug for ProcessorMessage {
@@ -124,11 +184,25 @@ pub mod sign {
/// Received preprocesses for the specified signing protocol. /// Received preprocesses for the specified signing protocol.
/// ///
/// This is sent by the Coordinator's Tributary scanner. /// This is sent by the Coordinator's Tributary scanner.
Preprocesses { id: SignId, preprocesses: HashMap<Participant, Vec<u8>> }, Preprocesses {
id: SignId,
#[borsh(
serialize_with = "borsh_serialize_participant_map",
deserialize_with = "borsh_deserialize_participant_map"
)]
preprocesses: HashMap<Participant, Vec<u8>>,
},
// Received shares for the specified signing protocol. // Received shares for the specified signing protocol.
/// ///
/// This is sent by the Coordinator's Tributary scanner. /// This is sent by the Coordinator's Tributary scanner.
Shares { id: SignId, shares: HashMap<Participant, Vec<u8>> }, Shares {
id: SignId,
#[borsh(
serialize_with = "borsh_serialize_participant_map",
deserialize_with = "borsh_deserialize_participant_map"
)]
shares: HashMap<Participant, Vec<u8>>,
},
// Re-attempt a signing protocol. // Re-attempt a signing protocol.
/// ///
/// This is sent by the Coordinator's Tributary re-attempt scheduling logic. /// This is sent by the Coordinator's Tributary re-attempt scheduling logic.
@@ -149,11 +223,24 @@ pub mod sign {
#[derive(Clone, Debug, BorshSerialize, BorshDeserialize)] #[derive(Clone, Debug, BorshSerialize, BorshDeserialize)]
pub enum ProcessorMessage { pub enum ProcessorMessage {
// Participant sent an invalid message during the sign protocol. // 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. // Created preprocesses for the specified signing protocol.
Preprocesses { id: SignId, preprocesses: Vec<Vec<u8>> }, Preprocesses {
id: SignId,
preprocesses: Vec<Vec<u8>>,
},
// Signed shares for the specified signing protocol. // Signed shares for the specified signing protocol.
Shares { id: SignId, shares: Vec<Vec<u8>> }, Shares {
id: SignId,
shares: Vec<Vec<u8>>,
},
} }
} }
@@ -298,7 +385,7 @@ impl CoordinatorMessage {
} }
// Unique since one participation per participant per session // Unique since one participation per participant per session
key_gen::CoordinatorMessage::Participation { session, participant, .. } => { 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) // Unique since we only blame a participant once (as this is fatal)
key_gen::ProcessorMessage::Blame { session, participant } => { key_gen::ProcessorMessage::Blame { session, participant } => {
(2, borsh::to_vec(&(session, participant)).unwrap()) (2, borsh::to_vec(&(session, u16::from(*participant))).unwrap())
} }
}; };