mirror of
https://github.com/serai-dex/serai.git
synced 2025-04-22 22:18:15 +00:00
Have the Tributary scanner yield DKG confirmation signing protocol data
This commit is contained in:
parent
f36bbcba25
commit
8b52b921f3
4 changed files with 118 additions and 11 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -8431,6 +8431,7 @@ dependencies = [
|
|||
"blake2",
|
||||
"borsh",
|
||||
"ciphersuite",
|
||||
"dkg",
|
||||
"log",
|
||||
"parity-scale-codec",
|
||||
"rand_core",
|
||||
|
|
|
@ -21,13 +21,14 @@ workspace = true
|
|||
zeroize = { version = "^1.5", default-features = false, features = ["std"] }
|
||||
rand_core = { version = "0.6", default-features = false, features = ["std"] }
|
||||
|
||||
blake2 = { version = "0.10", default-features = false, features = ["std"] }
|
||||
ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, features = ["std"] }
|
||||
schnorr = { package = "schnorr-signatures", path = "../../crypto/schnorr", default-features = false, features = ["std"] }
|
||||
|
||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std", "derive"] }
|
||||
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
||||
|
||||
blake2 = { version = "0.10", default-features = false, features = ["std"] }
|
||||
ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, features = ["std"] }
|
||||
dkg = { path = "../../crypto/dkg", default-features = false, features = ["std"] }
|
||||
schnorr = { package = "schnorr-signatures", path = "../../crypto/schnorr", default-features = false, features = ["std"] }
|
||||
|
||||
serai-client = { path = "../../substrate/client", default-features = false, features = ["serai", "borsh"] }
|
||||
|
||||
serai-db = { path = "../../common/db" }
|
||||
|
|
|
@ -229,7 +229,11 @@ create_db!(
|
|||
|
||||
db_channel!(
|
||||
CoordinatorTributary {
|
||||
// Messages to send to the processor
|
||||
ProcessorMessages: (set: ValidatorSet) -> messages::CoordinatorMessage,
|
||||
// Messages for the DKG confirmation
|
||||
DkgConfirmationMessages: (set: ValidatorSet) -> messages::sign::CoordinatorMessage,
|
||||
// Topics which have been explicitly recognized
|
||||
RecognizedTopics: (set: ValidatorSet) -> Topic,
|
||||
}
|
||||
);
|
||||
|
|
|
@ -5,7 +5,10 @@
|
|||
use core::{marker::PhantomData, future::Future};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use scale::Encode;
|
||||
|
||||
use ciphersuite::group::GroupEncoding;
|
||||
use dkg::Participant;
|
||||
|
||||
use serai_client::{
|
||||
primitives::SeraiAddress,
|
||||
|
@ -27,7 +30,7 @@ use tributary_sdk::{
|
|||
use serai_cosign::CosignIntent;
|
||||
use serai_coordinator_substrate::NewSetInformation;
|
||||
|
||||
use messages::sign::VariantSignId;
|
||||
use messages::sign::{VariantSignId, SignId};
|
||||
|
||||
mod transaction;
|
||||
pub use transaction::{SigningProtocolRound, Signed, Transaction};
|
||||
|
@ -45,6 +48,24 @@ impl ProcessorMessages {
|
|||
}
|
||||
}
|
||||
|
||||
/// Messages for the DKG confirmation.
|
||||
pub struct DkgConfirmationMessages;
|
||||
impl DkgConfirmationMessages {
|
||||
/// Receive a message for the DKG confirmation.
|
||||
///
|
||||
/// These messages use the ProcessorMessage API as that's what existing flows are designed
|
||||
/// around, enabling their reuse. The ProcessorMessage includes a VariantSignId which isn't
|
||||
/// applicable to the DKG confirmation (as there's no such variant of the VariantSignId). The
|
||||
/// actual ID is undefined other than it will be consistent to the signing protocol and unique
|
||||
/// across validator sets, with no guarantees of uniqueness across contexts.
|
||||
pub fn try_recv(
|
||||
txn: &mut impl DbTxn,
|
||||
set: ValidatorSet,
|
||||
) -> Option<messages::sign::CoordinatorMessage> {
|
||||
db::DkgConfirmationMessages::try_recv(txn, set)
|
||||
}
|
||||
}
|
||||
|
||||
/// The cosign intents.
|
||||
pub struct CosignIntents;
|
||||
impl CosignIntents {
|
||||
|
@ -158,6 +179,62 @@ impl<'a, TD: Db, TDT: DbTxn, P: P2p> ScanBlock<'a, TD, TDT, P> {
|
|||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn accumulate_dkg_confirmation<D: AsRef<[u8]> + Borshy>(
|
||||
&mut self,
|
||||
block_number: u64,
|
||||
topic: Topic,
|
||||
attempt: u32,
|
||||
data: &D,
|
||||
signer: SeraiAddress,
|
||||
) -> Option<(SignId, HashMap<Participant, Vec<u8>>)> {
|
||||
match TributaryDb::accumulate::<D>(
|
||||
self.tributary_txn,
|
||||
self.set.set,
|
||||
self.validators,
|
||||
self.total_weight,
|
||||
block_number,
|
||||
topic,
|
||||
signer,
|
||||
self.validator_weights[&signer],
|
||||
data,
|
||||
) {
|
||||
DataSet::None => None,
|
||||
DataSet::Participating(data_set) => {
|
||||
// Consistent ID for the DKG confirmation, unqie across sets
|
||||
let id = {
|
||||
let mut id = [0; 32];
|
||||
let encoded_set = self.set.set.encode();
|
||||
id[.. encoded_set.len()].copy_from_slice(&encoded_set);
|
||||
VariantSignId::Batch(id)
|
||||
};
|
||||
let id = SignId { session: self.set.set.session, id, attempt };
|
||||
|
||||
// This will be used in a MuSig protocol, so the Participant indexes are the validator's
|
||||
// position in the list regardless of their weight
|
||||
let flatten_data_set = |data_set: HashMap<_, D>| {
|
||||
let mut entries = HashMap::with_capacity(usize::from(self.total_weight));
|
||||
for (validator, participation) in data_set {
|
||||
let (index, (_validator, _weight)) = &self
|
||||
.set
|
||||
.validators
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_i, (validator_i, _weight))| validator == *validator_i)
|
||||
.unwrap();
|
||||
entries.insert(
|
||||
Participant::new(u16::try_from(*index).unwrap()).unwrap(),
|
||||
participation.as_ref().to_vec(),
|
||||
);
|
||||
}
|
||||
entries
|
||||
};
|
||||
let data_set = flatten_data_set(data_set);
|
||||
Some((id, data_set))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_application_tx(&mut self, block_number: u64, tx: Transaction) {
|
||||
let signer = |signed: Signed| SeraiAddress(signed.signer().to_bytes());
|
||||
|
||||
|
@ -226,12 +303,36 @@ impl<'a, TD: Db, TDT: DbTxn, P: P2p> ScanBlock<'a, TD, TDT, P> {
|
|||
);
|
||||
}
|
||||
Transaction::DkgConfirmationPreprocess { attempt, preprocess, signed } => {
|
||||
// Accumulate the preprocesses into our own FROST attempt manager
|
||||
todo!("TODO")
|
||||
let topic = topic.unwrap();
|
||||
let signer = signer(signed);
|
||||
|
||||
let Some((id, data_set)) =
|
||||
self.accumulate_dkg_confirmation(block_number, topic, attempt, &preprocess, signer)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
db::DkgConfirmationMessages::send(
|
||||
self.tributary_txn,
|
||||
self.set.set,
|
||||
&messages::sign::CoordinatorMessage::Preprocesses { id, preprocesses: data_set },
|
||||
);
|
||||
}
|
||||
Transaction::DkgConfirmationShare { attempt, share, signed } => {
|
||||
// Accumulate the shares into our own FROST attempt manager
|
||||
todo!("TODO: SetKeysTask")
|
||||
let topic = topic.unwrap();
|
||||
let signer = signer(signed);
|
||||
|
||||
let Some((id, data_set)) =
|
||||
self.accumulate_dkg_confirmation(block_number, topic, attempt, &share, signer)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
db::DkgConfirmationMessages::send(
|
||||
self.tributary_txn,
|
||||
self.set.set,
|
||||
&messages::sign::CoordinatorMessage::Shares { id, shares: data_set },
|
||||
);
|
||||
}
|
||||
|
||||
Transaction::Cosign { substrate_block_hash } => {
|
||||
|
@ -405,7 +506,7 @@ impl<'a, TD: Db, TDT: DbTxn, P: P2p> ScanBlock<'a, TD, TDT, P> {
|
|||
};
|
||||
}
|
||||
|
||||
Transaction::Sign { id, attempt, round, data, signed } => {
|
||||
Transaction::Sign { id: _, attempt: _, round, data, signed } => {
|
||||
let topic = topic.unwrap();
|
||||
let signer = signer(signed);
|
||||
|
||||
|
@ -458,7 +559,7 @@ impl<'a, TD: Db, TDT: DbTxn, P: P2p> ScanBlock<'a, TD, TDT, P> {
|
|||
},
|
||||
)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue