mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Route the coordinator, fix race conditions in the signers library
This commit is contained in:
@@ -26,7 +26,6 @@ frost = { package = "modular-frost", path = "../../crypto/frost", version = "^0.
|
||||
|
||||
serai-validator-sets-primitives = { path = "../../substrate/validator-sets/primitives", default-features = false, features = ["std"] }
|
||||
|
||||
hex = { version = "0.4", default-features = false, features = ["std"] }
|
||||
log = { version = "0.4", default-features = false, features = ["std"] }
|
||||
|
||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }
|
||||
|
||||
@@ -10,11 +10,11 @@ use frost::{
|
||||
use serai_validator_sets_primitives::Session;
|
||||
|
||||
use serai_db::{Get, DbTxn, Db, create_db};
|
||||
use messages::sign::{SignId, ProcessorMessage};
|
||||
use messages::sign::{VariantSignId, SignId, ProcessorMessage};
|
||||
|
||||
create_db!(
|
||||
FrostAttemptManager {
|
||||
Attempted: (id: [u8; 32]) -> u32,
|
||||
Attempted: (id: VariantSignId) -> u32,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -28,7 +28,7 @@ pub(crate) struct SigningProtocol<D: Db, M: Clone + PreprocessMachine> {
|
||||
// The key shares we sign with are expected to be continguous from this position.
|
||||
start_i: Participant,
|
||||
// The ID of this signing protocol.
|
||||
id: [u8; 32],
|
||||
id: VariantSignId,
|
||||
// This accepts a vector of `root` machines in order to support signing with multiple key shares.
|
||||
root: Vec<M>,
|
||||
preprocessed: HashMap<u32, (Vec<M::SignMachine>, HashMap<Participant, Vec<u8>>)>,
|
||||
@@ -48,10 +48,10 @@ impl<D: Db, M: Clone + PreprocessMachine> SigningProtocol<D, M> {
|
||||
db: D,
|
||||
session: Session,
|
||||
start_i: Participant,
|
||||
id: [u8; 32],
|
||||
id: VariantSignId,
|
||||
root: Vec<M>,
|
||||
) -> Self {
|
||||
log::info!("starting signing protocol {}", hex::encode(id));
|
||||
log::info!("starting signing protocol {id:?}");
|
||||
|
||||
Self {
|
||||
db,
|
||||
@@ -100,7 +100,7 @@ impl<D: Db, M: Clone + PreprocessMachine> SigningProtocol<D, M> {
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
log::debug!("attemting a new instance of signing protocol {}", hex::encode(self.id));
|
||||
log::debug!("attemting a new instance of signing protocol {:?}", self.id);
|
||||
|
||||
let mut our_preprocesses = HashMap::with_capacity(self.root.len());
|
||||
let mut preprocessed = Vec::with_capacity(self.root.len());
|
||||
@@ -137,7 +137,7 @@ impl<D: Db, M: Clone + PreprocessMachine> SigningProtocol<D, M> {
|
||||
attempt: u32,
|
||||
serialized_preprocesses: HashMap<Participant, Vec<u8>>,
|
||||
) -> Vec<ProcessorMessage> {
|
||||
log::debug!("handling preprocesses for signing protocol {}", hex::encode(self.id));
|
||||
log::debug!("handling preprocesses for signing protocol {:?}", self.id);
|
||||
|
||||
let Some((machines, our_serialized_preprocesses)) = self.preprocessed.remove(&attempt) else {
|
||||
return vec![];
|
||||
@@ -211,8 +211,8 @@ impl<D: Db, M: Clone + PreprocessMachine> SigningProtocol<D, M> {
|
||||
|
||||
assert!(self.shared.insert(attempt, (shared.swap_remove(0), our_shares)).is_none());
|
||||
log::debug!(
|
||||
"successfully handled preprocesses for signing protocol {}, sending shares",
|
||||
hex::encode(self.id)
|
||||
"successfully handled preprocesses for signing protocol {:?}, sending shares",
|
||||
self.id,
|
||||
);
|
||||
msgs.push(ProcessorMessage::Shares {
|
||||
id: SignId { session: self.session, id: self.id, attempt },
|
||||
@@ -229,7 +229,7 @@ impl<D: Db, M: Clone + PreprocessMachine> SigningProtocol<D, M> {
|
||||
attempt: u32,
|
||||
serialized_shares: HashMap<Participant, Vec<u8>>,
|
||||
) -> Result<M::Signature, Vec<ProcessorMessage>> {
|
||||
log::debug!("handling shares for signing protocol {}", hex::encode(self.id));
|
||||
log::debug!("handling shares for signing protocol {:?}", self.id);
|
||||
|
||||
let Some((machine, our_serialized_shares)) = self.shared.remove(&attempt) else { Err(vec![])? };
|
||||
|
||||
@@ -272,13 +272,13 @@ impl<D: Db, M: Clone + PreprocessMachine> SigningProtocol<D, M> {
|
||||
},
|
||||
};
|
||||
|
||||
log::info!("finished signing for protocol {}", hex::encode(self.id));
|
||||
log::info!("finished signing for protocol {:?}", self.id);
|
||||
|
||||
Ok(signature)
|
||||
}
|
||||
|
||||
/// Cleanup the database entries for a specified signing protocol.
|
||||
pub(crate) fn cleanup(txn: &mut impl DbTxn, id: [u8; 32]) {
|
||||
pub(crate) fn cleanup(txn: &mut impl DbTxn, id: VariantSignId) {
|
||||
Attempted::del(txn, id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use frost::{Participant, sign::PreprocessMachine};
|
||||
use serai_validator_sets_primitives::Session;
|
||||
|
||||
use serai_db::{DbTxn, Db};
|
||||
use messages::sign::{ProcessorMessage, CoordinatorMessage};
|
||||
use messages::sign::{VariantSignId, ProcessorMessage, CoordinatorMessage};
|
||||
|
||||
mod individual;
|
||||
use individual::SigningProtocol;
|
||||
@@ -21,7 +21,7 @@ pub enum Response<M: PreprocessMachine> {
|
||||
/// A produced signature.
|
||||
Signature {
|
||||
/// The ID of the protocol this is for.
|
||||
id: [u8; 32],
|
||||
id: VariantSignId,
|
||||
/// The signature.
|
||||
signature: M::Signature,
|
||||
},
|
||||
@@ -32,7 +32,7 @@ pub struct AttemptManager<D: Db, M: Clone + PreprocessMachine> {
|
||||
db: D,
|
||||
session: Session,
|
||||
start_i: Participant,
|
||||
active: HashMap<[u8; 32], SigningProtocol<D, M>>,
|
||||
active: HashMap<VariantSignId, SigningProtocol<D, M>>,
|
||||
}
|
||||
|
||||
impl<D: Db, M: Clone + PreprocessMachine> AttemptManager<D, M> {
|
||||
@@ -46,7 +46,7 @@ impl<D: Db, M: Clone + PreprocessMachine> AttemptManager<D, M> {
|
||||
/// Register a signing protocol to attempt.
|
||||
///
|
||||
/// This ID must be unique across all sessions, attempt managers, protocols, etc.
|
||||
pub fn register(&mut self, id: [u8; 32], machines: Vec<M>) -> Vec<ProcessorMessage> {
|
||||
pub fn register(&mut self, id: VariantSignId, machines: Vec<M>) -> Vec<ProcessorMessage> {
|
||||
let mut protocol =
|
||||
SigningProtocol::new(self.db.clone(), self.session, self.start_i, id, machines);
|
||||
let messages = protocol.attempt(0);
|
||||
@@ -60,11 +60,11 @@ impl<D: Db, M: Clone + PreprocessMachine> AttemptManager<D, M> {
|
||||
/// This does not stop the protocol from being re-registered and further worked on (with
|
||||
/// undefined behavior) then. The higher-level context must never call `register` again with this
|
||||
/// ID accordingly.
|
||||
pub fn retire(&mut self, txn: &mut impl DbTxn, id: [u8; 32]) {
|
||||
pub fn retire(&mut self, txn: &mut impl DbTxn, id: VariantSignId) {
|
||||
if self.active.remove(&id).is_none() {
|
||||
log::info!("retiring protocol {}, which we didn't register/already retired", hex::encode(id));
|
||||
log::info!("retiring protocol {id:?}, which we didn't register/already retired");
|
||||
} else {
|
||||
log::info!("retired signing protocol {}", hex::encode(id));
|
||||
log::info!("retired signing protocol {id:?}");
|
||||
}
|
||||
SigningProtocol::<D, M>::cleanup(txn, id);
|
||||
}
|
||||
@@ -79,8 +79,8 @@ impl<D: Db, M: Clone + PreprocessMachine> AttemptManager<D, M> {
|
||||
CoordinatorMessage::Preprocesses { id, preprocesses } => {
|
||||
let Some(protocol) = self.active.get_mut(&id.id) else {
|
||||
log::trace!(
|
||||
"handling preprocesses for signing protocol {}, which we're not actively running",
|
||||
hex::encode(id.id)
|
||||
"handling preprocesses for signing protocol {:?}, which we're not actively running",
|
||||
id.id,
|
||||
);
|
||||
return Response::Messages(vec![]);
|
||||
};
|
||||
@@ -89,8 +89,8 @@ impl<D: Db, M: Clone + PreprocessMachine> AttemptManager<D, M> {
|
||||
CoordinatorMessage::Shares { id, shares } => {
|
||||
let Some(protocol) = self.active.get_mut(&id.id) else {
|
||||
log::trace!(
|
||||
"handling shares for signing protocol {}, which we're not actively running",
|
||||
hex::encode(id.id)
|
||||
"handling shares for signing protocol {:?}, which we're not actively running",
|
||||
id.id,
|
||||
);
|
||||
return Response::Messages(vec![]);
|
||||
};
|
||||
@@ -102,8 +102,8 @@ impl<D: Db, M: Clone + PreprocessMachine> AttemptManager<D, M> {
|
||||
CoordinatorMessage::Reattempt { id } => {
|
||||
let Some(protocol) = self.active.get_mut(&id.id) else {
|
||||
log::trace!(
|
||||
"reattempting signing protocol {}, which we're not actively running",
|
||||
hex::encode(id.id)
|
||||
"reattempting signing protocol {:?}, which we're not actively running",
|
||||
id.id,
|
||||
);
|
||||
return Response::Messages(vec![]);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user