Update serai-processor-signers to VariantSignid::Batch([u8; 32])

This commit is contained in:
Luke Parker
2025-01-07 15:25:32 -05:00
parent 257f691277
commit 47a4e534ef
5 changed files with 51 additions and 35 deletions

1
Cargo.lock generated
View File

@@ -8996,6 +8996,7 @@ dependencies = [
name = "serai-processor-signers" name = "serai-processor-signers"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"blake2",
"borsh", "borsh",
"ciphersuite", "ciphersuite",
"frost-schnorrkel", "frost-schnorrkel",

View File

@@ -24,6 +24,7 @@ workspace = true
rand_core = { version = "0.6", default-features = false } rand_core = { version = "0.6", default-features = false }
zeroize = { version = "1", default-features = false, features = ["std"] } zeroize = { version = "1", default-features = false, features = ["std"] }
blake2 = { version = "0.10", default-features = false, features = ["std"] }
ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, features = ["std"] } ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, features = ["std"] }
frost = { package = "modular-frost", path = "../../crypto/frost", default-features = false } frost = { package = "modular-frost", path = "../../crypto/frost", default-features = false }
frost-schnorrkel = { path = "../../crypto/schnorrkel", default-features = false } frost-schnorrkel = { path = "../../crypto/schnorrkel", default-features = false }

View File

