diff --git a/nodes/nomos-node/Cargo.toml b/nodes/nomos-node/Cargo.toml index 53d255cc..623cbb3a 100644 --- a/nodes/nomos-node/Cargo.toml +++ b/nodes/nomos-node/Cargo.toml @@ -16,12 +16,14 @@ futures = "0.3" http = "0.2.9" hex = "0.4.3" kzgrs-backend = { path = "../../nomos-da/kzgrs-backend" } +subnetworks-assignations = { path = "../../nomos-da/network/subnetworks-assignations" } overwatch-rs = { git = "https://github.com/logos-co/Overwatch", rev = "2f70806" } overwatch-derive = { git = "https://github.com/logos-co/Overwatch", rev = "ac28d01" } tracing = "0.1" multiaddr = "0.18" nomos-core = { path = "../../nomos-core" } nomos-da-verifier = { path = "../../nomos-services/data-availability/verifier", features = ["rocksdb-backend", "libp2p"] } +nomos-da-network-service = { path = "../../nomos-services/data-availability/network" } nomos-network = { path = "../../nomos-services/network", features = ["libp2p"] } nomos-api = { path = "../../nomos-services/api" } nomos-log = { path = "../../nomos-services/log" } diff --git a/nodes/nomos-node/src/config.rs b/nodes/nomos-node/src/config.rs index cc973c46..357589fc 100644 --- a/nodes/nomos-node/src/config.rs +++ b/nodes/nomos-node/src/config.rs @@ -1,20 +1,25 @@ +// std use std::{ net::{IpAddr, SocketAddr, ToSocketAddrs}, path::PathBuf, }; - -use crate::NomosApiService; +// crates use clap::{Parser, ValueEnum}; use color_eyre::eyre::{eyre, Result}; use cryptarchia_ledger::Coin; use hex::FromHex; -use nomos_libp2p::{secp256k1::SecretKey, Multiaddr}; +use nomos_da_network_service::backends::libp2p::validator::DaNetworkValidatorBackend; +use nomos_da_network_service::NetworkService as DaNetworkService; +use nomos_libp2p::{ed25519::SecretKey, Multiaddr}; use nomos_log::{Logger, LoggerBackend, LoggerFormat}; use nomos_network::backends::libp2p::Libp2p as NetworkBackend; use nomos_network::NetworkService; use overwatch_rs::services::ServiceData; use serde::{Deserialize, Serialize}; +use subnetworks_assignations::versions::v1::FillFromNodeList; use tracing::Level; +// internal +use crate::NomosApiService; #[derive(ValueEnum, Clone, Debug, Default)] pub enum LoggerBackendType { @@ -114,6 +119,8 @@ pub struct MetricsArgs { pub struct Config { pub log: ::Settings, pub network: as ServiceData>::Settings, + pub da_network: + > as ServiceData>::Settings, pub http: ::Settings, pub cryptarchia: ::Settings, } diff --git a/nodes/nomos-node/src/lib.rs b/nodes/nomos-node/src/lib.rs index 5cbf4842..b227e419 100644 --- a/nodes/nomos-node/src/lib.rs +++ b/nodes/nomos-node/src/lib.rs @@ -1,19 +1,23 @@ +pub mod api; +mod config; +mod tx; + +// std +// crates +use api::AxumBackend; use bytes::Bytes; use color_eyre::eyre::Result; -use kzgrs_backend::dispersal::BlobInfo; -use overwatch_derive::*; -use overwatch_rs::services::handle::ServiceHandle; -use serde::{de::DeserializeOwned, Serialize}; - -use api::AxumBackend; pub use config::{Config, CryptarchiaArgs, HttpArgs, LogArgs, MetricsArgs, NetworkArgs}; use kzgrs_backend::common::blob::DaBlob; +use kzgrs_backend::dispersal::BlobInfo; use nomos_api::ApiService; use nomos_core::da::blob::info::DispersedBlobInfo; pub use nomos_core::{ da::blob::select::FillSize as FillSizeWithBlobs, tx::select::FillSize as FillSizeWithTx, }; use nomos_core::{header::HeaderId, tx::Transaction, wire}; +use nomos_da_network_service::backends::libp2p::validator::DaNetworkValidatorBackend; +use nomos_da_network_service::NetworkService as DaNetworkService; use nomos_da_verifier::backend::kzgrs::KzgrsDaVerifier; #[cfg(feature = "tracing")] use nomos_log::Logger; @@ -29,12 +33,13 @@ use nomos_storage::{ StorageService, }; use nomos_system_sig::SystemSig; +use overwatch_derive::*; +use overwatch_rs::services::handle::ServiceHandle; +use serde::{de::DeserializeOwned, Serialize}; +use subnetworks_assignations::versions::v1::FillFromNodeList; +// internal pub use tx::Tx; -pub mod api; -mod config; -mod tx; - pub type NomosApiService = ApiService>; @@ -68,6 +73,7 @@ pub struct Nomos { #[cfg(feature = "tracing")] logging: ServiceHandle, network: ServiceHandle>, + da_network: ServiceHandle>>, cl_mempool: ServiceHandle, da_mempool: ServiceHandle, cryptarchia: ServiceHandle, diff --git a/nodes/nomos-node/src/main.rs b/nodes/nomos-node/src/main.rs index 61e5d677..19ec2f71 100644 --- a/nodes/nomos-node/src/main.rs +++ b/nodes/nomos-node/src/main.rs @@ -90,6 +90,7 @@ fn main() -> Result<()> { }, registry: registry.clone(), }, + da_network: config.da_network, cryptarchia: config.cryptarchia, #[cfg(feature = "metrics")] metrics: MetricsSettings { registry }, diff --git a/nomos-cli/src/da/network/backend.rs b/nomos-cli/src/da/network/backend.rs index a33d2c4d..ff237036 100644 --- a/nomos-cli/src/da/network/backend.rs +++ b/nomos-cli/src/da/network/backend.rs @@ -10,7 +10,7 @@ use libp2p::{Multiaddr, PeerId}; use log::error; use nomos_da_network_core::SubnetworkId; use nomos_da_network_service::backends::NetworkBackend; -use nomos_libp2p::{secp256k1, secret_key_serde}; +use nomos_libp2p::{ed25519, secret_key_serde}; use overwatch_rs::overwatch::handle::OverwatchHandle; use overwatch_rs::services::state::NoState; use serde::{Deserialize, Serialize}; @@ -54,8 +54,8 @@ pub struct ExecutorBackend { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct ExecutorBackendSettings { // Identification Secp256k1 private key in Hex format (`0x123...abc`). Default random. - #[serde(with = "secret_key_serde", default = "secp256k1::SecretKey::generate")] - pub node_key: secp256k1::SecretKey, + #[serde(with = "secret_key_serde", default = "ed25519::SecretKey::generate")] + pub node_key: ed25519::SecretKey, /// Membership of DA network PoV set membership: Membership, node_addrs: HashMap, @@ -94,7 +94,7 @@ where let (dispersal_events_sender, dispersal_events_receiver) = unbounded_channel(); let keypair = - libp2p::identity::Keypair::from(secp256k1::Keypair::from(config.node_key.clone())); + libp2p::identity::Keypair::from(ed25519::Keypair::from(config.node_key.clone())); let mut executor_swarm = ExecutorSwarm::new(keypair, config.membership, dispersal_events_sender); let dispersal_request_sender = executor_swarm.blobs_sender(); diff --git a/nomos-da/network/subnetworks-assignations/src/versions/v1.rs b/nomos-da/network/subnetworks-assignations/src/versions/v1.rs index b7e196e1..0530eff8 100644 --- a/nomos-da/network/subnetworks-assignations/src/versions/v1.rs +++ b/nomos-da/network/subnetworks-assignations/src/versions/v1.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use std::collections::HashSet; /// Fill a `N` sized set of "subnetworks" from a list of peer ids members -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Default, Debug, Clone, Serialize, Deserialize)] pub struct FillFromNodeList { pub assignations: Vec>, pub subnetwork_size: usize, diff --git a/nomos-libp2p/src/config.rs b/nomos-libp2p/src/config.rs index ad07a1bb..ccb360ad 100644 --- a/nomos-libp2p/src/config.rs +++ b/nomos-libp2p/src/config.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use libp2p::{gossipsub, identity::secp256k1}; +use libp2p::{gossipsub, identity::ed25519}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -10,8 +10,8 @@ pub struct SwarmConfig { // TCP listening port. Use 0 for random pub port: u16, // Secp256k1 private key in Hex format (`0x123...abc`). Default random - #[serde(with = "secret_key_serde", default = "secp256k1::SecretKey::generate")] - pub node_key: secp256k1::SecretKey, + #[serde(with = "secret_key_serde", default = "ed25519::SecretKey::generate")] + pub node_key: ed25519::SecretKey, // Gossipsub config #[serde(with = "GossipsubConfigDef", default = "gossipsub::Config::default")] pub gossipsub_config: gossipsub::Config, @@ -22,7 +22,7 @@ impl Default for SwarmConfig { Self { host: std::net::Ipv4Addr::new(0, 0, 0, 0), port: 60000, - node_key: secp256k1::SecretKey::generate(), + node_key: ed25519::SecretKey::generate(), gossipsub_config: gossipsub::Config::default(), } } @@ -143,25 +143,25 @@ impl From for gossipsub::Config { } pub mod secret_key_serde { - use libp2p::identity::secp256k1; + use libp2p::identity::ed25519; use serde::de::Error; use serde::{Deserialize, Deserializer, Serialize, Serializer}; - pub fn serialize(key: &secp256k1::SecretKey, serializer: S) -> Result + pub fn serialize(key: &ed25519::SecretKey, serializer: S) -> Result where S: Serializer, { - let hex_str = hex::encode(key.to_bytes()); + let hex_str = hex::encode(key.as_ref()); hex_str.serialize(serializer) } - pub fn deserialize<'de, D>(deserializer: D) -> Result + pub fn deserialize<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { let hex_str = String::deserialize(deserializer)?; let mut key_bytes = hex::decode(hex_str).map_err(|e| D::Error::custom(format!("{e}")))?; - secp256k1::SecretKey::try_from_bytes(key_bytes.as_mut_slice()) + ed25519::SecretKey::try_from_bytes(key_bytes.as_mut_slice()) .map_err(|e| D::Error::custom(format!("{e}"))) } } @@ -180,6 +180,6 @@ mod tests { let deserialized: SwarmConfig = serde_json::from_str(serialized.as_str()).unwrap(); assert_eq!(deserialized.host, config.host); assert_eq!(deserialized.port, config.port); - assert_eq!(deserialized.node_key.to_bytes(), config.node_key.to_bytes()); + assert_eq!(deserialized.node_key.as_ref(), config.node_key.as_ref()); } } diff --git a/nomos-libp2p/src/lib.rs b/nomos-libp2p/src/lib.rs index dc0ab30e..686671cc 100644 --- a/nomos-libp2p/src/lib.rs +++ b/nomos-libp2p/src/lib.rs @@ -16,7 +16,7 @@ use libp2p::swarm::ConnectionId; pub use libp2p::{ core::upgrade, gossipsub::{self, PublishError, SubscriptionError}, - identity::{self, secp256k1}, + identity::{self, ed25519}, swarm::{dial_opts::DialOpts, DialError, NetworkBehaviour, SwarmEvent}, PeerId, SwarmBuilder, Transport, }; @@ -67,7 +67,7 @@ impl Swarm { // TODO: define error types pub fn build(config: &SwarmConfig) -> Result> { let keypair = - libp2p::identity::Keypair::from(secp256k1::Keypair::from(config.node_key.clone())); + libp2p::identity::Keypair::from(ed25519::Keypair::from(config.node_key.clone())); let peer_id = PeerId::from(keypair.public()); tracing::info!("libp2p peer_id:{}", peer_id); diff --git a/nomos-services/data-availability/network/Cargo.toml b/nomos-services/data-availability/network/Cargo.toml index 913462ff..2e84acfd 100644 --- a/nomos-services/data-availability/network/Cargo.toml +++ b/nomos-services/data-availability/network/Cargo.toml @@ -9,6 +9,7 @@ futures = "0.3" kzgrs-backend = { path = "../../../nomos-da/kzgrs-backend" } overwatch-rs = { git = "https://github.com/logos-co/Overwatch", rev = "2f70806" } nomos-core = { path = "../../../nomos-core" } +nomos-libp2p = { path = "../../../nomos-libp2p" } nomos-da-network-core = { path = "../../../nomos-da/network/core" } subnetworks-assignations = { path = "../../../nomos-da/network/subnetworks-assignations" } libp2p = { version = "0.54", features = ["ed25519"] } diff --git a/nomos-services/data-availability/network/src/backends/libp2p/validator.rs b/nomos-services/data-availability/network/src/backends/libp2p/validator.rs index ffc222cb..33d0c8ec 100644 --- a/nomos-services/data-availability/network/src/backends/libp2p/validator.rs +++ b/nomos-services/data-availability/network/src/backends/libp2p/validator.rs @@ -1,17 +1,18 @@ use crate::backends::NetworkBackend; use futures::{Stream, StreamExt}; use kzgrs_backend::common::blob::DaBlob; -use libp2p::identity::Keypair; +use libp2p::identity::ed25519; use libp2p::{Multiaddr, PeerId}; use log::error; use nomos_core::da::BlobId; -use nomos_da_network_core::address_book::AddressBook; use nomos_da_network_core::protocols::sampling; use nomos_da_network_core::protocols::sampling::behaviour::SamplingError; use nomos_da_network_core::swarm::validator::{ValidatorEventsStream, ValidatorSwarm}; use nomos_da_network_core::SubnetworkId; +use nomos_libp2p::secret_key_serde; use overwatch_rs::overwatch::handle::OverwatchHandle; use overwatch_rs::services::state::NoState; +use serde::{Deserialize, Serialize}; use std::fmt::Debug; use std::marker::PhantomData; use std::pin::Pin; @@ -76,14 +77,15 @@ pub struct DaNetworkValidatorBackend { _membership: PhantomData, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct DaNetworkValidatorBackendSettings { - /// Identification key - key: Keypair, + // Identification Secp256k1 private key in Hex format (`0x123...abc`). Default random. + #[serde(with = "secret_key_serde", default = "ed25519::SecretKey::generate")] + pub node_key: ed25519::SecretKey, /// Membership of DA network PoV set - membership: Membership, - addresses: AddressBook, - listening_address: Multiaddr, + pub membership: Membership, + pub addresses: Vec<(PeerId, Multiaddr)>, + pub listening_address: Multiaddr, } impl DaNetworkValidatorBackend { @@ -116,8 +118,13 @@ where type NetworkEvent = DaNetworkEvent; fn new(config: Self::Settings, overwatch_handle: OverwatchHandle) -> Self { - let (mut validator_swarm, events_streams) = - ValidatorSwarm::new(config.key, config.membership, config.addresses); + let keypair = + libp2p::identity::Keypair::from(ed25519::Keypair::from(config.node_key.clone())); + let (mut validator_swarm, events_streams) = ValidatorSwarm::new( + keypair, + config.membership, + config.addresses.into_iter().collect(), + ); let sampling_request_channel = validator_swarm .protocol_swarm() .behaviour() diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 4968d630..d91a0324 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -16,6 +16,8 @@ nomos-core = { path = "../nomos-core" } cryptarchia-engine = { path = "../consensus/cryptarchia-engine", features = ["serde"] } cryptarchia-ledger = { path = "../ledger/cryptarchia-ledger", features = ["serde"] } nomos-mempool = { path = "../nomos-services/mempool", features = ["mock", "libp2p"] } +nomos-da-network-service = { path = "../nomos-services/data-availability/network" } +subnetworks-assignations = { path = "../nomos-da/network/subnetworks-assignations" } full-replication = { path = "../nomos-da/full-replication" } kzgrs-backend = { path = "../nomos-da/kzgrs-backend" } rand = "0.8" diff --git a/tests/src/nodes/nomos.rs b/tests/src/nodes/nomos.rs index ec999e44..7862ae52 100644 --- a/tests/src/nodes/nomos.rs +++ b/tests/src/nodes/nomos.rs @@ -1,6 +1,7 @@ // std use std::net::SocketAddr; use std::process::{Child, Command, Stdio}; +use std::str::FromStr; use std::time::Duration; // internal use super::{create_tempdir, persist_tempdir, LOGS_PREFIX}; @@ -16,6 +17,9 @@ use mixnet::{ topology::{MixNodeInfo, MixnetTopology}, }; use nomos_core::{block::Block, header::HeaderId}; +use nomos_da_network_service::backends::libp2p::validator::DaNetworkValidatorBackendSettings; +use nomos_da_network_service::NetworkConfig as DaNetworkConfig; +use nomos_libp2p::{Multiaddr, SwarmConfig}; use nomos_log::{LoggerBackend, LoggerFormat}; use nomos_mempool::MempoolMetrics; #[cfg(feature = "mixnet")] @@ -350,10 +354,11 @@ fn create_node_config( time: TimeConfig, #[cfg(feature = "mixnet")] mixnet_config: MixnetConfig, ) -> Config { + let swarm_config: SwarmConfig = Default::default(); let mut config = Config { network: NetworkConfig { backend: Libp2pConfig { - inner: Default::default(), + inner: swarm_config.clone(), initial_peers: vec![], #[cfg(feature = "mixnet")] mixnet: mixnet_config, @@ -367,6 +372,14 @@ fn create_node_config( transaction_selector_settings: (), blob_selector_settings: (), }, + da_network: DaNetworkConfig { + backend: DaNetworkValidatorBackendSettings { + node_key: swarm_config.node_key, + listening_address: Multiaddr::from_str("/ip4/127.0.0.1/udp/0/quic-v1").unwrap(), + addresses: Default::default(), + membership: Default::default(), + }, + }, log: Default::default(), http: nomos_api::ApiServiceSettings { backend_settings: AxumBackendSettings {