mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 20:29:23 +00:00
DKG Removals (#467)
* Update ValidatorSets with a remove_participant call * Add DkgRemoval, a sign machine for producing the relevant MuSig signatures * Don't use position-dependent u8s yet Public when removing validators from the DKG * Add DkgRemovalPreprocess, DkgRemovalShares Implementation is via a new publish_tributary_tx lambda. This is code is a copy-pasted mess which will need to be cleaned up. * Only allow non-removed validators to vote for removals Otherwise, it's risked that the remaining validators fall below 67% of the original set. * Correct publish_serai_tx, which was prior publish_set_keys in practice
This commit is contained in:
@@ -36,6 +36,7 @@ mod db;
|
||||
pub use db::*;
|
||||
|
||||
mod dkg_confirmer;
|
||||
mod dkg_removal;
|
||||
|
||||
mod handle;
|
||||
pub use handle::*;
|
||||
@@ -226,7 +227,7 @@ impl<Id: Clone + PartialEq + Eq + Debug + Encode + Decode> SignData<Id> {
|
||||
writer.write_all(&[u8::try_from(self.data.len()).unwrap()])?;
|
||||
for data in &self.data {
|
||||
if data.len() > u16::MAX.into() {
|
||||
// Currently, the largest individual preproces is a Monero transaction
|
||||
// Currently, the largest individual preprocess is a Monero transaction
|
||||
// It provides 4 commitments per input (128 bytes), a 64-byte proof for them, along with a
|
||||
// key image and proof (96 bytes)
|
||||
// Even with all of that, we could support 227 inputs in a single TX
|
||||
@@ -265,6 +266,9 @@ pub enum Transaction {
|
||||
},
|
||||
DkgConfirmed(u32, [u8; 32], Signed),
|
||||
|
||||
DkgRemovalPreprocess(SignData<[u8; 32]>),
|
||||
DkgRemovalShare(SignData<[u8; 32]>),
|
||||
|
||||
// Co-sign a Substrate block.
|
||||
CosignSubstrateBlock([u8; 32]),
|
||||
|
||||
@@ -325,6 +329,12 @@ impl Debug for Transaction {
|
||||
.field("attempt", attempt)
|
||||
.field("signer", &hex::encode(signed.signer.to_bytes()))
|
||||
.finish_non_exhaustive(),
|
||||
Transaction::DkgRemovalPreprocess(sign_data) => {
|
||||
fmt.debug_struct("Transaction::DkgRemovalPreprocess").field("sign_data", sign_data).finish()
|
||||
}
|
||||
Transaction::DkgRemovalShare(sign_data) => {
|
||||
fmt.debug_struct("Transaction::DkgRemovalShare").field("sign_data", sign_data).finish()
|
||||
}
|
||||
Transaction::CosignSubstrateBlock(block) => fmt
|
||||
.debug_struct("Transaction::CosignSubstrateBlock")
|
||||
.field("block", &hex::encode(block))
|
||||
@@ -487,13 +497,16 @@ impl ReadWrite for Transaction {
|
||||
Ok(Transaction::DkgConfirmed(attempt, confirmation_share, signed))
|
||||
}
|
||||
|
||||
5 => {
|
||||
5 => SignData::read(reader, 0).map(Transaction::DkgRemovalPreprocess),
|
||||
6 => SignData::read(reader, 1).map(Transaction::DkgRemovalShare),
|
||||
|
||||
7 => {
|
||||
let mut block = [0; 32];
|
||||
reader.read_exact(&mut block)?;
|
||||
Ok(Transaction::CosignSubstrateBlock(block))
|
||||
}
|
||||
|
||||
6 => {
|
||||
8 => {
|
||||
let mut block = [0; 32];
|
||||
reader.read_exact(&mut block)?;
|
||||
let mut batch = [0; 5];
|
||||
@@ -501,19 +514,19 @@ impl ReadWrite for Transaction {
|
||||
Ok(Transaction::Batch(block, batch))
|
||||
}
|
||||
|
||||
7 => {
|
||||
9 => {
|
||||
let mut block = [0; 8];
|
||||
reader.read_exact(&mut block)?;
|
||||
Ok(Transaction::SubstrateBlock(u64::from_le_bytes(block)))
|
||||
}
|
||||
|
||||
8 => SignData::read(reader, 0).map(Transaction::SubstratePreprocess),
|
||||
9 => SignData::read(reader, 1).map(Transaction::SubstrateShare),
|
||||
10 => SignData::read(reader, 0).map(Transaction::SubstratePreprocess),
|
||||
11 => SignData::read(reader, 1).map(Transaction::SubstrateShare),
|
||||
|
||||
10 => SignData::read(reader, 0).map(Transaction::SignPreprocess),
|
||||
11 => SignData::read(reader, 1).map(Transaction::SignShare),
|
||||
12 => SignData::read(reader, 0).map(Transaction::SignPreprocess),
|
||||
13 => SignData::read(reader, 1).map(Transaction::SignShare),
|
||||
|
||||
12 => {
|
||||
14 => {
|
||||
let mut plan = [0; 32];
|
||||
reader.read_exact(&mut plan)?;
|
||||
|
||||
@@ -610,41 +623,50 @@ impl ReadWrite for Transaction {
|
||||
signed.write_without_nonce(writer)
|
||||
}
|
||||
|
||||
Transaction::CosignSubstrateBlock(block) => {
|
||||
Transaction::DkgRemovalPreprocess(data) => {
|
||||
writer.write_all(&[5])?;
|
||||
data.write(writer)
|
||||
}
|
||||
Transaction::DkgRemovalShare(data) => {
|
||||
writer.write_all(&[6])?;
|
||||
data.write(writer)
|
||||
}
|
||||
|
||||
Transaction::CosignSubstrateBlock(block) => {
|
||||
writer.write_all(&[7])?;
|
||||
writer.write_all(block)
|
||||
}
|
||||
|
||||
Transaction::Batch(block, batch) => {
|
||||
writer.write_all(&[6])?;
|
||||
writer.write_all(&[8])?;
|
||||
writer.write_all(block)?;
|
||||
writer.write_all(batch)
|
||||
}
|
||||
|
||||
Transaction::SubstrateBlock(block) => {
|
||||
writer.write_all(&[7])?;
|
||||
writer.write_all(&[9])?;
|
||||
writer.write_all(&block.to_le_bytes())
|
||||
}
|
||||
|
||||
Transaction::SubstratePreprocess(data) => {
|
||||
writer.write_all(&[8])?;
|
||||
writer.write_all(&[10])?;
|
||||
data.write(writer)
|
||||
}
|
||||
Transaction::SubstrateShare(data) => {
|
||||
writer.write_all(&[9])?;
|
||||
writer.write_all(&[11])?;
|
||||
data.write(writer)
|
||||
}
|
||||
|
||||
Transaction::SignPreprocess(data) => {
|
||||
writer.write_all(&[10])?;
|
||||
writer.write_all(&[12])?;
|
||||
data.write(writer)
|
||||
}
|
||||
Transaction::SignShare(data) => {
|
||||
writer.write_all(&[11])?;
|
||||
writer.write_all(&[13])?;
|
||||
data.write(writer)
|
||||
}
|
||||
Transaction::SignCompleted { plan, tx_hash, first_signer, signature } => {
|
||||
writer.write_all(&[12])?;
|
||||
writer.write_all(&[14])?;
|
||||
writer.write_all(plan)?;
|
||||
writer
|
||||
.write_all(&[u8::try_from(tx_hash.len()).expect("tx hash length exceed 255 bytes")])?;
|
||||
@@ -674,6 +696,13 @@ impl TransactionTrait for Transaction {
|
||||
TransactionKind::Signed((b"dkg", attempt).encode(), signed)
|
||||
}
|
||||
|
||||
Transaction::DkgRemovalPreprocess(data) => {
|
||||
TransactionKind::Signed((b"dkg_removal", data.plan, data.attempt).encode(), &data.signed)
|
||||
}
|
||||
Transaction::DkgRemovalShare(data) => {
|
||||
TransactionKind::Signed((b"dkg_removal", data.plan, data.attempt).encode(), &data.signed)
|
||||
}
|
||||
|
||||
Transaction::CosignSubstrateBlock(_) => TransactionKind::Provided("cosign"),
|
||||
|
||||
Transaction::Batch(_, _) => TransactionKind::Provided("batch"),
|
||||
@@ -753,6 +782,9 @@ impl Transaction {
|
||||
Transaction::InvalidDkgShare { .. } => 2,
|
||||
Transaction::DkgConfirmed(_, _, _) => 2,
|
||||
|
||||
Transaction::DkgRemovalPreprocess(_) => 0,
|
||||
Transaction::DkgRemovalShare(_) => 1,
|
||||
|
||||
Transaction::CosignSubstrateBlock(_) => panic!("signing CosignSubstrateBlock"),
|
||||
|
||||
Transaction::Batch(_, _) => panic!("signing Batch"),
|
||||
@@ -776,6 +808,9 @@ impl Transaction {
|
||||
Transaction::InvalidDkgShare { ref mut signed, .. } => signed,
|
||||
Transaction::DkgConfirmed(_, _, ref mut signed) => signed,
|
||||
|
||||
Transaction::DkgRemovalPreprocess(ref mut data) => &mut data.signed,
|
||||
Transaction::DkgRemovalShare(ref mut data) => &mut data.signed,
|
||||
|
||||
Transaction::CosignSubstrateBlock(_) => panic!("signing CosignSubstrateBlock"),
|
||||
|
||||
Transaction::Batch(_, _) => panic!("signing Batch"),
|
||||
|
||||
Reference in New Issue
Block a user