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

feat: added seed_peers to consensus global config #2920

Merged
merged 6 commits into from
Sep 20, 2024
Merged
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
2 changes: 2 additions & 0 deletions core/lib/config/src/configs/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ pub struct GenesisSpec {
pub leader: ValidatorPublicKey,
/// Address of the registry contract.
pub registry_address: Option<ethabi::Address>,
/// Recommended list of peers to connect to.
pub seed_peers: BTreeMap<NodePublicKey, Host>,
}

#[derive(Clone, Debug, PartialEq, Default)]
Expand Down
8 changes: 7 additions & 1 deletion core/lib/config/src/testonly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -774,14 +774,20 @@ impl Distribution<configs::consensus::WeightedAttester> for EncodeDist {

impl Distribution<configs::consensus::GenesisSpec> for EncodeDist {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> configs::consensus::GenesisSpec {
use configs::consensus::{GenesisSpec, ProtocolVersion, ValidatorPublicKey};
use configs::consensus::{
GenesisSpec, Host, NodePublicKey, ProtocolVersion, ValidatorPublicKey,
};
GenesisSpec {
chain_id: L2ChainId::default(),
protocol_version: ProtocolVersion(self.sample(rng)),
validators: self.sample_collect(rng),
attesters: self.sample_collect(rng),
leader: ValidatorPublicKey(self.sample(rng)),
registry_address: self.sample_opt(|| rng.gen()),
seed_peers: self
.sample_range(rng)
.map(|_| (NodePublicKey(self.sample(rng)), Host(self.sample(rng))))
.collect(),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions core/lib/dal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ zksync_utils.workspace = true
zksync_system_constants.workspace = true
zksync_contracts.workspace = true
zksync_types.workspace = true
zksync_concurrency.workspace = true
zksync_consensus_roles.workspace = true
zksync_consensus_storage.workspace = true
zksync_protobuf.workspace = true
Expand Down
34 changes: 33 additions & 1 deletion core/lib/dal/src/consensus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ mod testonly;
#[cfg(test)]
mod tests;

use std::collections::BTreeMap;

use anyhow::{anyhow, Context as _};
use zksync_consensus_roles::{attester, validator};
use zksync_concurrency::net;
use zksync_consensus_roles::{attester, node, validator};
use zksync_protobuf::{read_required, required, ProtoFmt, ProtoRepr};
use zksync_types::{
abi, ethabi,
Expand All @@ -27,6 +30,23 @@ use crate::models::{parse_h160, parse_h256};
pub struct GlobalConfig {
pub genesis: validator::Genesis,
pub registry_address: Option<ethabi::Address>,
pub seed_peers: BTreeMap<node::PublicKey, net::Host>,
}

impl ProtoRepr for proto::NodeAddr {
type Type = (node::PublicKey, net::Host);
fn read(&self) -> anyhow::Result<Self::Type> {
Ok((
read_required(&self.key).context("key")?,
net::Host(required(&self.addr).context("addr")?.clone()),
))
}
fn build(this: &Self::Type) -> Self {
Self {
key: Some(this.0.build()),
addr: Some(this.1 .0.clone()),
}
}
}

impl ProtoFmt for GlobalConfig {
Expand All @@ -41,13 +61,25 @@ impl ProtoFmt for GlobalConfig {
.map(|a| parse_h160(a))
.transpose()
.context("registry_address")?,
seed_peers: r
.seed_peers
.iter()
.enumerate()
.map(|(i, e)| e.read().context(i))
.collect::<Result<_, _>>()
.context("seed_peers")?,
})
}

fn build(&self) -> Self::Proto {
Self::Proto {
genesis: Some(self.genesis.build()),
registry_address: self.registry_address.map(|a| a.as_bytes().to_vec()),
seed_peers: self
.seed_peers
.iter()
.map(|(k, v)| ProtoRepr::build(&(k.clone(), v.clone())))
.collect(),
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions core/lib/dal/src/consensus/proto/mod.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package zksync.dal;

import "zksync/roles/validator.proto";
import "zksync/roles/attester.proto";
import "zksync/roles/node.proto";

message Payload {
// zksync-era ProtocolVersionId
Expand Down Expand Up @@ -122,9 +123,15 @@ message AttesterCommittee {
repeated roles.attester.WeightedAttester members = 1; // required
}

message NodeAddr {
optional roles.node.PublicKey key = 1; // required
optional string addr = 2; // required; Host
}

message GlobalConfig {
optional roles.validator.Genesis genesis = 1; // required
optional bytes registry_address = 2; // optional; H160
repeated NodeAddr seed_peers = 3;
}

message AttestationStatus {
Expand Down
4 changes: 4 additions & 0 deletions core/lib/dal/src/consensus_dal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ impl ConsensusDal<'_, '_> {
return Ok(Some(GlobalConfig {
genesis,
registry_address: None,
seed_peers: [].into(),
}));
}
Ok(None)
Expand Down Expand Up @@ -184,6 +185,7 @@ impl ConsensusDal<'_, '_> {
}
.with_hash(),
registry_address: old.registry_address,
seed_peers: old.seed_peers,
};
txn.consensus_dal().try_update_global_config(&new).await?;
txn.commit().await?;
Expand Down Expand Up @@ -681,6 +683,7 @@ mod tests {
let cfg = GlobalConfig {
genesis: genesis.with_hash(),
registry_address: Some(rng.gen()),
seed_peers: [].into(), // TODO: rng.gen() for Host
};
conn.consensus_dal()
.try_update_global_config(&cfg)
Expand Down Expand Up @@ -715,6 +718,7 @@ mod tests {
let cfg = GlobalConfig {
genesis: setup.genesis.clone(),
registry_address: Some(rng.gen()),
seed_peers: [].into(),
};
conn.consensus_dal()
.try_update_global_config(&cfg)
Expand Down
44 changes: 32 additions & 12 deletions core/lib/protobuf_config/src/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ impl ProtoRepr for proto::GenesisSpec {
.map(|x| parse_h160(x))
.transpose()
.context("registry_address")?,
seed_peers: self
.seed_peers
.iter()
.enumerate()
.map(|(i, e)| e.read().context(i))
.collect::<Result<_, _>>()
.context("seed_peers")?,
})
}
fn build(this: &Self::Type) -> Self {
Expand All @@ -81,6 +88,11 @@ impl ProtoRepr for proto::GenesisSpec {
attesters: this.attesters.iter().map(ProtoRepr::build).collect(),
leader: Some(this.leader.0.clone()),
registry_address: this.registry_address.map(|a| format!("{:?}", a)),
seed_peers: this
.seed_peers
.iter()
.map(|(k, v)| proto::NodeAddr::build(&(k.clone(), v.clone())))
.collect(),
}
}
}
Expand All @@ -99,15 +111,25 @@ impl ProtoRepr for proto::RpcConfig {
}
}

impl ProtoRepr for proto::NodeAddr {
type Type = (NodePublicKey, Host);
fn read(&self) -> anyhow::Result<Self::Type> {
Ok((
NodePublicKey(required(&self.key).context("key")?.clone()),
Host(required(&self.addr).context("addr")?.clone()),
))
}
fn build(this: &Self::Type) -> Self {
Self {
key: Some(this.0 .0.clone()),
addr: Some(this.1 .0.clone()),
}
}
}

impl ProtoRepr for proto::Config {
type Type = ConsensusConfig;
fn read(&self) -> anyhow::Result<Self::Type> {
let read_addr = |e: &proto::NodeAddr| {
let key = NodePublicKey(required(&e.key).context("key")?.clone());
let addr = Host(required(&e.addr).context("addr")?.clone());
anyhow::Ok((key, addr))
};

let max_payload_size = required(&self.max_payload_size)
.and_then(|x| Ok((*x).try_into()?))
.context("max_payload_size")?;
Expand Down Expand Up @@ -144,8 +166,9 @@ impl ProtoRepr for proto::Config {
.gossip_static_outbound
.iter()
.enumerate()
.map(|(i, e)| read_addr(e).context(i))
.collect::<Result<_, _>>()?,
.map(|(i, e)| e.read().context(i))
.collect::<Result<_, _>>()
.context("gossip_static_outbound")?,
genesis_spec: read_optional_repr(&self.genesis_spec),
rpc: read_optional_repr(&self.rpc_config),
})
Expand All @@ -168,10 +191,7 @@ impl ProtoRepr for proto::Config {
gossip_static_outbound: this
.gossip_static_outbound
.iter()
.map(|x| proto::NodeAddr {
key: Some(x.0 .0.clone()),
addr: Some(x.1 .0.clone()),
})
.map(|(k, v)| proto::NodeAddr::build(&(k.clone(), v.clone())))
.collect(),
genesis_spec: this.genesis_spec.as_ref().map(ProtoRepr::build),
rpc_config: this.rpc.as_ref().map(ProtoRepr::build),
Expand Down
5 changes: 3 additions & 2 deletions core/lib/protobuf_config/src/proto/core/consensus.proto
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ package zksync.core.consensus;

import "zksync/std.proto";

// (public key, ip address) of a gossip network node.
// (public key, host address) of a gossip network node.
message NodeAddr {
optional string key = 1; // required; NodePublicKey
optional string addr = 2; // required; IpAddr
optional string addr = 2; // required; Host
}

// Weighted member of a validator committee.
Expand All @@ -58,6 +58,7 @@ message GenesisSpec {
repeated WeightedAttester attesters = 5; // can be empty; attester committee.
// Currently not in consensus genesis, but still a part of the global configuration.
optional string registry_address = 6; // optional; H160
repeated NodeAddr seed_peers = 7;
}

// Per peer connection RPC rate limits.
Expand Down
28 changes: 26 additions & 2 deletions core/node/consensus/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Configuration utilities for the consensus component.
use std::collections::HashMap;
use std::collections::{BTreeMap, HashMap};

use anyhow::Context as _;
use secrecy::{ExposeSecret as _, Secret};
Expand Down Expand Up @@ -44,6 +44,7 @@ pub(super) struct GenesisSpec {
pub(super) attesters: Option<attester::Committee>,
pub(super) leader_selection: validator::LeaderSelectionMode,
pub(super) registry_address: Option<ethabi::Address>,
pub(super) seed_peers: BTreeMap<node::PublicKey, net::Host>,
}

impl GenesisSpec {
Expand All @@ -55,6 +56,7 @@ impl GenesisSpec {
attesters: cfg.genesis.attesters.clone(),
leader_selection: cfg.genesis.leader_selection.clone(),
registry_address: cfg.registry_address,
seed_peers: cfg.seed_peers.clone(),
}
}

Expand Down Expand Up @@ -98,6 +100,19 @@ impl GenesisSpec {
Some(attester::Committee::new(attesters).context("attesters")?)
},
registry_address: x.registry_address,
seed_peers: x
.seed_peers
.iter()
.map(|(key, addr)| {
anyhow::Ok((
Text::new(&key.0)
.decode::<node::PublicKey>()
.context("key")?,
net::Host(addr.0.clone()),
))
})
.collect::<Result<_, _>>()
.context("seed_peers")?,
})
}
}
Expand All @@ -109,9 +124,18 @@ pub(super) fn node_key(secrets: &ConsensusSecrets) -> anyhow::Result<Option<node
pub(super) fn executor(
cfg: &ConsensusConfig,
secrets: &ConsensusSecrets,
global_config: &consensus_dal::GlobalConfig,
build_version: Option<semver::Version>,
) -> anyhow::Result<executor::Config> {
let mut gossip_static_outbound = HashMap::new();
// Always connect to seed peers.
// Once we implement dynamic peer discovery,
// we won't establish a persistent connection to seed peers
// but rather just ask them for more peers.
let mut gossip_static_outbound: HashMap<_, _> = global_config
.seed_peers
.iter()
.map(|(k, v)| (k.clone(), v.clone()))
.collect();
{
let mut append = |key: &NodePublicKey, addr: &Host| {
gossip_static_outbound.insert(
Expand Down
3 changes: 2 additions & 1 deletion core/node/consensus/src/en.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ impl EN {
));

let executor = executor::Executor {
config: config::executor(&cfg, &secrets, build_version)?,
config: config::executor(&cfg, &secrets, &global_config, build_version)?,
block_store,
batch_store,
validator: config::validator_key(&secrets)
Expand Down Expand Up @@ -304,6 +304,7 @@ impl EN {
Ok(consensus_dal::GlobalConfig {
genesis: zksync_protobuf::serde::deserialize(&genesis.0).context("deserialize()")?,
registry_address: None,
seed_peers: [].into(),
})
}

Expand Down
4 changes: 2 additions & 2 deletions core/node/consensus/src/mn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ pub async fn run_main_node(
s.spawn_bg(run_attestation_controller(
ctx,
&pool,
global_config,
global_config.clone(),
attestation.clone(),
));

let executor = executor::Executor {
config: config::executor(&cfg, &secrets, None)?,
config: config::executor(&cfg, &secrets, &global_config, None)?,
block_store,
batch_store,
validator: Some(executor::Validator {
Expand Down
1 change: 1 addition & 0 deletions core/node/consensus/src/storage/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ impl<'a> Connection<'a> {
}
.with_hash(),
registry_address: spec.registry_address,
seed_peers: spec.seed_peers.clone(),
};

txn.try_update_global_config(ctx, &new)
Expand Down
18 changes: 12 additions & 6 deletions core/node/consensus/src/testonly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,8 @@ impl ConfigSet {
}
}

pub(super) fn new_configs(
rng: &mut impl Rng,
setup: &Setup,
gossip_peers: usize,
) -> Vec<ConfigSet> {
pub(super) fn new_configs(rng: &mut impl Rng, setup: &Setup, seed_peers: usize) -> Vec<ConfigSet> {
let net_cfgs = network::testonly::new_configs(rng, setup, 0);
let genesis_spec = config::GenesisSpec {
chain_id: setup.genesis.chain_id.0.try_into().unwrap(),
protocol_version: config::ProtocolVersion(setup.genesis.protocol_version.0),
Expand All @@ -117,8 +114,17 @@ pub(super) fn new_configs(
.collect(),
leader: config::ValidatorPublicKey(setup.validator_keys[0].public().encode()),
registry_address: None,
seed_peers: net_cfgs[..seed_peers]
.iter()
.map(|c| {
(
config::NodePublicKey(c.gossip.key.public().encode()),
config::Host(c.public_addr.0.clone()),
)
})
.collect(),
};
network::testonly::new_configs(rng, setup, gossip_peers)
net_cfgs
.into_iter()
.enumerate()
.map(|(i, net)| ConfigSet {
Expand Down
Loading
Loading