use super::NodeState;
use crate::types::keys::ed25519::Digest256;
use crate::types::Peer;
use itertools::Itertools;
use serde::{Deserialize, Serialize};
use sn_consensus::Generation;
use std::{
collections::{BTreeMap, BTreeSet},
net::SocketAddr,
};
use tiny_keccak::{Hasher, Sha3};
use xor_name::{Prefix, XorName};
#[derive(Clone, Eq, PartialEq, Hash, Serialize, Deserialize, custom_debug::Debug)]
pub struct DkgSessionId {
pub prefix: Prefix,
pub elders: BTreeMap<XorName, SocketAddr>,
pub section_chain_len: u64,
pub bootstrap_members: BTreeSet<NodeState>,
pub membership_gen: Generation,
}
impl DkgSessionId {
pub fn new(
prefix: Prefix,
elders: BTreeMap<XorName, SocketAddr>,
section_chain_len: u64,
bootstrap_members: BTreeSet<NodeState>,
membership_gen: Generation,
) -> Self {
assert!(elders
.keys()
.all(|e| bootstrap_members.iter().any(|m| &m.name() == e)));
Self {
prefix,
elders,
section_chain_len,
bootstrap_members,
membership_gen,
}
}
pub fn hash(&self) -> Digest256 {
let mut hasher = Sha3::v256();
self.hash_update(&mut hasher);
let mut hash = Digest256::default();
hasher.finalize(&mut hash);
hash
}
pub fn sh(&self) -> u16 {
let h = self.hash();
u16::from_le_bytes([h[0], h[1]])
}
pub fn hash_update(&self, hasher: &mut Sha3) {
hasher.update(&self.prefix.name());
for elder in self.elder_names() {
hasher.update(&elder);
}
hasher.update(&self.section_chain_len.to_le_bytes());
for member in &self.bootstrap_members {
hasher.update(&member.name());
}
}
pub fn elder_names(&self) -> impl Iterator<Item = XorName> + '_ {
self.elders.keys().copied()
}
pub fn elder_peers(&self) -> impl Iterator<Item = Peer> + '_ {
self.elders
.iter()
.map(|(name, addr)| Peer::new(*name, *addr))
}
pub fn elder_index(&self, elder: XorName) -> Option<usize> {
self.elder_names().sorted().position(|p| p == elder)
}
pub fn contains_elder(&self, elder: XorName) -> bool {
self.elder_names().any(|e| e == elder)
}
}