mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Use a MuSig signature to publish validator set key pairs to Serai
The processor/coordinator flow still has to be rewritten.
This commit is contained in:
@@ -1,42 +1,68 @@
|
||||
use sp_core::Pair;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use zeroize::Zeroizing;
|
||||
use rand_core::OsRng;
|
||||
|
||||
use scale::Encode;
|
||||
|
||||
use sp_core::{Pair, sr25519::Signature};
|
||||
|
||||
use ciphersuite::{group::GroupEncoding, Ciphersuite, Ristretto};
|
||||
use frost::dkg::musig::*;
|
||||
use schnorrkel::Schnorrkel;
|
||||
|
||||
use serai_client::{
|
||||
subxt::config::extrinsic_params::BaseExtrinsicParamsBuilder,
|
||||
primitives::{SeraiAddress, insecure_pair_from_name},
|
||||
primitives::insecure_pair_from_name,
|
||||
validator_sets::{
|
||||
primitives::{ValidatorSet, KeyPair},
|
||||
ValidatorSetsEvent,
|
||||
},
|
||||
PairSigner, Serai,
|
||||
Serai,
|
||||
};
|
||||
|
||||
use crate::common::{serai, tx::publish_tx};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub async fn vote_in_keys(set: ValidatorSet, key_pair: KeyPair) -> [u8; 32] {
|
||||
pub async fn set_validator_set_keys(set: ValidatorSet, key_pair: KeyPair) -> [u8; 32] {
|
||||
let pair = insecure_pair_from_name("Alice");
|
||||
let public = pair.public();
|
||||
|
||||
let serai = serai().await;
|
||||
let public_key = <Ristretto as Ciphersuite>::read_G::<&[u8]>(&mut public.0.as_ref()).unwrap();
|
||||
assert_eq!(
|
||||
serai.get_validator_set_musig_key(set).await.unwrap().unwrap(),
|
||||
musig_key::<Ristretto>(&[public_key]).unwrap().to_bytes()
|
||||
);
|
||||
|
||||
let secret_key = <Ristretto as Ciphersuite>::read_F::<&[u8]>(
|
||||
&mut pair.as_ref().secret.to_bytes()[.. 32].as_ref(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(Ristretto::generator() * secret_key, public_key);
|
||||
let threshold_keys = musig::<Ristretto>(&Zeroizing::new(secret_key), &[public_key]).unwrap();
|
||||
assert_eq!(
|
||||
serai.get_validator_set_musig_key(set).await.unwrap().unwrap(),
|
||||
threshold_keys.group_key().to_bytes()
|
||||
);
|
||||
|
||||
let sig = frost::tests::sign_without_caching(
|
||||
&mut OsRng,
|
||||
frost::tests::algorithm_machines(
|
||||
&mut OsRng,
|
||||
Schnorrkel::new(b"substrate"),
|
||||
&HashMap::from([(threshold_keys.params().i(), threshold_keys.into())]),
|
||||
),
|
||||
&key_pair.encode(),
|
||||
);
|
||||
|
||||
// Vote in a key pair
|
||||
let address = SeraiAddress::from(pair.public());
|
||||
let block = publish_tx(
|
||||
&serai
|
||||
.sign(
|
||||
&PairSigner::new(pair),
|
||||
&Serai::vote(set.network, key_pair.clone()),
|
||||
serai.get_nonce(&address).await.unwrap(),
|
||||
BaseExtrinsicParamsBuilder::new(),
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
let block = publish_tx(&Serai::set_validator_set_keys(
|
||||
set.network,
|
||||
key_pair.clone(),
|
||||
Signature(sig.to_bytes()),
|
||||
))
|
||||
.await;
|
||||
|
||||
assert_eq!(
|
||||
serai.get_vote_events(block).await.unwrap(),
|
||||
vec![ValidatorSetsEvent::Vote { voter: public, set, key_pair: key_pair.clone(), votes: 1 }]
|
||||
);
|
||||
assert_eq!(
|
||||
serai.get_key_gen_events(block).await.unwrap(),
|
||||
vec![ValidatorSetsEvent::KeyGen { set, key_pair: key_pair.clone() }]
|
||||
|
||||
Reference in New Issue
Block a user