Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Removed attester set from genesis #221

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 7 additions & 16 deletions node/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

86 changes: 0 additions & 86 deletions node/libs/roles/src/attester/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::*;
use crate::validator::testonly::Setup;
use assert_matches::assert_matches;
use rand::Rng;
use zksync_concurrency::ctx;
Expand Down Expand Up @@ -134,91 +133,6 @@ fn test_agg_signature_verify() {
.is_err());
}

#[test]
fn test_batch_qc() {
use BatchQCVerifyError as Error;
let ctx = ctx::test_root(&ctx::RealClock);
let rng = &mut ctx.rng();

let setup1 = Setup::new(rng, 6);
// Completely different genesis.
let setup2 = Setup::new(rng, 6);
// Genesis with only a subset of the attesters.
let genesis3 = {
let mut genesis3 = (*setup1.genesis).clone();
genesis3.attesters = Committee::new(
setup1
.genesis
.attesters
.as_ref()
.unwrap()
.iter()
.take(3)
.cloned(),
)
.unwrap()
.into();
genesis3.with_hash()
};

let attesters = setup1.genesis.attesters.as_ref().unwrap();

// Create QCs with increasing number of attesters.
for i in 0..setup1.attester_keys.len() + 1 {
let mut qc = BatchQC::new(Batch {
genesis: setup1.genesis.hash(),
number: rng.gen(),
hash: rng.gen(),
});
for key in &setup1.attester_keys[0..i] {
qc.add(&key.sign_msg(qc.message.clone()), attesters)
.unwrap();
}

let expected_weight: u64 = attesters.iter().take(i).map(|w| w.weight).sum();
if expected_weight >= attesters.threshold() {
qc.verify(setup1.genesis.hash(), attesters)
.expect("failed to verify QC");
} else {
assert_matches!(
qc.verify(setup1.genesis.hash(), attesters),
Err(Error::NotEnoughSigners { .. })
);
}

// Mismatching attesters sets.
assert!(qc
.verify(
setup1.genesis.hash(),
setup2.genesis.attesters.as_ref().unwrap()
)
.is_err());
assert!(qc
.verify(setup1.genesis.hash(), genesis3.attesters.as_ref().unwrap())
.is_err());
}
}

#[test]
fn test_attester_committee_weights() {
let ctx = ctx::test_root(&ctx::RealClock);
let rng = &mut ctx.rng();

// Attesters with non-uniform weights
let setup = Setup::new_with_weights(rng, vec![1000, 600, 800, 6000, 900, 700]);
// Expected sum of the attesters weights
let sums = [1000, 1600, 2400, 8400, 9300, 10000];
let attesters = setup.genesis.attesters.as_ref().unwrap();

let msg: Batch = rng.gen();
let mut qc = BatchQC::new(msg.clone());
for (i, weight) in sums.iter().enumerate() {
let key = &setup.attester_keys[i];
qc.add(&key.sign_msg(msg.clone()), attesters).unwrap();
assert_eq!(attesters.weight_of_keys(qc.signatures.keys()), *weight);
}
}

