mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Add dedicated BatchSignId
This commit is contained in:
@@ -16,7 +16,7 @@ use crate::tributary::TributarySpec;
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub enum Topic {
|
||||
Dkg,
|
||||
Batch([u8; 32]),
|
||||
Batch([u8; 5]),
|
||||
Sign([u8; 32]),
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ use tributary::Signed;
|
||||
|
||||
use processor_messages::{
|
||||
key_gen::{self, KeyGenId},
|
||||
coordinator,
|
||||
coordinator::{self, BatchSignId},
|
||||
sign::{self, SignId},
|
||||
};
|
||||
|
||||
@@ -370,7 +370,7 @@ pub(crate) async fn handle_application_tx<
|
||||
// Because this Batch has achieved synchrony, its batch ID should be authorized
|
||||
TributaryDb::<D>::recognize_topic(txn, genesis, Topic::Batch(batch));
|
||||
let nonce = NonceDecider::<D>::handle_batch(txn, genesis, batch);
|
||||
recognized_id(spec.set(), genesis, RecognizedIdType::Batch, batch, nonce).await;
|
||||
recognized_id(spec.set(), genesis, RecognizedIdType::Batch, batch.to_vec(), nonce).await;
|
||||
}
|
||||
|
||||
Transaction::SubstrateBlock(block) => {
|
||||
@@ -382,7 +382,7 @@ pub(crate) async fn handle_application_tx<
|
||||
let nonces = NonceDecider::<D>::handle_substrate_block(txn, genesis, &plan_ids);
|
||||
for (nonce, id) in nonces.into_iter().zip(plan_ids.into_iter()) {
|
||||
TributaryDb::<D>::recognize_topic(txn, genesis, Topic::Sign(id));
|
||||
recognized_id(spec.set(), genesis, RecognizedIdType::Plan, id, nonce).await;
|
||||
recognized_id(spec.set(), genesis, RecognizedIdType::Plan, id.to_vec(), nonce).await;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,12 +403,12 @@ pub(crate) async fn handle_application_tx<
|
||||
Accumulation::Ready(DataSet::Participating(mut preprocesses)) => {
|
||||
unflatten(spec, &mut preprocesses);
|
||||
NonceDecider::<D>::selected_for_signing_batch(txn, genesis, data.plan);
|
||||
let key = TributaryDb::<D>::key_pair(txn, spec.set()).unwrap().0 .0.to_vec();
|
||||
let key = TributaryDb::<D>::key_pair(txn, spec.set()).unwrap().0 .0;
|
||||
processors
|
||||
.send(
|
||||
spec.set().network,
|
||||
coordinator::CoordinatorMessage::BatchPreprocesses {
|
||||
id: SignId { key, id: data.plan, attempt: data.attempt },
|
||||
id: BatchSignId { key, id: data.plan, attempt: data.attempt },
|
||||
preprocesses,
|
||||
},
|
||||
)
|
||||
@@ -434,12 +434,12 @@ pub(crate) async fn handle_application_tx<
|
||||
) {
|
||||
Accumulation::Ready(DataSet::Participating(mut shares)) => {
|
||||
unflatten(spec, &mut shares);
|
||||
let key = TributaryDb::<D>::key_pair(txn, spec.set()).unwrap().0 .0.to_vec();
|
||||
let key = TributaryDb::<D>::key_pair(txn, spec.set()).unwrap().0 .0;
|
||||
processors
|
||||
.send(
|
||||
spec.set().network,
|
||||
coordinator::CoordinatorMessage::BatchShares {
|
||||
id: SignId { key, id: data.plan, attempt: data.attempt },
|
||||
id: BatchSignId { key, id: data.plan, attempt: data.attempt },
|
||||
shares: shares
|
||||
.into_iter()
|
||||
.map(|(validator, share)| (validator, share.try_into().unwrap()))
|
||||
|
||||
@@ -167,8 +167,8 @@ impl TributarySpec {
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct SignData {
|
||||
pub plan: [u8; 32],
|
||||
pub struct SignData<const N: usize> {
|
||||
pub plan: [u8; N],
|
||||
pub attempt: u32,
|
||||
|
||||
pub data: Vec<Vec<u8>>,
|
||||
@@ -176,9 +176,9 @@ pub struct SignData {
|
||||
pub signed: Signed,
|
||||
}
|
||||
|
||||
impl ReadWrite for SignData {
|
||||
impl<const N: usize> ReadWrite for SignData<N> {
|
||||
fn read<R: io::Read>(reader: &mut R) -> io::Result<Self> {
|
||||
let mut plan = [0; 32];
|
||||
let mut plan = [0; N];
|
||||
reader.read_exact(&mut plan)?;
|
||||
|
||||
let mut attempt = [0; 4];
|
||||
@@ -249,16 +249,16 @@ pub enum Transaction {
|
||||
// which would be binding over the block hash and automatically achieve synchrony on all
|
||||
// relevant batches. ExternalBlock was removed for this due to complexity around the pipeline
|
||||
// with the current processor, yet it would still be an improvement.
|
||||
Batch([u8; 32], [u8; 32]),
|
||||
Batch([u8; 32], [u8; 5]),
|
||||
// When a Serai block is finalized, with the contained batches, we can allow the associated plan
|
||||
// IDs
|
||||
SubstrateBlock(u64),
|
||||
|
||||
BatchPreprocess(SignData),
|
||||
BatchShare(SignData),
|
||||
BatchPreprocess(SignData<5>),
|
||||
BatchShare(SignData<5>),
|
||||
|
||||
SignPreprocess(SignData),
|
||||
SignShare(SignData),
|
||||
SignPreprocess(SignData<32>),
|
||||
SignShare(SignData<32>),
|
||||
// This is defined as an Unsigned transaction in order to de-duplicate SignCompleted amongst
|
||||
// reporters (who should all report the same thing)
|
||||
// We do still track the signer in order to prevent a single signer from publishing arbitrarily
|
||||
@@ -367,7 +367,7 @@ impl ReadWrite for Transaction {
|
||||
3 => {
|
||||
let mut block = [0; 32];
|
||||
reader.read_exact(&mut block)?;
|
||||
let mut batch = [0; 32];
|
||||
let mut batch = [0; 5];
|
||||
reader.read_exact(&mut batch)?;
|
||||
Ok(Transaction::Batch(block, batch))
|
||||
}
|
||||
|
||||
@@ -27,31 +27,25 @@ impl<D: Db> NonceDecider<D> {
|
||||
next
|
||||
}
|
||||
|
||||
fn item_nonce_key(genesis: [u8; 32], code: u8, id: [u8; 32]) -> Vec<u8> {
|
||||
fn item_nonce_key(genesis: [u8; 32], code: u8, id: &[u8]) -> Vec<u8> {
|
||||
D::key(
|
||||
b"coordinator_tributary_nonce",
|
||||
b"item",
|
||||
[genesis.as_slice(), [code].as_ref(), id.as_ref()].concat(),
|
||||
[genesis.as_slice(), [code].as_ref(), id].concat(),
|
||||
)
|
||||
}
|
||||
fn set_nonce(
|
||||
txn: &mut D::Transaction<'_>,
|
||||
genesis: [u8; 32],
|
||||
code: u8,
|
||||
id: [u8; 32],
|
||||
nonce: u32,
|
||||
) {
|
||||
fn set_nonce(txn: &mut D::Transaction<'_>, genesis: [u8; 32], code: u8, id: &[u8], nonce: u32) {
|
||||
txn.put(Self::item_nonce_key(genesis, code, id), nonce.to_le_bytes())
|
||||
}
|
||||
fn db_nonce<G: Get>(getter: &G, genesis: [u8; 32], code: u8, id: [u8; 32]) -> Option<u32> {
|
||||
fn db_nonce<G: Get>(getter: &G, genesis: [u8; 32], code: u8, id: &[u8]) -> Option<u32> {
|
||||
getter
|
||||
.get(Self::item_nonce_key(genesis, code, id))
|
||||
.map(|bytes| u32::from_le_bytes(bytes.try_into().unwrap()))
|
||||
}
|
||||
|
||||
pub fn handle_batch(txn: &mut D::Transaction<'_>, genesis: [u8; 32], batch: [u8; 32]) -> u32 {
|
||||
pub fn handle_batch(txn: &mut D::Transaction<'_>, genesis: [u8; 32], batch: [u8; 5]) -> u32 {
|
||||
let nonce_for = Self::allocate_nonce(txn, genesis);
|
||||
Self::set_nonce(txn, genesis, BATCH_CODE, batch, nonce_for);
|
||||
Self::set_nonce(txn, genesis, BATCH_CODE, &batch, nonce_for);
|
||||
nonce_for
|
||||
}
|
||||
// TODO: The processor won't yield shares for this if the signing protocol aborts. We need to
|
||||
@@ -60,10 +54,10 @@ impl<D: Db> NonceDecider<D> {
|
||||
pub fn selected_for_signing_batch(
|
||||
txn: &mut D::Transaction<'_>,
|
||||
genesis: [u8; 32],
|
||||
batch: [u8; 32],
|
||||
batch: [u8; 5],
|
||||
) {
|
||||
let nonce_for = Self::allocate_nonce(txn, genesis);
|
||||
Self::set_nonce(txn, genesis, BATCH_SIGNING_CODE, batch, nonce_for);
|
||||
Self::set_nonce(txn, genesis, BATCH_SIGNING_CODE, &batch, nonce_for);
|
||||
}
|
||||
|
||||
pub fn handle_substrate_block(
|
||||
@@ -74,7 +68,7 @@ impl<D: Db> NonceDecider<D> {
|
||||
let mut res = Vec::with_capacity(plans.len());
|
||||
for plan in plans {
|
||||
let nonce_for = Self::allocate_nonce(txn, genesis);
|
||||
Self::set_nonce(txn, genesis, PLAN_CODE, *plan, nonce_for);
|
||||
Self::set_nonce(txn, genesis, PLAN_CODE, plan, nonce_for);
|
||||
res.push(nonce_for);
|
||||
}
|
||||
res
|
||||
@@ -86,7 +80,7 @@ impl<D: Db> NonceDecider<D> {
|
||||
plan: [u8; 32],
|
||||
) {
|
||||
let nonce_for = Self::allocate_nonce(txn, genesis);
|
||||
Self::set_nonce(txn, genesis, PLAN_SIGNING_CODE, plan, nonce_for);
|
||||
Self::set_nonce(txn, genesis, PLAN_SIGNING_CODE, &plan, nonce_for);
|
||||
}
|
||||
|
||||
pub fn nonce<G: Get>(getter: &G, genesis: [u8; 32], tx: &Transaction) -> Option<Option<u32>> {
|
||||
@@ -109,20 +103,20 @@ impl<D: Db> NonceDecider<D> {
|
||||
|
||||
Transaction::BatchPreprocess(data) => {
|
||||
assert_eq!(data.attempt, 0);
|
||||
Some(Self::db_nonce(getter, genesis, BATCH_CODE, data.plan))
|
||||
Some(Self::db_nonce(getter, genesis, BATCH_CODE, &data.plan))
|
||||
}
|
||||
Transaction::BatchShare(data) => {
|
||||
assert_eq!(data.attempt, 0);
|
||||
Some(Self::db_nonce(getter, genesis, BATCH_SIGNING_CODE, data.plan))
|
||||
Some(Self::db_nonce(getter, genesis, BATCH_SIGNING_CODE, &data.plan))
|
||||
}
|
||||
|
||||
Transaction::SignPreprocess(data) => {
|
||||
assert_eq!(data.attempt, 0);
|
||||
Some(Self::db_nonce(getter, genesis, PLAN_CODE, data.plan))
|
||||
Some(Self::db_nonce(getter, genesis, PLAN_CODE, &data.plan))
|
||||
}
|
||||
Transaction::SignShare(data) => {
|
||||
assert_eq!(data.attempt, 0);
|
||||
Some(Self::db_nonce(getter, genesis, PLAN_SIGNING_CODE, data.plan))
|
||||
Some(Self::db_nonce(getter, genesis, PLAN_SIGNING_CODE, &data.plan))
|
||||
}
|
||||
|
||||
Transaction::SignCompleted { .. } => None,
|
||||
|
||||
@@ -35,10 +35,10 @@ pub enum RecognizedIdType {
|
||||
}
|
||||
|
||||
pub(crate) trait RIDTrait<FRid>:
|
||||
Clone + Fn(ValidatorSet, [u8; 32], RecognizedIdType, [u8; 32], u32) -> FRid
|
||||
Clone + Fn(ValidatorSet, [u8; 32], RecognizedIdType, Vec<u8>, u32) -> FRid
|
||||
{
|
||||
}
|
||||
impl<FRid, F: Clone + Fn(ValidatorSet, [u8; 32], RecognizedIdType, [u8; 32], u32) -> FRid>
|
||||
impl<FRid, F: Clone + Fn(ValidatorSet, [u8; 32], RecognizedIdType, Vec<u8>, u32) -> FRid>
|
||||
RIDTrait<FRid> for F
|
||||
{
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user