@@ -5,8 +5,9 @@ use serai_db::{Get, DbTxn, create_db};
create_db! { create_db! {
SignersBatch { SignersBatch {
ActiveSigningProtocols: (session: Session) -> Vec<u32>, ActiveSigningProtocols: (session: Session) -> Vec<[u8; 32]>,
Batches: (id: u32) -> Batch, BatchHash: (id: u32) -> [u8; 32],
Batches: (hash: [u8; 32]) -> Batch,
SignedBatches: (id: u32) -> SignedBatch, SignedBatches: (id: u32) -> SignedBatch,
LastAcknowledgedBatch: () -> u32, LastAcknowledgedBatch: () -> u32,
} }

View File

@@ -1,9 +1,12 @@
use core::future::Future; use core::future::Future;
use std::collections::HashSet; use std::collections::HashSet;
use blake2::{digest::typenum::U32, Digest, Blake2b};
use ciphersuite::{group::GroupEncoding, Ristretto}; use ciphersuite::{group::GroupEncoding, Ristretto};
use frost::dkg::ThresholdKeys; use frost::dkg::ThresholdKeys;
use scale::Encode;
use serai_validator_sets_primitives::Session; use serai_validator_sets_primitives::Session;
use serai_in_instructions_primitives::{SignedBatch, batch_message}; use serai_in_instructions_primitives::{SignedBatch, batch_message};
@@ -40,7 +43,7 @@ pub(crate) struct BatchSignerTask<D: Db, E: GroupEncoding> {
external_key: E, external_key: E,
keys: Vec<ThresholdKeys<Ristretto>>, keys: Vec<ThresholdKeys<Ristretto>>,
active_signing_protocols: HashSet<u32>, active_signing_protocols: HashSet<[u8; 32]>,
attempt_manager: AttemptManager<D, WrappedSchnorrkelMachine>, attempt_manager: AttemptManager<D, WrappedSchnorrkelMachine>,
} }
@@ -63,7 +66,6 @@ impl<D: Db, E: GroupEncoding> BatchSignerTask<D, E> {
active_signing_protocols.insert(id); active_signing_protocols.insert(id);
let batch = Batches::get(&db, id).unwrap(); let batch = Batches::get(&db, id).unwrap();
assert_eq!(batch.id, id);
let mut machines = Vec::with_capacity(keys.len()); let mut machines = Vec::with_capacity(keys.len());
for keys in &keys { for keys in &keys {
@@ -90,19 +92,21 @@ impl<D: Db, E: Send + GroupEncoding> ContinuallyRan for BatchSignerTask<D, E> {
iterated = true; iterated = true;
// Save this to the database as a transaction to sign // Save this to the database as a transaction to sign
self.active_signing_protocols.insert(batch.id); let batch_hash = <[u8; 32]>::from(Blake2b::<U32>::digest(batch.encode()));
self.active_signing_protocols.insert(batch_hash);
ActiveSigningProtocols::set( ActiveSigningProtocols::set(
&mut txn, &mut txn,
self.session, self.session,
&self.active_signing_protocols.iter().copied().collect(), &self.active_signing_protocols.iter().copied().collect(),
); );
Batches::set(&mut txn, batch.id, &batch); BatchHash::set(&mut txn, batch.id, &batch_hash);
Batches::set(&mut txn, batch_hash, &batch);
let mut machines = Vec::with_capacity(self.keys.len()); let mut machines = Vec::with_capacity(self.keys.len());
for keys in &self.keys { for keys in &self.keys {
machines.push(WrappedSchnorrkelMachine::new(keys.clone(), batch_message(&batch))); machines.push(WrappedSchnorrkelMachine::new(keys.clone(), batch_message(&batch)));
} }
for msg in self.attempt_manager.register(VariantSignId::Batch(batch.id), machines) { for msg in self.attempt_manager.register(VariantSignId::Batch(batch_hash), machines) {
BatchSignerToCoordinatorMessages::send(&mut txn, self.session, &msg); BatchSignerToCoordinatorMessages::send(&mut txn, self.session, &msg);
} }
@@ -112,48 +116,57 @@ impl<D: Db, E: Send + GroupEncoding> ContinuallyRan for BatchSignerTask<D, E> {
// Check for acknowledged Batches (meaning we should no longer sign for these Batches) // Check for acknowledged Batches (meaning we should no longer sign for these Batches)
loop { loop {
let mut txn = self.db.txn(); let mut txn = self.db.txn();
let Some(id) = AcknowledgedBatches::try_recv(&mut txn, &self.external_key) else { let batch_hash = {
let Some(batch_id) = AcknowledgedBatches::try_recv(&mut txn, &self.external_key) else {
break; break;
}; };
{
let last_acknowledged = LastAcknowledgedBatch::get(&txn);
if Some(id) > last_acknowledged {
LastAcknowledgedBatch::set(&mut txn, &id);
}
}
/* /*
We may have yet to register this signing protocol. We may have yet to register this signing protocol.
While `BatchesToSign` is populated before `AcknowledgedBatches`, we could theoretically While `BatchesToSign` is populated before `AcknowledgedBatches`, we could theoretically
have `BatchesToSign` populated with a new batch _while iterating over have `BatchesToSign` populated with a new batch _while iterating over
`AcknowledgedBatches`_, and then have `AcknowledgedBatched` populated. In that edge case, `AcknowledgedBatches`_, and then have `AcknowledgedBatched` populated. In that edge
we will see the acknowledgement notification before we see the transaction. case, we will see the acknowledgement notification before we see the transaction.
In such a case, we break (dropping the txn, re-queueing the acknowledgement notification). In such a case, we break (dropping the txn, re-queueing the acknowledgement
On the task's next iteration, we'll process the Batch from `BatchesToSign` and be notification). On the task's next iteration, we'll process the Batch from
able to make progress. `BatchesToSign` and be able to make progress.
*/ */
if !self.active_signing_protocols.remove(&id) { let Some(batch_hash) = BatchHash::take(&mut txn, batch_id) else {
drop(txn);
break; break;
} };
batch_hash
};
let batch =
Batches::take(&mut txn, batch_hash).expect("BatchHash populated but not Batches");
iterated = true; iterated = true;
// Since it was, remove this as an active signing protocol // Update the last acknowledged Batch
{
let last_acknowledged = LastAcknowledgedBatch::get(&txn);
if Some(batch.id) > last_acknowledged {
LastAcknowledgedBatch::set(&mut txn, &batch.id);
}
}
// Remove this as an active signing protocol
assert!(self.active_signing_protocols.remove(&batch_hash));
ActiveSigningProtocols::set( ActiveSigningProtocols::set(
&mut txn, &mut txn,
self.session, self.session,
&self.active_signing_protocols.iter().copied().collect(), &self.active_signing_protocols.iter().copied().collect(),
); );
// Clean up the database
Batches::del(&mut txn, id); // Clean up SignedBatches
SignedBatches::del(&mut txn, id); SignedBatches::del(&mut txn, batch.id);
// We retire with a txn so we either successfully flag this Batch as acknowledged, and // We retire with a txn so we either successfully flag this Batch as acknowledged, and
// won't re-register it (making this retire safe), or we don't flag it, meaning we will // won't re-register it (making this retire safe), or we don't flag it, meaning we will
// re-register it, yet that's safe as we have yet to retire it // re-register it, yet that's safe as we have yet to retire it
self.attempt_manager.retire(&mut txn, VariantSignId::Batch(id)); self.attempt_manager.retire(&mut txn, VariantSignId::Batch(batch_hash));
txn.commit(); txn.commit();
} }

View File

@@ -143,7 +143,7 @@ impl<D: Db, C: Coordinator> ContinuallyRan for CoordinatorTask<D, C> {
// the prior Batch(es) (and accordingly didn't publish them) // the prior Batch(es) (and accordingly didn't publish them)
let last_batch = let last_batch =
crate::batch::last_acknowledged_batch(&txn).max(db::LastPublishedBatch::get(&txn)); crate::batch::last_acknowledged_batch(&txn).max(db::LastPublishedBatch::get(&txn));
let mut next_batch = last_batch.map_or(0, |id| id + 1); let mut next_batch = last_batch.map(|id| id + 1).unwrap_or(0);
while let Some(batch) = crate::batch::signed_batch(&txn, next_batch) { while let Some(batch) = crate::batch::signed_batch(&txn, next_batch) {
iterated = true; iterated = true;
db::LastPublishedBatch::set(&mut txn, &batch.batch.id); db::LastPublishedBatch::set(&mut txn, &batch.batch.id);