serai/processor/src/tests/key_gen.rs
Luke Parker 9f143a9742
Replace "coin" with "network"
The Processor's coins folder referred to the networks it could process, as did
its Coin trait. This, and other similar cases throughout the codebase, have now
been corrected.

Also corrects dated documentation for a key pair is confirmed under the
validator-sets pallet.
2023-07-30 16:11:30 -04:00

154 lines
4.4 KiB
Rust

use std::collections::HashMap;
use zeroize::Zeroizing;
use rand_core::{RngCore, OsRng};
use ciphersuite::group::GroupEncoding;
use frost::{Participant, ThresholdParams, tests::clone_without};
use serai_db::{DbTxn, Db, MemDb};
use sp_application_crypto::sr25519;
use serai_client::{
primitives::NetworkId,
validator_sets::primitives::{Session, ValidatorSet},
};
use messages::key_gen::*;
use crate::{
networks::Network,
key_gen::{KeyConfirmed, KeyGen},
};
const ID: KeyGenId =
KeyGenId { set: ValidatorSet { session: Session(1), network: NetworkId::Monero }, attempt: 3 };
pub async fn test_key_gen<N: Network>() {
let mut entropies = HashMap::new();
let mut dbs = HashMap::new();
let mut key_gens = HashMap::new();
for i in 1 ..= 5 {
let mut entropy = Zeroizing::new([0; 32]);
OsRng.fill_bytes(entropy.as_mut());
entropies.insert(i, entropy);
let db = MemDb::new();
dbs.insert(i, db.clone());
key_gens.insert(i, KeyGen::<N, MemDb>::new(db, entropies[&i].clone()));
}
let mut all_commitments = HashMap::new();
for i in 1 ..= 5 {
let key_gen = key_gens.get_mut(&i).unwrap();
let mut txn = dbs.get_mut(&i).unwrap().txn();
if let ProcessorMessage::Commitments { id, commitments } = key_gen
.handle(
&mut txn,
CoordinatorMessage::GenerateKey {
id: ID,
params: ThresholdParams::new(3, 5, Participant::new(u16::try_from(i).unwrap()).unwrap())
.unwrap(),
},
)
.await
{
assert_eq!(id, ID);
all_commitments.insert(Participant::new(u16::try_from(i).unwrap()).unwrap(), commitments);
} else {
panic!("didn't get commitments back");
}
txn.commit();
}
// 1 is rebuilt on every step
// 2 is rebuilt here
// 3 ... are rebuilt once, one at each of the following steps
let rebuild = |key_gens: &mut HashMap<_, _>, dbs: &HashMap<_, MemDb>, i| {
key_gens.remove(&i);
key_gens.insert(i, KeyGen::<N, _>::new(dbs[&i].clone(), entropies[&i].clone()));
};
rebuild(&mut key_gens, &dbs, 1);
rebuild(&mut key_gens, &dbs, 2);
let mut all_shares = HashMap::new();
for i in 1 ..= 5 {
let key_gen = key_gens.get_mut(&i).unwrap();
let mut txn = dbs.get_mut(&i).unwrap().txn();
let i = Participant::new(u16::try_from(i).unwrap()).unwrap();
if let ProcessorMessage::Shares { id, shares } = key_gen
.handle(
&mut txn,
CoordinatorMessage::Commitments {
id: ID,
commitments: clone_without(&all_commitments, &i),
},
)
.await
{
assert_eq!(id, ID);
all_shares.insert(i, shares);
} else {
panic!("didn't get shares back");
}
txn.commit();
}
// Rebuild 1 and 3
rebuild(&mut key_gens, &dbs, 1);
rebuild(&mut key_gens, &dbs, 3);
let mut res = None;
for i in 1 ..= 5 {
let key_gen = key_gens.get_mut(&i).unwrap();
let mut txn = dbs.get_mut(&i).unwrap().txn();
let i = Participant::new(u16::try_from(i).unwrap()).unwrap();
if let ProcessorMessage::GeneratedKeyPair { id, substrate_key, network_key } = key_gen
.handle(
&mut txn,
CoordinatorMessage::Shares {
id: ID,
shares: all_shares
.iter()
.filter_map(|(l, shares)| if i == *l { None } else { Some((*l, shares[&i].clone())) })
.collect(),
},
)
.await
{
assert_eq!(id, ID);
if res.is_none() {
res = Some((substrate_key, network_key.clone()));
}
assert_eq!(res.as_ref().unwrap(), &(substrate_key, network_key));
} else {
panic!("didn't get key back");
}
txn.commit();
}
let res = res.unwrap();
// Rebuild 1 and 4
rebuild(&mut key_gens, &dbs, 1);
rebuild(&mut key_gens, &dbs, 4);
for i in 1 ..= 5 {
let key_gen = key_gens.get_mut(&i).unwrap();
let mut txn = dbs.get_mut(&i).unwrap().txn();
let KeyConfirmed { substrate_keys, network_keys } = key_gen
.confirm(&mut txn, ID.set, (sr25519::Public(res.0), res.1.clone().try_into().unwrap()))
.await;
txn.commit();
let params =
ThresholdParams::new(3, 5, Participant::new(u16::try_from(i).unwrap()).unwrap()).unwrap();
assert_eq!(substrate_keys.params(), params);
assert_eq!(network_keys.params(), params);
assert_eq!(
(
substrate_keys.group_key().to_bytes(),
network_keys.group_key().to_bytes().as_ref().to_vec()
),
res
);
}
}