Remove needless transposition in coordinator

This commit is contained in:
Luke Parker 2023-11-15 22:49:58 -05:00
parent c03afbe03e
commit a03a1edbff
No known key found for this signature in database
7 changed files with 56 additions and 71 deletions

View file

@ -257,7 +257,6 @@ impl<D: Db> CosignEvaluator<D> {
} }
} else { } else {
let mut latest_cosigns = self.latest_cosigns.write().await; let mut latest_cosigns = self.latest_cosigns.write().await;
latest_cosigns.insert(cosign.network, (block.number(), cosign)); latest_cosigns.insert(cosign.network, (block.number(), cosign));
self.update_latest_cosign().await; self.update_latest_cosign().await;
} }

View file

@ -431,24 +431,19 @@ async fn handle_processor_message<D: Db, P: P2p>(
.i(pub_key) .i(pub_key)
.expect("processor message to DKG for a session we aren't a validator in"); .expect("processor message to DKG for a session we aren't a validator in");
// TODO: This is [receiver_share][sender_share] and is later transposed to
// [sender_share][receiver_share]. Make this [sender_share][receiver_share] from the
// start?
// `tx_shares` needs to be done here as while it can be serialized from the HashMap // `tx_shares` needs to be done here as while it can be serialized from the HashMap
// without further context, it can't be deserialized without context // without further context, it can't be deserialized without context
let mut tx_shares = Vec::with_capacity(shares.len()); let mut tx_shares = Vec::with_capacity(shares.len());
for i in 1 ..= spec.n() { for shares in &mut shares {
let i = Participant::new(i).unwrap(); tx_shares.push(vec![]);
if our_i.contains(&i) { for i in 1 ..= spec.n() {
for shares in &shares { let i = Participant::new(i).unwrap();
if our_i.contains(&i) {
if shares.contains_key(&i) { if shares.contains_key(&i) {
panic!("processor sent us our own shares"); panic!("processor sent us our own shares");
} }
continue;
} }
continue;
}
tx_shares.push(vec![]);
for shares in &mut shares {
tx_shares.last_mut().unwrap().push( tx_shares.last_mut().unwrap().push(
shares.remove(&i).expect("processor didn't send share for another validator"), shares.remove(&i).expect("processor didn't send share for another validator"),
); );

View file

@ -456,15 +456,11 @@ async fn handle_new_blocks<D: Db, Pro: Processors>(
let maximally_latent_cosign_block = let maximally_latent_cosign_block =
skipped_block.map(|skipped_block| skipped_block + COSIGN_DISTANCE); skipped_block.map(|skipped_block| skipped_block + COSIGN_DISTANCE);
for block in (last_intended_to_cosign_block + 1) ..= latest_number { for block in (last_intended_to_cosign_block + 1) ..= latest_number {
SeraiBlockNumber::set( let actual_block = serai
&mut txn, .block_by_number(block)
serai .await?
.block_by_number(block) .expect("couldn't get block which should've been finalized");
.await? SeraiBlockNumber::set(&mut txn, actual_block.hash(), &block);
.expect("couldn't get block which should've been finalized")
.hash(),
&block,
);
let mut set = false; let mut set = false;
@ -494,10 +490,6 @@ async fn handle_new_blocks<D: Db, Pro: Processors>(
// Get the keys as of the prior block // Get the keys as of the prior block
// That means if this block is setting new keys (which won't lock in until we process this // That means if this block is setting new keys (which won't lock in until we process this
// block), we won't freeze up waiting for the yet-to-be-processed keys to sign this block // block), we won't freeze up waiting for the yet-to-be-processed keys to sign this block
let actual_block = serai
.block_by_number(block)
.await?
.expect("couldn't get block which should've been finalized");
let serai = serai.as_of(actual_block.header().parent_hash.into()); let serai = serai.as_of(actual_block.header().parent_hash.into());
has_no_cosigners = Some(actual_block.clone()); has_no_cosigners = Some(actual_block.clone());

View file

@ -161,12 +161,12 @@ async fn dkg_test() {
for (k, key) in keys.iter().enumerate() { for (k, key) in keys.iter().enumerate() {
let attempt = 0; let attempt = 0;
let mut shares = vec![]; let mut shares = vec![vec![]];
for i in 0 .. keys.len() { for i in 0 .. keys.len() {
if i != k { if i != k {
let mut share = vec![0; 256]; let mut share = vec![0; 256];
OsRng.fill_bytes(&mut share); OsRng.fill_bytes(&mut share);
shares.push(vec![share]); shares.last_mut().unwrap().push(share);
} }
} }
@ -225,7 +225,7 @@ async fn dkg_test() {
let relative_i = i - (if i > l { 1 } else { 0 }); let relative_i = i - (if i > l { 1 } else { 0 });
Some(( Some((
Participant::new((l + 1).try_into().unwrap()).unwrap(), Participant::new((l + 1).try_into().unwrap()).unwrap(),
shares[relative_i][0].clone(), shares[0][relative_i].clone(),
)) ))
} }
} else { } else {

View file

@ -279,38 +279,39 @@ pub(crate) async fn handle_application_tx<
.expect("transaction added to tributary by signer who isn't a participant"); .expect("transaction added to tributary by signer who isn't a participant");
let sender_is_len = u16::from(sender_i.end) - u16::from(sender_i.start); let sender_is_len = u16::from(sender_i.end) - u16::from(sender_i.start);
if shares.len() != (usize::from(spec.n() - sender_is_len)) { if shares.len() != usize::from(sender_is_len) {
fatal_slash::<D>(txn, genesis, signed.signer.to_bytes(), "invalid amount of DKG shares"); fatal_slash::<D>(
txn,
genesis,
signed.signer.to_bytes(),
"invalid amount of DKG shares by key shares",
);
return; return;
} }
for shares in &shares { for shares in &shares {
if shares.len() != usize::from(sender_is_len) { if shares.len() != (usize::from(spec.n() - sender_is_len)) {
fatal_slash::<D>( fatal_slash::<D>(txn, genesis, signed.signer.to_bytes(), "invalid amount of DKG shares");
txn,
genesis,
signed.signer.to_bytes(),
"invalid amount of DKG shares by key shares",
);
return; return;
} }
} }
// Save each share as needed for blame // Save each share as needed for blame
{ {
let from = spec.i(signed.signer).unwrap(); let from_range = spec.i(signed.signer).unwrap();
for (to, shares) in shares.iter().enumerate() { for (from_offset, shares) in shares.iter().enumerate() {
// 0-indexed (the enumeration) to 1-indexed (Participant) let from =
let mut to = u16::try_from(to).unwrap() + 1; Participant::new(u16::from(from_range.start) + u16::try_from(from_offset).unwrap())
// Adjust for the omission of the sender's own shares .unwrap();
if to >= u16::from(from.start) {
to += u16::from(from.end) - u16::from(from.start); for (to_offset, share) in shares.iter().enumerate() {
} // 0-indexed (the enumeration) to 1-indexed (Participant)
let to = Participant::new(to).unwrap(); let mut to = u16::try_from(to_offset).unwrap() + 1;
// Adjust for the omission of the sender's own shares
if to >= u16::from(from_range.start) {
to += u16::from(from_range.end) - u16::from(from_range.start);
}
let to = Participant::new(to).unwrap();
for (sender_share, share) in shares.iter().enumerate() {
let from =
Participant::new(u16::from(from.start) + u16::try_from(sender_share).unwrap())
.unwrap();
TributaryDb::<D>::save_share_for_blame(txn, &genesis, from, to, share); TributaryDb::<D>::save_share_for_blame(txn, &genesis, from, to, share);
} }
} }
@ -331,21 +332,17 @@ pub(crate) async fn handle_application_tx<
our_i_pos -= sender_is_len; our_i_pos -= sender_is_len;
} }
let our_i_pos = usize::from(our_i_pos); let our_i_pos = usize::from(our_i_pos);
let shares = shares shares
.drain( .iter_mut()
our_i_pos .. (our_i_pos + usize::from(u16::from(our_i.end) - u16::from(our_i.start))), .map(|shares| {
) shares
.collect::<Vec<_>>(); .drain(
our_i_pos ..
// Transpose from our shares -> sender shares -> shares to (our_i_pos + usize::from(u16::from(our_i.end) - u16::from(our_i.start))),
// sender shares -> our shares -> shares )
let mut transposed = vec![vec![]; shares[0].len()]; .collect::<Vec<_>>()
for shares in shares { })
for (sender_index, share) in shares.into_iter().enumerate() { .collect()
transposed[sender_index].push(share);
}
}
transposed
}; };
// Drop shares as it's been mutated into invalidity // Drop shares as it's been mutated into invalidity
drop(shares); drop(shares);
@ -519,6 +516,8 @@ pub(crate) async fn handle_application_tx<
}; };
break key_pair.0.into(); break key_pair.0.into();
}; };
let block_number = SeraiBlockNumber::get(txn, hash)
.expect("CosignSubstrateBlock yet didn't save Serai block number");
processors processors
.send( .send(
spec.set().network, spec.set().network,
@ -528,8 +527,7 @@ pub(crate) async fn handle_application_tx<
id: SubstrateSignableId::CosigningSubstrateBlock(hash), id: SubstrateSignableId::CosigningSubstrateBlock(hash),
attempt: 0, attempt: 0,
}, },
block_number: SeraiBlockNumber::get(txn, hash) block_number,
.expect("CosignSubstrateBlock yet didn't save Serai block number"),
}, },
) )
.await; .await;

View file

@ -243,7 +243,7 @@ pub enum Transaction {
DkgCommitments(u32, Vec<Vec<u8>>, Signed), DkgCommitments(u32, Vec<Vec<u8>>, Signed),
DkgShares { DkgShares {
attempt: u32, attempt: u32,
// Receiving Participant, Sending Participant, Share // Sending Participant, Receiving Participant, Share
shares: Vec<Vec<Vec<u8>>>, shares: Vec<Vec<Vec<u8>>>,
confirmation_nonces: [u8; 64], confirmation_nonces: [u8; 64],
signed: Signed, signed: Signed,

View file

@ -22,7 +22,7 @@ pub async fn potentially_cosign(
) -> CoordinatorMessage { ) -> CoordinatorMessage {
let msg = processors[primary_processor].recv_message().await; let msg = processors[primary_processor].recv_message().await;
let messages::CoordinatorMessage::Coordinator( let messages::CoordinatorMessage::Coordinator(
messages::coordinator::CoordinatorMessage::CosignSubstrateBlock { id }, messages::coordinator::CoordinatorMessage::CosignSubstrateBlock { block_number, id },
) = msg.clone() ) = msg.clone()
else { else {
return msg; return msg;
@ -85,7 +85,7 @@ pub async fn potentially_cosign(
participants.insert(known_signer_i); participants.insert(known_signer_i);
participants participants
} }
_ => panic!("coordinator didn't send back SubstratePreprocesses"), other => panic!("coordinator didn't send back SubstratePreprocesses: {:?}", other),
}; };
for i in participants.clone() { for i in participants.clone() {
@ -152,7 +152,7 @@ pub async fn potentially_cosign(
let signature = Signature( let signature = Signature(
schnorrkel::keys::Keypair::from_bytes(&schnorrkel_key_pair) schnorrkel::keys::Keypair::from_bytes(&schnorrkel_key_pair)
.unwrap() .unwrap()
.sign_simple(b"substrate", &cosign_block_msg(block)) .sign_simple(b"substrate", &cosign_block_msg(block_number, block))
.to_bytes(), .to_bytes(),
); );
@ -162,6 +162,7 @@ pub async fn potentially_cosign(
} }
processor processor
.send_message(messages::coordinator::ProcessorMessage::CosignedBlock { .send_message(messages::coordinator::ProcessorMessage::CosignedBlock {
block_number,
block, block,
signature: signature.0.to_vec(), signature: signature.0.to_vec(),
}) })