#[test]
fn test_committee_weights_overflow_check() {
let ctx = ctx::test_root(&ctx::RealClock);
Expand Down
5 changes: 2 additions & 3 deletions node/libs/roles/src/proto/validator/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ message LeaderSelectionMode {
}

message Genesis {
reserved 1,2;
reserved "fork","validators";
reserved 1,2,9;
reserved "fork","validators", "attesters";
optional uint64 chain_id = 5; // required
optional uint64 fork_number = 6; // required; ForkNumber
optional uint64 first_block = 7; // required; BlockNumber
Expand All @@ -33,7 +33,6 @@ message Genesis {
// We will either remove them entirely, or keep them for the initial epoch.
optional uint32 protocol_version = 8; // required; ProtocolVersion
repeated WeightedValidator validators_v1 = 3;
repeated attester.WeightedAttester attesters = 9; // optional
optional LeaderSelectionMode leader_selection = 4; // required
}

Expand Down
24 changes: 1 addition & 23 deletions node/libs/roles/src/validator/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,7 @@ use super::{
ProposalJustification, ProtocolVersion, PublicKey, ReplicaCommit, ReplicaNewView,
ReplicaTimeout, Signature, Signed, Signers, TimeoutQC, View, ViewNumber, WeightedValidator,
};
use crate::{
attester::{self, WeightedAttester},
node::SessionId,
proto::validator as proto,
validator::LeaderSelectionMode,
};
use crate::{node::SessionId, proto::validator as proto, validator::LeaderSelectionMode};
use anyhow::Context as _;
use std::collections::BTreeMap;
use zksync_consensus_crypto::ByteFmt;
Expand All @@ -27,25 +22,13 @@ impl ProtoFmt for GenesisRaw {
.map(|(i, v)| WeightedValidator::read(v).context(i))
.collect::<Result<_, _>>()
.context("validators_v1")?;
let attesters: Vec<_> = r
.attesters
.iter()
.enumerate()
.map(|(i, v)| WeightedAttester::read(v).context(i))
.collect::<Result<_, _>>()
.context("attesters")?;
Ok(GenesisRaw {
chain_id: ChainId(*required(&r.chain_id).context("chain_id")?),
fork_number: ForkNumber(*required(&r.fork_number).context("fork_number")?),
first_block: BlockNumber(*required(&r.first_block).context("first_block")?),

protocol_version: ProtocolVersion(r.protocol_version.context("protocol_version")?),
validators: Committee::new(validators.into_iter()).context("validators_v1")?,
attesters: if attesters.is_empty() {
None
} else {
Some(attester::Committee::new(attesters.into_iter()).context("attesters")?)
},
leader_selection: read_required(&r.leader_selection).context("leader_selection")?,
})
}
Expand All @@ -57,11 +40,6 @@ impl ProtoFmt for GenesisRaw {

protocol_version: Some(self.protocol_version.0),
validators_v1: self.validators.iter().map(|v| v.build()).collect(),
attesters: self
.attesters
.as_ref()
.map(|c| c.iter().map(|v| v.build()).collect())
.unwrap_or_default(),
leader_selection: Some(self.leader_selection.build()),
}
}
Expand Down
4 changes: 1 addition & 3 deletions node/libs/roles/src/validator/messages/genesis.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Messages related to the consensus protocol.
use super::{BlockNumber, LeaderSelectionMode, ViewNumber};
use crate::{attester, validator};
use crate::validator;
use std::{fmt, hash::Hash};
use zksync_consensus_crypto::{keccak256::Keccak256, ByteFmt, Text, TextFmt};

Expand All @@ -18,8 +18,6 @@ pub struct GenesisRaw {
pub first_block: BlockNumber,
/// Set of validators of the chain.
pub validators: validator::Committee,
/// Set of attesters of the chain.
pub attesters: Option<attester::Committee>,
/// The mode used for selecting leader for a given view.
pub leader_selection: LeaderSelectionMode,
}
Expand Down
3 changes: 1 addition & 2 deletions node/libs/roles/src/validator/messages/tests/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,12 @@ fn test_view_prev() {

#[test]
fn test_view_verify() {
let genesis = genesis_with_attesters();
let genesis = genesis();
let view = View {
genesis: genesis.hash(),
number: ViewNumber(1),
};
assert!(view.verify(&genesis).is_ok());
assert!(view.verify(&genesis_empty_attesters()).is_err());
let view = View {
genesis: GenesisHash::default(),
number: ViewNumber(1),
Expand Down
59 changes: 7 additions & 52 deletions node/libs/roles/src/validator/messages/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use super::*;
use crate::{
attester::{self, WeightedAttester},
validator::{self, testonly::Setup},
};
use crate::validator::{self, testonly::Setup};
use rand::Rng;
use zksync_consensus_crypto::Text;

Expand All @@ -18,7 +15,7 @@ mod versions;
/// Hardcoded view.
fn view() -> View {
View {
genesis: genesis_empty_attesters().hash(),
genesis: genesis().hash(),
number: ViewNumber(9136),
}
}
Expand Down Expand Up @@ -58,18 +55,6 @@ fn validator_keys() -> Vec<validator::SecretKey> {
.collect()
}

/// Hardcoded attester secret keys.
fn attester_keys() -> Vec<attester::SecretKey> {
[
"attester:secret:secp256k1:27cb45b1670a1ae8d376a85821d51c7f91ebc6e32788027a84758441aaf0a987",
"attester:secret:secp256k1:20132edc08a529e927f155e710ae7295a2a0d249f1b1f37726894d1d0d8f0d81",
"attester:secret:secp256k1:0946901f0a6650284726763b12de5da0f06df0016c8ec2144cf6b1903f1979a6",
]
.iter()
.map(|raw| Text::new(raw).decode().unwrap())
.collect()
}

/// Hardcoded validator committee.
fn validator_committee() -> Committee {
Committee::new(
Expand All @@ -84,45 +69,15 @@ fn validator_committee() -> Committee {
.unwrap()
}

/// Hardcoded attester committee.
fn attester_committee() -> attester::Committee {
attester::Committee::new(
attester_keys()
.iter()
.enumerate()
.map(|(i, key)| WeightedAttester {
key: key.public(),
weight: i as u64 + 10,
}),
)
.unwrap()
}

/// Hardcoded genesis with no attesters.
fn genesis_empty_attesters() -> Genesis {
GenesisRaw {
chain_id: ChainId(1337),
fork_number: ForkNumber(42),
first_block: BlockNumber(2834),

protocol_version: ProtocolVersion(1),
validators: validator_committee(),
attesters: None,
leader_selection: LeaderSelectionMode::Weighted,
}
.with_hash()
}

/// Hardcoded genesis with attesters.
fn genesis_with_attesters() -> Genesis {
fn genesis() -> Genesis {
GenesisRaw {
chain_id: ChainId(1337),
fork_number: ForkNumber(42),
first_block: BlockNumber(2834),

protocol_version: ProtocolVersion(1),
validators: validator_committee(),
attesters: attester_committee().into(),
leader_selection: LeaderSelectionMode::Weighted,
}
.with_hash()
Expand All @@ -146,7 +101,7 @@ fn replica_commit() -> ReplicaCommit {

/// Hardcoded `CommitQC`.
fn commit_qc() -> CommitQC {
let genesis = genesis_empty_attesters();
let genesis = genesis();
let replica_commit = replica_commit();
let mut x = CommitQC::new(replica_commit.clone(), &genesis);
for k in validator_keys() {
Expand All @@ -160,7 +115,7 @@ fn commit_qc() -> CommitQC {
fn replica_timeout() -> ReplicaTimeout {
ReplicaTimeout {
view: View {
genesis: genesis_empty_attesters().hash(),
genesis: genesis().hash(),
number: ViewNumber(9169),
},
high_vote: Some(replica_commit()),
Expand All @@ -171,10 +126,10 @@ fn replica_timeout() -> ReplicaTimeout {
/// Hardcoded `TimeoutQC`.
fn timeout_qc() -> TimeoutQC {
let mut x = TimeoutQC::new(View {
genesis: genesis_empty_attesters().hash(),
genesis: genesis().hash(),
number: ViewNumber(9169),
});
let genesis = genesis_empty_attesters();
let genesis = genesis();
let replica_timeout = replica_timeout();
for k in validator_keys() {
x.add(&k.sign_msg(replica_timeout.clone()), &genesis)
Expand Down
Loading
Loading