Skip to content

Multiple committees #360

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

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
73eeb03
Add `CommitteeId` and `Round`.
twittner May 28, 2025
bb993b5
Move `Timestamp` to sailfish-types.
twittner May 21, 2025
400c178
Move `math` module to sailfish-types.
twittner May 21, 2025
91126cb
Add `ConsensusTime` newtype.
twittner May 21, 2025
055e025
Add `HasTime` trait.
twittner May 21, 2025
44333f5
Merge branch 'main' into tw/committee-id
twittner May 28, 2025
7857180
Update consensus timestamp.
twittner May 29, 2025
a7c5a76
Update committee on time.
twittner May 29, 2025
f47b39f
Add `Role`, `Command` and ways to add/remove peers.
twittner Jun 3, 2025
153d7f9
Add `Message::Handover` and multicast to next committee.
twittner Jun 3, 2025
614430d
Add `HandoverMessage`.
twittner Jun 3, 2025
c725dc3
Add committee switching logic to consensus.
twittner Jun 4, 2025
10c93f4
Merge branch 'main' into tw/committee-id
twittner Jun 4, 2025
50c0939
Simplify.
twittner Jun 5, 2025
7afb6dc
Utilise `Coordinator` for committee switch.
twittner Jun 5, 2025
2438e84
Route `Message::{Handover, HandoverCert}` to next committee.
twittner Jun 5, 2025
563eddb
Add `Comm::{add_committee, use_committee}`.
twittner Jun 5, 2025
2aa74f2
Use `PLACEHOLDER` in `produce`.
twittner Jun 5, 2025
3dfd167
Handle two consensus instances in coordinator.
twittner Jun 6, 2025
78220b6
Only require `CommitteeId` in `NextCommittee`.
twittner Jun 6, 2025
9e4aa8e
Add `AddressableCommittee`.
twittner Jun 6, 2025
dced810
Remove `rbc::abraham::AddrInfo`.
twittner Jun 9, 2025
d95557c
Add `Consensus::State`.
twittner Jun 9, 2025
58c6e7f
Some renamings in `Coordinator`.
twittner Jun 9, 2025
e799637
Set next committee in includer.
twittner Jun 9, 2025
448cc03
Rename `PLACEHOLDER` to `UNKNOWN_COMMITTEE_ID`.
twittner Jun 9, 2025
1249f7e
Remove unnecessary error case.
twittner Jun 9, 2025
18b2eeb
Add `sailfish::Event`.
twittner Jun 9, 2025
095b9d0
Add handover test.
twittner Jun 10, 2025
75b96d1
Add coordinator state.
twittner Jun 11, 2025
4313569
Fix handover message validation.
twittner Jun 11, 2025
9db90c6
Small fixes.
twittner Jun 11, 2025
7db8b5c
Remove `Committee::with` and `AddressableCommittee::with`.
twittner Jun 11, 2025
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
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ alloy-signer = "1.0.5"
alloy-signer-local = "1.0.5"
anyhow = "1.0.89"
arbitrary = "1.4.1"
arbtest = "0.3.2"
ark-bn254 = "0.5"
ark-ec = "0.5"
ark-ff = "0.5"
Expand All @@ -47,6 +48,7 @@ ark-secp256k1 = "0.5"
ark-bls12-381 = "0.5"
ark-serialize = { version = "0.5", features = ["derive"] }
ark-std = { version = "0.5", default-features = false }
arrayvec = "0.7.6"
async-lock = "3.3"
async-trait = "0.1"
bimap = "0.6.3"
Expand Down Expand Up @@ -90,6 +92,7 @@ spongefish = { git = "https://github.com/arkworks-rs/spongefish.git", rev = "e9f
thiserror = "2.0"
tide-disco = "0.9.3"
tokio = { version = "1", default-features = false, features = ["full"] }
tokio-stream = "0.1.17"
toml = "0.8.19"
tracing = "0.1"
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "json"] }
Expand Down
63 changes: 63 additions & 0 deletions cliquenet/src/addr.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::collections::HashMap;
use std::fmt;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};

use multisig::{Committee, PublicKey, x25519};
use serde::{Deserialize, Deserializer, Serialize, Serializer, de};

/// A network address.
Expand Down Expand Up @@ -134,6 +136,67 @@ impl<'de> Deserialize<'de> for Address {
}
}

/// A `Committee` plus address information.
#[derive(Debug, Clone)]
pub struct AddressableCommittee {
committee: Committee,
addresses: HashMap<PublicKey, (x25519::PublicKey, Address)>,
}

impl AddressableCommittee {
pub fn new<I, A>(c: Committee, addrs: I) -> Self
where
I: IntoIterator<Item = (PublicKey, x25519::PublicKey, A)>,
A: Into<Address>,
{
let this = Self {
committee: c,
addresses: addrs
.into_iter()
.map(|(k, x, a)| (k, (x, a.into())))
.collect(),
};
this.assert_shared_domain();
this
}

pub fn committee(&self) -> &Committee {
&self.committee
}

pub fn address(&self, p: &PublicKey) -> Option<&(x25519::PublicKey, Address)> {
self.addresses.get(p)
}

pub fn parties(&self) -> impl Iterator<Item = &PublicKey> {
self.addresses.keys()
}

pub fn entries(&self) -> impl Iterator<Item = (PublicKey, x25519::PublicKey, Address)> {
self.addresses.iter().map(|(k, (x, a))| (*k, *x, a.clone()))
}

pub fn diff(
&self,
other: &Self,
) -> impl Iterator<Item = (PublicKey, x25519::PublicKey, Address)> {
self.addresses
.iter()
.filter(|(k, _)| !other.addresses.contains_key(k))
.map(|(k, (x, a))| (*k, *x, a.clone()))
}

/// Assert that addresses and committee have the same keys.
fn assert_shared_domain(&self) {
for p in self.committee.parties() {
assert!(self.addresses.contains_key(p), "{p} has no address")
}
for k in self.addresses.keys() {
assert!(self.committee.contains_key(k), "{k} not in committee")
}
}
}

#[cfg(test)]
mod tests {
use super::Address;
Expand Down
20 changes: 19 additions & 1 deletion cliquenet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ mod time;

pub mod overlay;

pub use addr::{Address, InvalidAddress};
pub use addr::{Address, AddressableCommittee, InvalidAddress};
pub use error::NetworkError;
pub use id::Id;
pub use metrics::NetworkMetrics;
Expand All @@ -22,3 +22,21 @@ pub const MAX_MESSAGE_SIZE: usize = 5 * 1024 * 1024;

/// Max. number of messages to queue for a peer.
pub const PEER_CAPACITY: usize = 256;

/// Network peer role.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Role {
/// Active peers receive broadcast messages.
Active,
/// Passive peers are excluded from broadcasts.
///
/// Note however that passive peers can be addressed directly in
/// unicast or multicast operations.
Passive,
}

impl Role {
pub fn is_active(self) -> bool {
matches!(self, Self::Active)
}
}
Loading