From 33c862ffe5894127082526c7bcc3e44595c4debb Mon Sep 17 00:00:00 2001 From: Antonio Date: Wed, 26 Aug 2026 06:52:56 +0000 Subject: [PATCH] chore(blend): restructure existing core crates (#3404) --- Cargo.lock | 39 ++- Cargo.toml | 4 + blend/core/Cargo.toml | 2 + blend/core/src/lib.rs | 2 + blend/membership/Cargo.toml | 25 ++ blend/membership/src/lib.rs | 147 +++++++++ blend/membership/src/tests.rs | 167 ++++++++++ blend/message/src/codec.rs | 50 +++ blend/message/src/lib.rs | 5 + blend/network/Cargo.toml | 5 +- blend/network/src/core/mod.rs | 2 +- blend/network/src/core/tests/utils.rs | 2 +- .../src/core/with_core/behaviour/mod.rs | 6 +- .../core/with_core/behaviour/tests/epoch.rs | 2 +- .../behaviour/tests/message_handling.rs | 2 +- .../core/with_core/behaviour/tests/utils.rs | 2 +- .../src/core/with_core/behaviour/utils.rs | 9 +- .../src/core/with_edge/behaviour/mod.rs | 10 +- .../core/with_edge/behaviour/tests/epoch.rs | 2 +- .../behaviour/tests/message_handling.rs | 2 +- .../core/with_edge/behaviour/tests/utils.rs | 2 +- blend/provers/Cargo.toml | 45 +++ .../src}/crypto/core_and_leader/mod.rs | 0 .../src}/crypto/core_and_leader/receive.rs | 5 +- .../src}/crypto/core_and_leader/send.rs | 20 +- .../core_and_leader/send_and_receive.rs | 32 +- .../src}/crypto/leader/mod.rs | 0 .../src}/crypto/leader/send.rs | 12 +- .../src}/crypto/mod.rs | 36 +- .../src}/crypto/test_utils.rs | 2 +- .../mod.rs => provers/src/lib.rs} | 0 .../src}/provers/core/mod.rs | 2 +- .../src}/provers/core/tests.rs | 2 +- .../src}/provers/core_and_leader/mod.rs | 4 +- .../src}/provers/core_and_leader/tests.rs | 2 +- .../src}/provers/core_leader_and_pow/mod.rs | 2 +- .../src}/provers/core_leader_and_pow/tests.rs | 2 +- .../src}/provers/leader/mod.rs | 2 +- .../src}/provers/leader/tests.rs | 2 +- .../src}/provers/leader_and_pow/mod.rs | 2 +- .../src}/provers/leader_and_pow/tests.rs | 2 +- .../src}/provers/mod.rs | 0 .../src}/provers/pow/mod.rs | 2 +- .../src}/provers/pow/tests.rs | 2 +- .../src}/provers/test_utils.rs | 2 +- blend/scheduling/Cargo.toml | 39 +-- blend/scheduling/src/lib.rs | 13 +- blend/scheduling/src/membership.rs | 312 ------------------ 48 files changed, 571 insertions(+), 460 deletions(-) create mode 100644 blend/membership/Cargo.toml create mode 100644 blend/membership/src/lib.rs create mode 100644 blend/membership/src/tests.rs create mode 100644 blend/message/src/codec.rs create mode 100644 blend/provers/Cargo.toml rename blend/{scheduling/src/message_blend => provers/src}/crypto/core_and_leader/mod.rs (100%) rename blend/{scheduling/src/message_blend => provers/src}/crypto/core_and_leader/receive.rs (98%) rename blend/{scheduling/src/message_blend => provers/src}/crypto/core_and_leader/send.rs (95%) rename blend/{scheduling/src/message_blend => provers/src}/crypto/core_and_leader/send_and_receive.rs (89%) rename blend/{scheduling/src/message_blend => provers/src}/crypto/leader/mod.rs (100%) rename blend/{scheduling/src/message_blend => provers/src}/crypto/leader/send.rs (95%) rename blend/{scheduling/src/message_blend => provers/src}/crypto/mod.rs (62%) rename blend/{scheduling/src/message_blend => provers/src}/crypto/test_utils.rs (99%) rename blend/{scheduling/src/message_blend/mod.rs => provers/src/lib.rs} (100%) rename blend/{scheduling/src/message_blend => provers/src}/provers/core/mod.rs (99%) rename blend/{scheduling/src/message_blend => provers/src}/provers/core/tests.rs (98%) rename blend/{scheduling/src/message_blend => provers/src}/provers/core_and_leader/mod.rs (98%) rename blend/{scheduling/src/message_blend => provers/src}/provers/core_and_leader/tests.rs (99%) rename blend/{scheduling/src/message_blend => provers/src}/provers/core_leader_and_pow/mod.rs (99%) rename blend/{scheduling/src/message_blend => provers/src}/provers/core_leader_and_pow/tests.rs (99%) rename blend/{scheduling/src/message_blend => provers/src}/provers/leader/mod.rs (99%) rename blend/{scheduling/src/message_blend => provers/src}/provers/leader/tests.rs (98%) rename blend/{scheduling/src/message_blend => provers/src}/provers/leader_and_pow/mod.rs (98%) rename blend/{scheduling/src/message_blend => provers/src}/provers/leader_and_pow/tests.rs (98%) rename blend/{scheduling/src/message_blend => provers/src}/provers/mod.rs (100%) rename blend/{scheduling/src/message_blend => provers/src}/provers/pow/mod.rs (99%) rename blend/{scheduling/src/message_blend => provers/src}/provers/pow/tests.rs (99%) rename blend/{scheduling/src/message_blend => provers/src}/provers/test_utils.rs (98%) delete mode 100644 blend/scheduling/src/membership.rs diff --git a/Cargo.lock b/Cargo.lock index 9065c2fdf..b239d49aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4008,9 +4008,11 @@ name = "logos-blockchain-blend" version = "0.0.0" dependencies = [ "logos-blockchain-blend-crypto", + "logos-blockchain-blend-membership", "logos-blockchain-blend-message", "logos-blockchain-blend-network", "logos-blockchain-blend-proofs", + "logos-blockchain-blend-provers", "logos-blockchain-blend-scheduling", ] @@ -4028,6 +4030,16 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "logos-blockchain-blend-membership" +version = "0.0.0" +dependencies = [ + "logos-blockchain-key-management-system-keys", + "multiaddr", + "rand 0.8.6", + "serde", +] + [[package]] name = "logos-blockchain-blend-message" version = "0.0.0" @@ -4067,9 +4079,10 @@ dependencies = [ "libp2p", "libp2p-stream", "libp2p-swarm-test", + "logos-blockchain-blend-membership", "logos-blockchain-blend-message", "logos-blockchain-blend-proofs", - "logos-blockchain-blend-scheduling", + "logos-blockchain-blend-provers", "logos-blockchain-cryptarchia-engine", "logos-blockchain-groth16", "logos-blockchain-key-management-system-keys", @@ -4107,18 +4120,17 @@ dependencies = [ ] [[package]] -name = "logos-blockchain-blend-scheduling" +name = "logos-blockchain-blend-provers" version = "0.0.0" dependencies = [ "async-trait", "derivative", - "fork_stream", "futures", "hex", "libp2p", + "logos-blockchain-blend-membership", "logos-blockchain-blend-message", "logos-blockchain-blend-proofs", - "logos-blockchain-codec", "logos-blockchain-core", "logos-blockchain-cryptarchia-engine", "logos-blockchain-groth16", @@ -4128,8 +4140,25 @@ dependencies = [ "multiaddr", "rand 0.8.6", "rayon", - "serde", "test-log", + "tokio", + "tracing", +] + +[[package]] +name = "logos-blockchain-blend-scheduling" +version = "0.0.0" +dependencies = [ + "fork_stream", + "futures", + "logos-blockchain-blend-membership", + "logos-blockchain-blend-message", + "logos-blockchain-blend-proofs", + "logos-blockchain-blend-provers", + "logos-blockchain-cryptarchia-engine", + "logos-blockchain-log-targets", + "logos-blockchain-utils", + "rand 0.8.6", "thiserror 2.0.18", "tokio", "tokio-stream", diff --git a/Cargo.toml b/Cargo.toml index a709ca3b4..7109ebb92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,9 +31,11 @@ strip = "none" # Don't strip symbols to allow for better profiling results members = [ "blend/core", "blend/crypto", + "blend/membership", "blend/message", "blend/network", "blend/proofs", + "blend/provers", "blend/scheduling", "c-bindings", "codec", @@ -110,9 +112,11 @@ lb-api-service = { default-features = false, package = "logo lb-blake2btree = { default-features = false, package = "logos-blockchain-blake2btree", path = "merkle/blake2btree" } lb-blend = { default-features = false, package = "logos-blockchain-blend", path = "./blend/core" } lb-blend-crypto = { default-features = false, package = "logos-blockchain-blend-crypto", path = "./blend/crypto" } +lb-blend-membership = { default-features = false, package = "logos-blockchain-blend-membership", path = "./blend/membership" } lb-blend-message = { default-features = false, package = "logos-blockchain-blend-message", path = "./blend/message" } lb-blend-network = { default-features = false, package = "logos-blockchain-blend-network", path = "./blend/network" } lb-blend-proofs = { default-features = false, package = "logos-blockchain-blend-proofs", path = "./blend/proofs" } +lb-blend-provers = { default-features = false, package = "logos-blockchain-blend-provers", path = "./blend/provers" } lb-blend-scheduling = { default-features = false, package = "logos-blockchain-blend-scheduling", path = "./blend/scheduling" } lb-blend-service = { default-features = false, package = "logos-blockchain-blend-service", path = "./services/blend" } lb-chain-broadcast-service = { default-features = false, package = "logos-blockchain-chain-broadcast-service", path = "./services/chain/broadcast-service" } diff --git a/blend/core/Cargo.toml b/blend/core/Cargo.toml index 0023653c8..ec3d57832 100644 --- a/blend/core/Cargo.toml +++ b/blend/core/Cargo.toml @@ -14,9 +14,11 @@ workspace = true [dependencies] lb-blend-crypto = { workspace = true } +lb-blend-membership = { workspace = true } lb-blend-message = { workspace = true } lb-blend-network = { workspace = true } lb-blend-proofs = { workspace = true } +lb-blend-provers = { workspace = true } lb-blend-scheduling = { workspace = true } [features] diff --git a/blend/core/src/lib.rs b/blend/core/src/lib.rs index 4e3c03ed0..1e0d5d09f 100644 --- a/blend/core/src/lib.rs +++ b/blend/core/src/lib.rs @@ -1,5 +1,7 @@ pub use lb_blend_crypto as crypto; +pub use lb_blend_membership as membership; pub use lb_blend_message as message; pub use lb_blend_network as network; pub use lb_blend_proofs as proofs; +pub use lb_blend_provers as provers; pub use lb_blend_scheduling as scheduling; diff --git a/blend/membership/Cargo.toml b/blend/membership/Cargo.toml new file mode 100644 index 000000000..845033792 --- /dev/null +++ b/blend/membership/Cargo.toml @@ -0,0 +1,25 @@ +[package] +categories = { workspace = true } +description = { workspace = true } +edition = { workspace = true } +keywords = { workspace = true } +license = { workspace = true } +name = "logos-blockchain-blend-membership" +readme = { workspace = true } +repository = { workspace = true } +version = { workspace = true } + +[lints] +workspace = true + +[dependencies] +lb-key-management-system-keys = { workspace = true } +multiaddr = { workspace = true } +rand = { features = ["alloc"], workspace = true } +serde = { workspace = true } + +[dev-dependencies] +lb-key-management-system-keys = { workspace = true } + +[features] +unsafe-test-functions = [] diff --git a/blend/membership/src/lib.rs b/blend/membership/src/lib.rs new file mode 100644 index 000000000..a0e5f4f9d --- /dev/null +++ b/blend/membership/src/lib.rs @@ -0,0 +1,147 @@ +use std::{ + collections::{HashMap, HashSet}, + hash::Hash, +}; + +use lb_key_management_system_keys::keys::Ed25519PublicKey; +use multiaddr::Multiaddr; +use rand::{Rng, seq::IteratorRandom as _}; +use serde::{Deserialize, Serialize}; + +#[cfg(test)] +mod tests; + +/// A set of core nodes in an epoch. +#[derive(Clone, Debug)] +pub struct Membership { + /// All nodes, including local and remote. + core_nodes: HashMap>, + /// List of node indices, used for proof of selection generation. It + /// contains all nodes in the `nodes` map. + node_indices: Vec, + /// ID of the local node in the `node_indices` vector, if present (i.e., if + /// the local node is a core node). + local_node_index: Option, +} + +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] +pub struct Node { + /// An unique identifier of the node, + /// which is usually corresponding to the network node identifier + /// but depending on the network backend. + pub id: Id, + /// A listening address + pub address: Multiaddr, + /// A public key used for the blend message encryption + pub public_key: Ed25519PublicKey, +} + +impl Membership +where + NodeId: Clone + Hash + Eq, +{ + #[must_use] + pub fn new(nodes: &[Node], local_public_key: &Ed25519PublicKey) -> Self { + let mut core_nodes = HashMap::with_capacity(nodes.len()); + let mut node_indices = Vec::with_capacity(nodes.len()); + let mut local_node_index = None; + for (index, node) in nodes.iter().enumerate() { + assert!( + core_nodes.insert(node.id.clone(), node.clone()).is_none(), + "Membership info contained a duplicate node." + ); + node_indices.push(node.id.clone()); + if node.public_key == *local_public_key { + local_node_index = Some(index); + } + } + + Self { + core_nodes, + node_indices, + local_node_index, + } + } + + #[cfg(any(test, feature = "unsafe-test-functions"))] + #[must_use] + pub fn new_without_local(nodes: &[Node]) -> Self { + use lb_key_management_system_keys::keys::ED25519_PUBLIC_KEY_SIZE; + + Self::new( + nodes, + &Ed25519PublicKey::from_bytes(&[0; ED25519_PUBLIC_KEY_SIZE]).unwrap(), + ) + } +} + +impl Membership +where + NodeId: Eq + Hash, +{ + /// Choose `amount` random remote nodes. + pub fn choose_remote_nodes( + &self, + rng: &mut R, + amount: usize, + ) -> impl Iterator> + use<'_, R, NodeId> { + self.filter_and_choose_remote_nodes(rng, amount, &HashSet::new()) + } + + /// Choose `amount` random remote nodes excluding the given set of node IDs. + pub fn filter_and_choose_remote_nodes( + &self, + rng: &mut R, + amount: usize, + exclude_peers: &HashSet, + ) -> impl Iterator> + use<'_, R, NodeId> { + self.node_indices + .iter() + .enumerate() + // Filter out excluded peers. + .filter(|(_, node_id)| !exclude_peers.contains(node_id)) + // Filter out local node, if the local node is a core node. + .filter(|(index, _)| self.local_node_index != Some(*index)) + // Discard index after it's used. + .map(|(_, node)| node) + .choose_multiple(rng, amount) + .into_iter() + .map(|id| { + self.core_nodes + .get(id) + .expect("Node ID must exist in core nodes.") + }) + } + + pub fn contains(&self, node_id: &NodeId) -> bool { + self.core_nodes.contains_key(node_id) + } + + #[must_use] + pub fn get_node_at(&self, index: usize) -> Option<&Node> { + self.core_nodes.get(self.node_indices.get(index)?) + } +} + +impl Membership { + #[must_use] + pub const fn local_index(&self) -> Option { + self.local_node_index + } + + #[must_use] + pub const fn contains_local(&self) -> bool { + self.local_node_index.is_some() + } + + /// Returns the number of all nodes, including local and remote. + #[must_use] + pub fn size(&self) -> usize { + self.core_nodes.len() + } + + #[must_use] + pub fn is_empty(&self) -> bool { + self.core_nodes.is_empty() + } +} diff --git a/blend/membership/src/tests.rs b/blend/membership/src/tests.rs new file mode 100644 index 000000000..ede91aba8 --- /dev/null +++ b/blend/membership/src/tests.rs @@ -0,0 +1,167 @@ +use std::collections::HashSet; + +use lb_key_management_system_keys::keys::{Ed25519PublicKey, UnsecuredEd25519Key}; +use multiaddr::Multiaddr; +use rand::rngs::OsRng; + +use crate::{Membership, Node}; + +#[test] +fn test_membership_new_with_local_node() { + let nodes = vec![node(1, 1), node(2, 2), node(3, 3)]; + let local_key = key(2); + + let membership = Membership::new(&nodes, &local_key); + + assert_eq!(membership.size(), 3); + assert_eq!( + membership + .core_nodes + .keys() + .copied() + .collect::>(), + HashSet::from([1, 2, 3]) + ); + assert_eq!(membership.node_indices, vec![1, 2, 3]); + assert_eq!(membership.local_node_index, Some(1)); + assert!(membership.contains_local()); +} + +#[test] +fn test_membership_new_without_local_node() { + let nodes = vec![node(1, 1), node(2, 2), node(3, 3)]; + let local_key = key(99); + + let membership = Membership::new(&nodes, &local_key); + + assert_eq!(membership.size(), 3); + assert_eq!( + membership + .core_nodes + .keys() + .copied() + .collect::>(), + HashSet::from([1, 2, 3]) + ); + assert_eq!(membership.node_indices, vec![1, 2, 3]); + assert!(membership.local_node_index.is_none()); + assert!(!membership.contains_local()); +} + +#[test] +fn test_membership_new_empty() { + let local_key = key(99); + + let membership = Membership::::new(&[], &local_key); + + assert_eq!(membership.size(), 0); + assert!(membership.core_nodes.keys().next().is_none()); + assert!(membership.node_indices.is_empty()); + assert!(membership.local_node_index.is_none()); + assert!(!membership.contains_local()); +} + +#[test] +fn test_choose_remote_nodes() { + let nodes = vec![node(1, 1), node(2, 2), node(3, 3), node(4, 4)]; + let local_key = key(99); + let membership = Membership::new(&nodes, &local_key); + + let chosen: HashSet<_> = membership + .choose_remote_nodes(&mut OsRng, 2) + .map(|node| node.id) + .collect(); + assert_eq!(chosen.len(), 2); +} + +#[test] +fn test_choose_remote_nodes_more_than_available() { + let nodes = vec![node(1, 1), node(2, 2)]; + let local_key = key(99); + let membership = Membership::new(&nodes, &local_key); + + let chosen: HashSet<_> = membership + .choose_remote_nodes(&mut OsRng, 5) + .map(|node| node.id) + .collect(); + assert_eq!(chosen.len(), 2); +} + +#[test] +fn test_choose_remote_nodes_zero() { + let nodes = vec![node(1, 1), node(2, 2)]; + let local_key = key(99); + let membership = Membership::new(&nodes, &local_key); + + let mut rng = OsRng; + let mut chosen = membership.choose_remote_nodes(&mut rng, 0); + assert!(chosen.next().is_none()); +} + +#[test] +fn test_filter_and_choose_remote_nodes() { + let nodes = vec![node(1, 1), node(2, 2), node(3, 3)]; + let local_key = key(99); + let membership = Membership::new(&nodes, &local_key); + let exclude_peers = HashSet::from([3]); + + let chosen: HashSet<_> = membership + .filter_and_choose_remote_nodes(&mut OsRng, 2, &exclude_peers) + .map(|node| node.id) + .collect(); + assert_eq!(chosen.len(), 2); +} + +#[test] +fn test_filter_and_choose_remote_nodes_all_excluded() { + let nodes = vec![node(1, 1), node(2, 2)]; + let local_key = key(99); + let membership = Membership::new(&nodes, &local_key); + let exclude_peers = HashSet::from([1, 2]); + + let chosen: HashSet<_> = membership + .filter_and_choose_remote_nodes(&mut OsRng, 2, &exclude_peers) + .map(|node| node.id) + .collect(); + assert!(chosen.is_empty()); +} + +#[test] +fn test_contains() { + let nodes = vec![node(1, 1)]; + let local_key = key(99); + let membership = Membership::new(&nodes, &local_key); + + assert!(membership.contains(&1)); + assert!(!membership.contains(&2)); +} + +#[test] +fn get_node_at() { + let nodes = vec![node(1, 1)]; + let local_key = key(99); + let membership = Membership::new(&nodes, &local_key); + + assert_eq!(membership.get_node_at(0), Some(&node(1, 1))); + assert_eq!(membership.get_node_at(1), None); +} + +#[test] +#[should_panic(expected = "Membership info contained a duplicate node.")] +fn duplicate_remote_node() { + let nodes = vec![node(1, 1), node(1, 2)]; + let local_key = key(99); + drop(Membership::new(&nodes, &local_key)); +} + +fn key(seed: u8) -> Ed25519PublicKey { + UnsecuredEd25519Key::from_bytes(&[seed; 32]).public_key() +} + +fn node(id: u32, seed: u8) -> Node { + Node { + id, + address: Multiaddr::empty(), + public_key: key(seed), + } +} diff --git a/blend/message/src/codec.rs b/blend/message/src/codec.rs new file mode 100644 index 000000000..edda918d4 --- /dev/null +++ b/blend/message/src/codec.rs @@ -0,0 +1,50 @@ +//! Wire helpers for whole encapsulated messages. +//! +//! Thin wrappers over the [`lb_codec`] impls, kept here so a crate that only +//! moves messages around — the network behaviours, say — does not have to +//! depend on anything that knows how to *produce* one. + +use core::num::NonZeroU64; + +use lb_codec::{BinaryDecode as _, BinaryEncode as _}; + +use crate::{ + Error, + encap::{ + encapsulated::EncapsulatedMessage, + validated::{ + EncapsulatedMessageWithVerifiedPublicHeader, EncapsulatedMessageWithVerifiedSignature, + }, + }, +}; + +#[must_use] +pub fn serialize_encapsulated_message_with_verified_public_header( + message: &EncapsulatedMessageWithVerifiedPublicHeader, +) -> Vec { + message.encode_to_vec() +} + +#[must_use] +pub fn serialize_encapsulated_message_with_verified_signature( + message: &EncapsulatedMessageWithVerifiedSignature, +) -> Vec { + message.encode_to_vec() +} + +/// Decodes a whole encapsulated message, rejecting trailing bytes. +/// +/// # Errors +/// +/// [`Error::MessageDeserializationFailed`] if the input does not decode, or +/// decodes with bytes left over. +pub fn deserialize_encapsulated_message( + message: &[u8], + num_blend_layers: &NonZeroU64, +) -> Result { + let (remaining, deserialized_message) = EncapsulatedMessage::decode(message, num_blend_layers)?; + if !remaining.is_empty() { + return Err(Error::MessageDeserializationFailed); + } + Ok(deserialized_message) +} diff --git a/blend/message/src/lib.rs b/blend/message/src/lib.rs index c7baba925..24891b5e3 100644 --- a/blend/message/src/lib.rs +++ b/blend/message/src/lib.rs @@ -1,3 +1,4 @@ +pub mod codec; pub mod crypto; pub mod encap; pub mod input; @@ -7,6 +8,10 @@ mod error; mod fixtures; mod message; +pub use codec::{ + deserialize_encapsulated_message, serialize_encapsulated_message_with_verified_public_header, + serialize_encapsulated_message_with_verified_signature, +}; pub use encap::encapsulated::MessageIdentifier; pub use error::Error; pub use message::payload::{MAX_PAYLOAD_BODY_SIZE, PaddedPayloadBody, PayloadType}; diff --git a/blend/network/Cargo.toml b/blend/network/Cargo.toml index df265f375..0a9cc53aa 100644 --- a/blend/network/Cargo.toml +++ b/blend/network/Cargo.toml @@ -17,9 +17,9 @@ either = { workspace = true } futures = { workspace = true } futures-timer = { workspace = true } hex = { workspace = true } +lb-blend-membership = { workspace = true } lb-blend-message = { workspace = true } lb-blend-proofs = { workspace = true } -lb-blend-scheduling = { workspace = true } lb-cryptarchia-engine = { workspace = true } lb-groth16 = { workspace = true } lb-key-management-system-keys = { workspace = true } @@ -32,8 +32,9 @@ tracing = { workspace = true } [dev-dependencies] async-trait = { workspace = true } +lb-blend-membership = { features = ["unsafe-test-functions"], workspace = true } lb-blend-message = { features = ["unsafe-test-functions"], workspace = true } -lb-blend-scheduling = { features = ["unsafe-test-functions"], workspace = true } +lb-blend-provers = { features = ["unsafe-test-functions"], workspace = true } libp2p = { features = ["plaintext", "tcp", "yamux"], workspace = true } libp2p-stream = { workspace = true } libp2p-swarm-test = { features = ["tokio"], workspace = true } diff --git a/blend/network/src/core/mod.rs b/blend/network/src/core/mod.rs index 523033665..f5ceaf8f6 100644 --- a/blend/network/src/core/mod.rs +++ b/blend/network/src/core/mod.rs @@ -6,7 +6,7 @@ mod poq_verification; #[cfg(test)] mod tests; -use lb_blend_scheduling::membership::Membership; +use lb_blend_membership::Membership; use lb_cryptarchia_engine::Epoch; use libp2p::{PeerId, StreamProtocol}; diff --git a/blend/network/src/core/tests/utils.rs b/blend/network/src/core/tests/utils.rs index be0894b2f..66cf87b1d 100644 --- a/blend/network/src/core/tests/utils.rs +++ b/blend/network/src/core/tests/utils.rs @@ -15,7 +15,7 @@ use lb_blend_proofs::{ quota::{ProofOfQuota, VerifiedProofOfQuota}, selection::{ProofOfSelection, VerifiedProofOfSelection, inputs::VerifyInputs}, }; -use lb_blend_scheduling::message_blend::provers::BlendLayerProof; +use lb_blend_provers::provers::BlendLayerProof; use lb_cryptarchia_engine::Epoch; use lb_key_management_system_keys::keys::{ Ed25519PublicKey, Ed25519Signature, UnsecuredEd25519Key, diff --git a/blend/network/src/core/with_core/behaviour/mod.rs b/blend/network/src/core/with_core/behaviour/mod.rs index b8e7e006a..0c9f2b292 100644 --- a/blend/network/src/core/with_core/behaviour/mod.rs +++ b/blend/network/src/core/with_core/behaviour/mod.rs @@ -12,10 +12,10 @@ use std::{ use either::Either; use futures::{Stream, StreamExt as _}; +use lb_blend_membership::Membership; use lb_blend_message::encap::{ ProofsVerifier as ProofsVerifierTrait, validated::EncapsulatedMessageWithVerifiedPublicHeader, }; -use lb_blend_scheduling::membership::Membership; use lb_cryptarchia_engine::Epoch; use lb_groth16::fr_to_bytes; use lb_log_targets::blend; @@ -377,9 +377,7 @@ impl epoch: Epoch, ) -> Result<(), SendError> { let serialized_message = - lb_blend_scheduling::serialize_encapsulated_message_with_verified_public_header( - message, - ); + lb_blend_message::serialize_encapsulated_message_with_verified_public_header(message); self.force_send_serialized_message_to_peer_at_epoch(serialized_message, peer_id, epoch) } diff --git a/blend/network/src/core/with_core/behaviour/tests/epoch.rs b/blend/network/src/core/with_core/behaviour/tests/epoch.rs index 44be853b4..33bed486d 100644 --- a/blend/network/src/core/with_core/behaviour/tests/epoch.rs +++ b/blend/network/src/core/with_core/behaviour/tests/epoch.rs @@ -2,8 +2,8 @@ use core::time::Duration; use either::Either; use futures::StreamExt as _; +use lb_blend_membership::Membership; use lb_blend_message::encap::validated::EncapsulatedMessageWithVerifiedPublicHeader; -use lb_blend_scheduling::membership::Membership; use lb_cryptarchia_engine::Epoch; use lb_libp2p::{NetworkBehaviour as _, SwarmEvent}; use libp2p::{Multiaddr, swarm::ConnectionId}; diff --git a/blend/network/src/core/with_core/behaviour/tests/message_handling.rs b/blend/network/src/core/with_core/behaviour/tests/message_handling.rs index 599e3aaed..c04c41ffb 100644 --- a/blend/network/src/core/with_core/behaviour/tests/message_handling.rs +++ b/blend/network/src/core/with_core/behaviour/tests/message_handling.rs @@ -2,7 +2,7 @@ use core::time::Duration; use std::collections::HashSet; use futures::StreamExt as _; -use lb_blend_scheduling::serialize_encapsulated_message_with_verified_public_header; +use lb_blend_message::serialize_encapsulated_message_with_verified_public_header; use lb_libp2p::SwarmEvent; use libp2p_swarm_test::SwarmExt as _; use test_log::test; diff --git a/blend/network/src/core/with_core/behaviour/tests/utils.rs b/blend/network/src/core/with_core/behaviour/tests/utils.rs index ba0f134e4..55b742901 100644 --- a/blend/network/src/core/with_core/behaviour/tests/utils.rs +++ b/blend/network/src/core/with_core/behaviour/tests/utils.rs @@ -11,8 +11,8 @@ use std::{ use async_trait::async_trait; use futures::{Stream, StreamExt as _, select}; +use lb_blend_membership::{Membership, Node}; use lb_blend_message::crypto::key_ext::Ed25519SecretKeyExt as _; -use lb_blend_scheduling::membership::{Membership, Node}; use lb_key_management_system_keys::keys::{Ed25519PublicKey, UnsecuredEd25519Key}; use lb_libp2p::{NetworkBehaviour, SwarmEvent}; use libp2p::{ diff --git a/blend/network/src/core/with_core/behaviour/utils.rs b/blend/network/src/core/with_core/behaviour/utils.rs index a1ea6ebb1..0073e984e 100644 --- a/blend/network/src/core/with_core/behaviour/utils.rs +++ b/blend/network/src/core/with_core/behaviour/utils.rs @@ -2,11 +2,10 @@ use core::{convert::Infallible, num::NonZeroU64, task::Waker}; use std::{collections::VecDeque, sync::Arc}; use either::Either; -use lb_blend_message::encap::{ - ProofsVerifier, validated::EncapsulatedMessageWithVerifiedPublicHeader, -}; -use lb_blend_scheduling::{ - deserialize_encapsulated_message, serialize_encapsulated_message_with_verified_public_header, +use lb_blend_message::{ + deserialize_encapsulated_message, + encap::{ProofsVerifier, validated::EncapsulatedMessageWithVerifiedPublicHeader}, + serialize_encapsulated_message_with_verified_public_header, }; use lb_cryptarchia_engine::Epoch; use libp2p::{ diff --git a/blend/network/src/core/with_edge/behaviour/mod.rs b/blend/network/src/core/with_edge/behaviour/mod.rs index c7890d410..4b0c3d0dd 100644 --- a/blend/network/src/core/with_edge/behaviour/mod.rs +++ b/blend/network/src/core/with_edge/behaviour/mod.rs @@ -10,10 +10,14 @@ use std::{ use either::Either; use futures::StreamExt as _; -use lb_blend_message::encap::{ - ProofsVerifier as ProofsVerifierTrait, validated::EncapsulatedMessageWithVerifiedPublicHeader, +use lb_blend_membership::Membership; +use lb_blend_message::{ + deserialize_encapsulated_message, + encap::{ + ProofsVerifier as ProofsVerifierTrait, + validated::EncapsulatedMessageWithVerifiedPublicHeader, + }, }; -use lb_blend_scheduling::{deserialize_encapsulated_message, membership::Membership}; use lb_cryptarchia_engine::Epoch; use lb_log_targets::blend; use libp2p::{ diff --git a/blend/network/src/core/with_edge/behaviour/tests/epoch.rs b/blend/network/src/core/with_edge/behaviour/tests/epoch.rs index 0cc4bbe2a..011993022 100644 --- a/blend/network/src/core/with_edge/behaviour/tests/epoch.rs +++ b/blend/network/src/core/with_edge/behaviour/tests/epoch.rs @@ -1,7 +1,7 @@ use core::time::Duration; use futures::StreamExt as _; -use lb_blend_scheduling::membership::{Membership, Node}; +use lb_blend_membership::{Membership, Node}; use lb_key_management_system_keys::keys::{ED25519_PUBLIC_KEY_SIZE, Ed25519PublicKey}; use lb_libp2p::SwarmEvent; use libp2p::{Multiaddr, PeerId}; diff --git a/blend/network/src/core/with_edge/behaviour/tests/message_handling.rs b/blend/network/src/core/with_edge/behaviour/tests/message_handling.rs index 0399d07aa..3767c8222 100644 --- a/blend/network/src/core/with_edge/behaviour/tests/message_handling.rs +++ b/blend/network/src/core/with_edge/behaviour/tests/message_handling.rs @@ -2,7 +2,7 @@ use core::time::Duration; use futures::{FutureExt as _, StreamExt as _, select}; use futures_timer::Delay; -use lb_blend_scheduling::serialize_encapsulated_message_with_verified_public_header; +use lb_blend_message::serialize_encapsulated_message_with_verified_public_header; use lb_libp2p::SwarmEvent; use libp2p::PeerId; use libp2p_stream::Behaviour as StreamBehaviour; diff --git a/blend/network/src/core/with_edge/behaviour/tests/utils.rs b/blend/network/src/core/with_edge/behaviour/tests/utils.rs index 7dd70b268..ad3248fd4 100644 --- a/blend/network/src/core/with_edge/behaviour/tests/utils.rs +++ b/blend/network/src/core/with_edge/behaviour/tests/utils.rs @@ -9,7 +9,7 @@ use std::{ use async_trait::async_trait; use futures::StreamExt as _; -use lb_blend_scheduling::membership::{Membership, Node}; +use lb_blend_membership::{Membership, Node}; use lb_key_management_system_keys::keys::{ED25519_PUBLIC_KEY_SIZE, Ed25519PublicKey}; use lb_libp2p::SwarmEvent; use libp2p::{Multiaddr, PeerId, Stream, Swarm}; diff --git a/blend/provers/Cargo.toml b/blend/provers/Cargo.toml new file mode 100644 index 000000000..b5d109f9a --- /dev/null +++ b/blend/provers/Cargo.toml @@ -0,0 +1,45 @@ +[package] +categories = { workspace = true } +description = { workspace = true } +edition = { workspace = true } +keywords = { workspace = true } +license = { workspace = true } +name = "logos-blockchain-blend-provers" +readme = { workspace = true } +repository = { workspace = true } +version = { workspace = true } + +[lints] +workspace = true + +[dependencies] +async-trait = { workspace = true } +derivative = { workspace = true } +futures = { workspace = true } +hex = { workspace = true } +lb-blend-membership = { workspace = true } +lb-blend-message = { workspace = true } +lb-blend-proofs = { workspace = true } +lb-core = { workspace = true } +lb-cryptarchia-engine = { workspace = true } +lb-groth16 = { workspace = true } +lb-key-management-system-keys = { workspace = true } +lb-log-targets = { workspace = true } +lb-utils = { features = ["rng", "tokio"], workspace = true } +rand = { features = ["alloc"], workspace = true } +rayon = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } + +[dev-dependencies] +lb-blend-membership = { features = ["unsafe-test-functions"], workspace = true } +lb-blend-message = { features = ["unsafe-test-functions"], workspace = true } +lb-blend-proofs = { features = ["unsafe-test-functions"], workspace = true } +lb-groth16 = { workspace = true } +libp2p = { workspace = true } +multiaddr = { workspace = true } +test-log = { features = ["trace"], workspace = true } + +[features] +tokio-task-names = ["lb-utils/tokio-task-names"] +unsafe-test-functions = [] diff --git a/blend/scheduling/src/message_blend/crypto/core_and_leader/mod.rs b/blend/provers/src/crypto/core_and_leader/mod.rs similarity index 100% rename from blend/scheduling/src/message_blend/crypto/core_and_leader/mod.rs rename to blend/provers/src/crypto/core_and_leader/mod.rs diff --git a/blend/scheduling/src/message_blend/crypto/core_and_leader/receive.rs b/blend/provers/src/crypto/core_and_leader/receive.rs similarity index 98% rename from blend/scheduling/src/message_blend/crypto/core_and_leader/receive.rs rename to blend/provers/src/crypto/core_and_leader/receive.rs index 933ab7028..1bc3ef171 100644 --- a/blend/scheduling/src/message_blend/crypto/core_and_leader/receive.rs +++ b/blend/provers/src/crypto/core_and_leader/receive.rs @@ -1,3 +1,4 @@ +use lb_blend_membership::Membership; use lb_blend_message::{ Error, crypto::proofs::PoQVerificationInputsMinusSigningKey, @@ -12,9 +13,7 @@ use lb_blend_message::{ use lb_cryptarchia_engine::Epoch; use lb_key_management_system_keys::keys::X25519PrivateKey; -use crate::{ - membership::Membership, message_blend::crypto::EncapsulatedMessageWithVerifiedPublicHeader, -}; +use crate::crypto::EncapsulatedMessageWithVerifiedPublicHeader; /// [`EpochCryptographicProcessor`] is responsible for only unwrapping the /// messages addressed to the local node. diff --git a/blend/scheduling/src/message_blend/crypto/core_and_leader/send.rs b/blend/provers/src/crypto/core_and_leader/send.rs similarity index 95% rename from blend/scheduling/src/message_blend/crypto/core_and_leader/send.rs rename to blend/provers/src/crypto/core_and_leader/send.rs index d627e3050..c026af346 100644 --- a/blend/scheduling/src/message_blend/crypto/core_and_leader/send.rs +++ b/blend/provers/src/crypto/core_and_leader/send.rs @@ -1,6 +1,7 @@ use core::{hash::Hash, marker::PhantomData}; use std::{num::NonZeroU64, sync::Arc}; +use lb_blend_membership::Membership; use lb_blend_message::{ Error, PaddedPayloadBody, PayloadType, crypto::proofs::PoQVerificationInputsMinusSigningKey, input::EncapsulationInput, @@ -11,13 +12,10 @@ use lb_groth16::fr_to_bytes; use rayon::ThreadPool; use crate::{ - membership::Membership, - message_blend::{ - crypto::EncapsulatedMessageWithVerifiedPublicHeader, - provers::{ - BlendLayerProof, ProofsGeneratorSettings, WinningPolInfoStream, - core_leader_and_pow::CoreLeaderAndPowProofsGenerator, - }, + crypto::EncapsulatedMessageWithVerifiedPublicHeader, + provers::{ + BlendLayerProof, ProofsGeneratorSettings, WinningPolInfoStream, + core_leader_and_pow::CoreLeaderAndPowProofsGenerator, }, }; @@ -214,6 +212,7 @@ mod test { use std::{num::NonZeroU64, sync::Arc}; use futures::{StreamExt as _, stream::repeat}; + use lb_blend_membership::{Membership, Node}; use lb_blend_message::crypto::proofs::PoQVerificationInputsMinusSigningKey; use lb_blend_proofs::quota::{ Quota, @@ -231,11 +230,8 @@ mod test { use rayon::ThreadPoolBuilder; use super::EpochCryptographicProcessor; - use crate::{ - membership::{Membership, Node}, - message_blend::crypto::test_utils::{ - MockCorePoQGenerator, TestEpochChangeCoreAndLeaderProofsGenerator, - }, + use crate::crypto::test_utils::{ + MockCorePoQGenerator, TestEpochChangeCoreAndLeaderProofsGenerator, }; #[tokio::test] diff --git a/blend/scheduling/src/message_blend/crypto/core_and_leader/send_and_receive.rs b/blend/provers/src/crypto/core_and_leader/send_and_receive.rs similarity index 89% rename from blend/scheduling/src/message_blend/crypto/core_and_leader/send_and_receive.rs rename to blend/provers/src/crypto/core_and_leader/send_and_receive.rs index 01c7e11fc..99809329a 100644 --- a/blend/scheduling/src/message_blend/crypto/core_and_leader/send_and_receive.rs +++ b/blend/provers/src/crypto/core_and_leader/send_and_receive.rs @@ -1,5 +1,6 @@ use core::ops::{Deref, DerefMut}; +use lb_blend_membership::Membership; use lb_blend_message::{ Error, crypto::proofs::PoQVerificationInputsMinusSigningKey, @@ -8,17 +9,14 @@ use lb_blend_message::{ use lb_cryptarchia_engine::Epoch; use crate::{ - membership::Membership, - message_blend::{ - crypto::{ - EncapsulatedMessageWithVerifiedPublicHeader, EpochCryptographicProcessorSettings, - core_and_leader::{ - receive::EpochCryptographicProcessor as ReceiverEpochCryptographicProcessor, - send::EpochCryptographicProcessor as SenderEpochCryptographicProcessor, - }, + crypto::{ + EncapsulatedMessageWithVerifiedPublicHeader, EpochCryptographicProcessorSettings, + core_and_leader::{ + receive::EpochCryptographicProcessor as ReceiverEpochCryptographicProcessor, + send::EpochCryptographicProcessor as SenderEpochCryptographicProcessor, }, - provers::core_leader_and_pow::CoreLeaderAndPowProofsGenerator, }, + provers::core_leader_and_pow::CoreLeaderAndPowProofsGenerator, }; /// [`EpochCryptographicProcessor`] is responsible for wrapping both cover and @@ -133,6 +131,7 @@ mod test { use std::{num::NonZeroU64, sync::Arc}; use futures::{StreamExt as _, stream::repeat}; + use lb_blend_membership::{Membership, Node}; use lb_blend_message::crypto::proofs::PoQVerificationInputsMinusSigningKey; use lb_blend_proofs::quota::{ Quota, @@ -148,15 +147,12 @@ mod test { use multiaddr::{Multiaddr, PeerId}; use rayon::ThreadPoolBuilder; - use crate::{ - membership::{Membership, Node}, - message_blend::crypto::{ - EpochCryptographicProcessorSettings, - core_and_leader::send_and_receive::EpochCryptographicProcessor, - test_utils::{ - MockCorePoQGenerator, TestEpochChangeCoreAndLeaderProofsGenerator, - TestEpochChangeProofsVerifier, - }, + use crate::crypto::{ + EpochCryptographicProcessorSettings, + core_and_leader::send_and_receive::EpochCryptographicProcessor, + test_utils::{ + MockCorePoQGenerator, TestEpochChangeCoreAndLeaderProofsGenerator, + TestEpochChangeProofsVerifier, }, }; diff --git a/blend/scheduling/src/message_blend/crypto/leader/mod.rs b/blend/provers/src/crypto/leader/mod.rs similarity index 100% rename from blend/scheduling/src/message_blend/crypto/leader/mod.rs rename to blend/provers/src/crypto/leader/mod.rs diff --git a/blend/scheduling/src/message_blend/crypto/leader/send.rs b/blend/provers/src/crypto/leader/send.rs similarity index 95% rename from blend/scheduling/src/message_blend/crypto/leader/send.rs rename to blend/provers/src/crypto/leader/send.rs index 69cc67eb3..b3d5e41ee 100644 --- a/blend/scheduling/src/message_blend/crypto/leader/send.rs +++ b/blend/provers/src/crypto/leader/send.rs @@ -1,6 +1,7 @@ use core::hash::Hash; use std::{num::NonZeroU64, sync::Arc}; +use lb_blend_membership::Membership; use lb_blend_message::{ Error, PaddedPayloadBody, crypto::proofs::PoQVerificationInputsMinusSigningKey, input::EncapsulationInput, @@ -9,13 +10,10 @@ use lb_cryptarchia_engine::Epoch; use rayon::ThreadPool; use crate::{ - membership::Membership, - message_blend::{ - crypto::EncapsulatedMessageWithVerifiedPublicHeader, - provers::{ - BlendLayerProof, ProofsGeneratorSettings, WinningPolInfoStream, - leader_and_pow::LeaderAndPowProofsGenerator, - }, + crypto::EncapsulatedMessageWithVerifiedPublicHeader, + provers::{ + BlendLayerProof, ProofsGeneratorSettings, WinningPolInfoStream, + leader_and_pow::LeaderAndPowProofsGenerator, }, }; diff --git a/blend/scheduling/src/message_blend/crypto/mod.rs b/blend/provers/src/crypto/mod.rs similarity index 62% rename from blend/scheduling/src/message_blend/crypto/mod.rs rename to blend/provers/src/crypto/mod.rs index 54f3ea03d..32c7df475 100644 --- a/blend/scheduling/src/message_blend/crypto/mod.rs +++ b/blend/provers/src/crypto/mod.rs @@ -1,17 +1,8 @@ use std::{num::NonZeroU64, sync::Arc}; use derivative::Derivative; -use lb_blend_message::{ - Error, - encap::{ - encapsulated::EncapsulatedMessage, - validated::{ - EncapsulatedMessageWithVerifiedPublicHeader, EncapsulatedMessageWithVerifiedSignature, - }, - }, -}; +pub use lb_blend_message::encap::validated::EncapsulatedMessageWithVerifiedPublicHeader; use lb_blend_proofs::quota::Quota; -use lb_codec::{BinaryDecode as _, BinaryEncode as _}; use lb_key_management_system_keys::keys::X25519PrivateKey; use rayon::ThreadPool; @@ -45,28 +36,3 @@ pub struct EpochCryptographicProcessorSettings { /// generator resumes rather than replaying key nullifiers. pub spent_core_quota: Quota, } - -#[must_use] -pub fn serialize_encapsulated_message_with_verified_public_header( - message: &EncapsulatedMessageWithVerifiedPublicHeader, -) -> Vec { - message.encode_to_vec() -} - -#[must_use] -pub fn serialize_encapsulated_message_with_verified_signature( - message: &EncapsulatedMessageWithVerifiedSignature, -) -> Vec { - message.encode_to_vec() -} - -pub fn deserialize_encapsulated_message( - message: &[u8], - num_blend_layers: &NonZeroU64, -) -> Result { - let (remaining, deserialized_message) = EncapsulatedMessage::decode(message, num_blend_layers)?; - if !remaining.is_empty() { - return Err(Error::MessageDeserializationFailed); - } - Ok(deserialized_message) -} diff --git a/blend/scheduling/src/message_blend/crypto/test_utils.rs b/blend/provers/src/crypto/test_utils.rs similarity index 99% rename from blend/scheduling/src/message_blend/crypto/test_utils.rs rename to blend/provers/src/crypto/test_utils.rs index 2da778e08..78d07a870 100644 --- a/blend/scheduling/src/message_blend/crypto/test_utils.rs +++ b/blend/provers/src/crypto/test_utils.rs @@ -13,7 +13,7 @@ use lb_core::crypto::ZkHash; use lb_cryptarchia_engine::Epoch; use lb_key_management_system_keys::keys::Ed25519PublicKey; -use crate::message_blend::{ +use crate::{ CoreProofOfQuotaGenerator, provers::{ BlendLayerProof, ProofsGeneratorSettings, WinningPolInfoStream, diff --git a/blend/scheduling/src/message_blend/mod.rs b/blend/provers/src/lib.rs similarity index 100% rename from blend/scheduling/src/message_blend/mod.rs rename to blend/provers/src/lib.rs diff --git a/blend/scheduling/src/message_blend/provers/core/mod.rs b/blend/provers/src/provers/core/mod.rs similarity index 99% rename from blend/scheduling/src/message_blend/provers/core/mod.rs rename to blend/provers/src/provers/core/mod.rs index e598798c4..104e74063 100644 --- a/blend/scheduling/src/message_blend/provers/core/mod.rs +++ b/blend/provers/src/provers/core/mod.rs @@ -15,7 +15,7 @@ use lb_log_targets::blend; use lb_utils::tokio::{stream::Buffered, task::spawn}; use tokio::time::Instant; -use crate::message_blend::{ +use crate::{ CoreProofOfQuotaGenerator, buffer_size, provers::{BlendLayerProof, ProofsGeneratorSettings}, }; diff --git a/blend/scheduling/src/message_blend/provers/core/tests.rs b/blend/provers/src/provers/core/tests.rs similarity index 98% rename from blend/scheduling/src/message_blend/provers/core/tests.rs rename to blend/provers/src/provers/core/tests.rs index eb8d02fbd..a9d33d3f4 100644 --- a/blend/scheduling/src/message_blend/provers/core/tests.rs +++ b/blend/provers/src/provers/core/tests.rs @@ -8,7 +8,7 @@ use lb_cryptarchia_engine::Epoch; use rayon::ThreadPoolBuilder; use test_log::test; -use crate::message_blend::provers::{ +use crate::provers::{ ProofsGeneratorSettings, core::{CoreProofsGenerator as _, RealCoreProofsGenerator}, test_utils::{ diff --git a/blend/scheduling/src/message_blend/provers/core_and_leader/mod.rs b/blend/provers/src/provers/core_and_leader/mod.rs similarity index 98% rename from blend/scheduling/src/message_blend/provers/core_and_leader/mod.rs rename to blend/provers/src/provers/core_and_leader/mod.rs index 971036c78..b3e22991f 100644 --- a/blend/scheduling/src/message_blend/provers/core_and_leader/mod.rs +++ b/blend/provers/src/provers/core_and_leader/mod.rs @@ -6,7 +6,7 @@ use lb_blend_proofs::quota::KeyIndex; use lb_cryptarchia_engine::Epoch; use lb_log_targets::blend; -use crate::message_blend::{ +use crate::{ CoreProofOfQuotaGenerator, provers::{ BlendLayerProof, ProofsGeneratorSettings, WinningPolInfoStream, @@ -63,7 +63,7 @@ impl RealCoreAndLeaderProofsGenerator { #[cfg(test)] pub fn override_settings( &mut self, - new_settings: crate::message_blend::provers::core::CoreProofsGeneratorSettings, + new_settings: crate::provers::core::CoreProofsGeneratorSettings, ) { self.core_proofs_generator.settings = new_settings.clone(); if let Some(leader_proofs_generator) = &mut self.leader_proofs_generator { diff --git a/blend/scheduling/src/message_blend/provers/core_and_leader/tests.rs b/blend/provers/src/provers/core_and_leader/tests.rs similarity index 99% rename from blend/scheduling/src/message_blend/provers/core_and_leader/tests.rs rename to blend/provers/src/provers/core_and_leader/tests.rs index db17086ac..64596c52a 100644 --- a/blend/scheduling/src/message_blend/provers/core_and_leader/tests.rs +++ b/blend/provers/src/provers/core_and_leader/tests.rs @@ -9,7 +9,7 @@ use lb_cryptarchia_engine::Epoch; use rayon::ThreadPoolBuilder; use test_log::test; -use crate::message_blend::provers::{ +use crate::provers::{ ProofsGeneratorSettings, core::CoreProofsGeneratorSettings, core_and_leader::{CoreAndLeaderProofsGenerator as _, RealCoreAndLeaderProofsGenerator}, diff --git a/blend/scheduling/src/message_blend/provers/core_leader_and_pow/mod.rs b/blend/provers/src/provers/core_leader_and_pow/mod.rs similarity index 99% rename from blend/scheduling/src/message_blend/provers/core_leader_and_pow/mod.rs rename to blend/provers/src/provers/core_leader_and_pow/mod.rs index 16545599a..7b8f30fcc 100644 --- a/blend/scheduling/src/message_blend/provers/core_leader_and_pow/mod.rs +++ b/blend/provers/src/provers/core_leader_and_pow/mod.rs @@ -3,7 +3,7 @@ use lb_blend_proofs::quota::KeyIndex; use lb_cryptarchia_engine::Epoch; use lb_log_targets::blend; -use crate::message_blend::{ +use crate::{ CoreProofOfQuotaGenerator, provers::{ BlendLayerProof, ProofsGeneratorSettings, WinningPolInfoStream, diff --git a/blend/scheduling/src/message_blend/provers/core_leader_and_pow/tests.rs b/blend/provers/src/provers/core_leader_and_pow/tests.rs similarity index 99% rename from blend/scheduling/src/message_blend/provers/core_leader_and_pow/tests.rs rename to blend/provers/src/provers/core_leader_and_pow/tests.rs index cea35ed5e..8ec5b2a8e 100644 --- a/blend/scheduling/src/message_blend/provers/core_leader_and_pow/tests.rs +++ b/blend/provers/src/provers/core_leader_and_pow/tests.rs @@ -8,7 +8,7 @@ use lb_cryptarchia_engine::Epoch; use rayon::ThreadPoolBuilder; use test_log::test; -use crate::message_blend::provers::{ +use crate::provers::{ ProofsGeneratorSettings, core_leader_and_pow::{ CoreLeaderAndPowProofsGenerator as _, RealCoreLeaderAndPowProofsGenerator, diff --git a/blend/scheduling/src/message_blend/provers/leader/mod.rs b/blend/provers/src/provers/leader/mod.rs similarity index 99% rename from blend/scheduling/src/message_blend/provers/leader/mod.rs rename to blend/provers/src/provers/leader/mod.rs index aec03cc81..257a8bef7 100644 --- a/blend/scheduling/src/message_blend/provers/leader/mod.rs +++ b/blend/provers/src/provers/leader/mod.rs @@ -19,7 +19,7 @@ use lb_log_targets::blend; use lb_utils::tokio::{stream::Buffered, task::spawn_blocking}; use tokio::time::Instant; -use crate::message_blend::{ +use crate::{ buffer_size, provers::{BlendLayerProof, ProofsGeneratorSettings, WinningPolInfoStream}, }; diff --git a/blend/scheduling/src/message_blend/provers/leader/tests.rs b/blend/provers/src/provers/leader/tests.rs similarity index 98% rename from blend/scheduling/src/message_blend/provers/leader/tests.rs rename to blend/provers/src/provers/leader/tests.rs index 90a4a29bc..b5d424ab1 100644 --- a/blend/scheduling/src/message_blend/provers/leader/tests.rs +++ b/blend/provers/src/provers/leader/tests.rs @@ -8,7 +8,7 @@ use rayon::ThreadPoolBuilder; use test_log::test; use tokio::time::timeout; -use crate::message_blend::provers::{ +use crate::provers::{ ProofsGeneratorSettings, leader::{LeaderProofsGenerator as _, RealLeaderProofsGenerator}, test_utils::{ diff --git a/blend/scheduling/src/message_blend/provers/leader_and_pow/mod.rs b/blend/provers/src/provers/leader_and_pow/mod.rs similarity index 98% rename from blend/scheduling/src/message_blend/provers/leader_and_pow/mod.rs rename to blend/provers/src/provers/leader_and_pow/mod.rs index fdfd75f2b..09ff42b8d 100644 --- a/blend/scheduling/src/message_blend/provers/leader_and_pow/mod.rs +++ b/blend/provers/src/provers/leader_and_pow/mod.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use lb_log_targets::blend; -use crate::message_blend::provers::{ +use crate::provers::{ BlendLayerProof, ProofsGeneratorSettings, WinningPolInfoStream, leader::{LeaderProofsGenerator as _, RealLeaderProofsGenerator}, pow::{PowProofsGenerator as _, RealPowProofsGenerator}, diff --git a/blend/scheduling/src/message_blend/provers/leader_and_pow/tests.rs b/blend/provers/src/provers/leader_and_pow/tests.rs similarity index 98% rename from blend/scheduling/src/message_blend/provers/leader_and_pow/tests.rs rename to blend/provers/src/provers/leader_and_pow/tests.rs index aa494f8a6..74635c297 100644 --- a/blend/scheduling/src/message_blend/provers/leader_and_pow/tests.rs +++ b/blend/provers/src/provers/leader_and_pow/tests.rs @@ -6,7 +6,7 @@ use lb_cryptarchia_engine::Epoch; use rayon::ThreadPoolBuilder; use test_log::test; -use crate::message_blend::provers::{ +use crate::provers::{ ProofsGeneratorSettings, leader_and_pow::{LeaderAndPowProofsGenerator as _, RealLeaderAndPowProofsGenerator}, test_utils::{ diff --git a/blend/scheduling/src/message_blend/provers/mod.rs b/blend/provers/src/provers/mod.rs similarity index 100% rename from blend/scheduling/src/message_blend/provers/mod.rs rename to blend/provers/src/provers/mod.rs diff --git a/blend/scheduling/src/message_blend/provers/pow/mod.rs b/blend/provers/src/provers/pow/mod.rs similarity index 99% rename from blend/scheduling/src/message_blend/provers/pow/mod.rs rename to blend/provers/src/provers/pow/mod.rs index 352ca2f5a..4efcc9cd2 100644 --- a/blend/scheduling/src/message_blend/provers/pow/mod.rs +++ b/blend/provers/src/provers/pow/mod.rs @@ -29,7 +29,7 @@ use rand::rngs::OsRng; use rayon::{ThreadPool, ThreadPoolBuilder}; use tokio::{sync::oneshot, time::Instant}; -use crate::message_blend::provers::{BlendLayerProof, ProofsGeneratorSettings}; +use crate::provers::{BlendLayerProof, ProofsGeneratorSettings}; #[cfg(test)] mod tests; diff --git a/blend/scheduling/src/message_blend/provers/pow/tests.rs b/blend/provers/src/provers/pow/tests.rs similarity index 99% rename from blend/scheduling/src/message_blend/provers/pow/tests.rs rename to blend/provers/src/provers/pow/tests.rs index b10175925..69d6f79ae 100644 --- a/blend/scheduling/src/message_blend/provers/pow/tests.rs +++ b/blend/provers/src/provers/pow/tests.rs @@ -11,7 +11,7 @@ use rayon::ThreadPoolBuilder; use test_log::test; use tokio::time::timeout; -use crate::message_blend::provers::{ +use crate::provers::{ ProofsGeneratorSettings, pow::{PowProofsGenerator as _, RealPowProofsGenerator}, test_utils::{ diff --git a/blend/scheduling/src/message_blend/provers/test_utils.rs b/blend/provers/src/provers/test_utils.rs similarity index 98% rename from blend/scheduling/src/message_blend/provers/test_utils.rs rename to blend/provers/src/provers/test_utils.rs index e6ba8d1d1..5a6f078f9 100644 --- a/blend/scheduling/src/message_blend/provers/test_utils.rs +++ b/blend/provers/src/provers/test_utils.rs @@ -14,7 +14,7 @@ use lb_blend_proofs::quota::{ use lb_core::crypto::ZkHash; use lb_key_management_system_keys::keys::{ED25519_PUBLIC_KEY_SIZE, Ed25519PublicKey}; -use crate::message_blend::CoreProofOfQuotaGenerator; +use crate::CoreProofOfQuotaGenerator; pub const fn poq_public_inputs_from_epoch_public_inputs_and_signing_key( (PoQVerificationInputsMinusSigningKey { core, leader, pow }, signing_key): ( diff --git a/blend/scheduling/Cargo.toml b/blend/scheduling/Cargo.toml index b521ee3c1..eb2df12a6 100644 --- a/blend/scheduling/Cargo.toml +++ b/blend/scheduling/Cargo.toml @@ -13,35 +13,24 @@ version = { workspace = true } workspace = true [dependencies] -async-trait = { workspace = true } -derivative = { workspace = true } -fork_stream = { workspace = true } -futures = { workspace = true } -hex = { workspace = true } -lb-blend-message = { workspace = true } -lb-blend-proofs = { workspace = true } -lb-codec = { workspace = true } -lb-core = { workspace = true } -lb-cryptarchia-engine = { workspace = true } -lb-groth16 = { workspace = true } -lb-key-management-system-keys = { workspace = true } -lb-log-targets = { workspace = true } -lb-utils = { features = ["rng", "tokio"], workspace = true } -multiaddr = { workspace = true } -rand = { features = ["alloc"], workspace = true } -rayon = { workspace = true } -serde = { workspace = true } -thiserror = { workspace = true } -tokio = { workspace = true } -tokio-stream = { workspace = true } -tracing = { workspace = true } +fork_stream = { workspace = true } +futures = { workspace = true } +lb-blend-membership = { workspace = true } +lb-blend-message = { workspace = true } +lb-blend-proofs = { workspace = true } +lb-blend-provers = { workspace = true } +lb-cryptarchia-engine = { workspace = true } +lb-log-targets = { workspace = true } +lb-utils = { features = ["rng", "tokio"], workspace = true } +rand = { features = ["alloc"], workspace = true } +thiserror = { workspace = true } +tokio = { workspace = true } +tokio-stream = { workspace = true } +tracing = { workspace = true } [dev-dependencies] lb-blend-message = { features = ["unsafe-test-functions"], workspace = true } lb-blend-proofs = { features = ["unsafe-test-functions"], workspace = true } -lb-groth16 = { workspace = true } -libp2p = { workspace = true } -test-log = { features = ["trace"], workspace = true } [features] tokio-task-names = ["lb-utils/tokio-task-names"] diff --git a/blend/scheduling/src/lib.rs b/blend/scheduling/src/lib.rs index e1cbb1155..cc1f9a2be 100644 --- a/blend/scheduling/src/lib.rs +++ b/blend/scheduling/src/lib.rs @@ -1,13 +1,14 @@ pub mod epoch; -pub mod membership; -pub mod message_blend; -pub use message_blend::crypto::{ - deserialize_encapsulated_message, serialize_encapsulated_message_with_verified_public_header, - serialize_encapsulated_message_with_verified_signature, -}; pub mod message_scheduler; pub use message_scheduler::EpochMessageScheduler; pub mod stream; +pub use lb_blend_membership as membership; +pub use lb_blend_message::{ + deserialize_encapsulated_message, serialize_encapsulated_message_with_verified_public_header, + serialize_encapsulated_message_with_verified_signature, +}; +pub use lb_blend_provers as message_blend; + mod cover_traffic; mod release_delayer; diff --git a/blend/scheduling/src/membership.rs b/blend/scheduling/src/membership.rs deleted file mode 100644 index 58d6ac1b3..000000000 --- a/blend/scheduling/src/membership.rs +++ /dev/null @@ -1,312 +0,0 @@ -use std::{ - collections::{HashMap, HashSet}, - hash::Hash, -}; - -use lb_key_management_system_keys::keys::Ed25519PublicKey; -use multiaddr::Multiaddr; -use rand::{Rng, seq::IteratorRandom as _}; -use serde::{Deserialize, Serialize}; - -/// A set of core nodes in an epoch. -#[derive(Clone, Debug)] -pub struct Membership { - /// All nodes, including local and remote. - core_nodes: HashMap>, - /// List of node indices, used for proof of selection generation. It - /// contains all nodes in the `nodes` map. - node_indices: Vec, - /// ID of the local node in the `node_indices` vector, if present (i.e., if - /// the local node is a core node). - local_node_index: Option, -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] -pub struct Node { - /// An unique identifier of the node, - /// which is usually corresponding to the network node identifier - /// but depending on the network backend. - pub id: Id, - /// A listening address - pub address: Multiaddr, - /// A public key used for the blend message encryption - pub public_key: Ed25519PublicKey, -} - -impl Membership -where - NodeId: Clone + Hash + Eq, -{ - #[must_use] - pub fn new(nodes: &[Node], local_public_key: &Ed25519PublicKey) -> Self { - let mut core_nodes = HashMap::with_capacity(nodes.len()); - let mut node_indices = Vec::with_capacity(nodes.len()); - let mut local_node_index = None; - for (index, node) in nodes.iter().enumerate() { - assert!( - core_nodes.insert(node.id.clone(), node.clone()).is_none(), - "Membership info contained a duplicate node." - ); - node_indices.push(node.id.clone()); - if node.public_key == *local_public_key { - local_node_index = Some(index); - } - } - - Self { - core_nodes, - node_indices, - local_node_index, - } - } - - #[cfg(any(test, feature = "unsafe-test-functions"))] - #[must_use] - pub fn new_without_local(nodes: &[Node]) -> Self { - use lb_key_management_system_keys::keys::ED25519_PUBLIC_KEY_SIZE; - - Self::new( - nodes, - &Ed25519PublicKey::from_bytes(&[0; ED25519_PUBLIC_KEY_SIZE]).unwrap(), - ) - } -} - -impl Membership -where - NodeId: Eq + Hash, -{ - /// Choose `amount` random remote nodes. - pub fn choose_remote_nodes( - &self, - rng: &mut R, - amount: usize, - ) -> impl Iterator> + use<'_, R, NodeId> { - self.filter_and_choose_remote_nodes(rng, amount, &HashSet::new()) - } - - /// Choose `amount` random remote nodes excluding the given set of node IDs. - pub fn filter_and_choose_remote_nodes( - &self, - rng: &mut R, - amount: usize, - exclude_peers: &HashSet, - ) -> impl Iterator> + use<'_, R, NodeId> { - self.node_indices - .iter() - .enumerate() - // Filter out excluded peers. - .filter(|(_, node_id)| !exclude_peers.contains(node_id)) - // Filter out local node, if the local node is a core node. - .filter(|(index, _)| self.local_node_index != Some(*index)) - // Discard index after it's used. - .map(|(_, node)| node) - .choose_multiple(rng, amount) - .into_iter() - .map(|id| { - self.core_nodes - .get(id) - .expect("Node ID must exist in core nodes.") - }) - } - - pub fn contains(&self, node_id: &NodeId) -> bool { - self.core_nodes.contains_key(node_id) - } - - #[must_use] - pub fn get_node_at(&self, index: usize) -> Option<&Node> { - self.core_nodes.get(self.node_indices.get(index)?) - } -} - -impl Membership { - #[must_use] - pub const fn local_index(&self) -> Option { - self.local_node_index - } - - #[must_use] - pub const fn contains_local(&self) -> bool { - self.local_node_index.is_some() - } - - /// Returns the number of all nodes, including local and remote. - #[must_use] - pub fn size(&self) -> usize { - self.core_nodes.len() - } - - #[must_use] - pub fn is_empty(&self) -> bool { - self.core_nodes.is_empty() - } -} - -#[cfg(test)] -mod tests { - use lb_key_management_system_keys::keys::UnsecuredEd25519Key; - use rand::rngs::OsRng; - - use super::*; - - #[test] - fn test_membership_new_with_local_node() { - let nodes = vec![node(1, 1), node(2, 2), node(3, 3)]; - let local_key = key(2); - - let membership = Membership::new(&nodes, &local_key); - - assert_eq!(membership.size(), 3); - assert_eq!( - membership - .core_nodes - .keys() - .copied() - .collect::>(), - HashSet::from([1, 2, 3]) - ); - assert_eq!(membership.node_indices, vec![1, 2, 3]); - assert_eq!(membership.local_node_index, Some(1)); - assert!(membership.contains_local()); - } - - #[test] - fn test_membership_new_without_local_node() { - let nodes = vec![node(1, 1), node(2, 2), node(3, 3)]; - let local_key = key(99); - - let membership = Membership::new(&nodes, &local_key); - - assert_eq!(membership.size(), 3); - assert_eq!( - membership - .core_nodes - .keys() - .copied() - .collect::>(), - HashSet::from([1, 2, 3]) - ); - assert_eq!(membership.node_indices, vec![1, 2, 3]); - assert!(membership.local_node_index.is_none()); - assert!(!membership.contains_local()); - } - - #[test] - fn test_membership_new_empty() { - let local_key = key(99); - - let membership = Membership::::new(&[], &local_key); - - assert_eq!(membership.size(), 0); - assert!(membership.core_nodes.keys().next().is_none()); - assert!(membership.node_indices.is_empty()); - assert!(membership.local_node_index.is_none()); - assert!(!membership.contains_local()); - } - - #[test] - fn test_choose_remote_nodes() { - let nodes = vec![node(1, 1), node(2, 2), node(3, 3), node(4, 4)]; - let local_key = key(99); - let membership = Membership::new(&nodes, &local_key); - - let chosen: HashSet<_> = membership - .choose_remote_nodes(&mut OsRng, 2) - .map(|node| node.id) - .collect(); - assert_eq!(chosen.len(), 2); - } - - #[test] - fn test_choose_remote_nodes_more_than_available() { - let nodes = vec![node(1, 1), node(2, 2)]; - let local_key = key(99); - let membership = Membership::new(&nodes, &local_key); - - let chosen: HashSet<_> = membership - .choose_remote_nodes(&mut OsRng, 5) - .map(|node| node.id) - .collect(); - assert_eq!(chosen.len(), 2); - } - - #[test] - fn test_choose_remote_nodes_zero() { - let nodes = vec![node(1, 1), node(2, 2)]; - let local_key = key(99); - let membership = Membership::new(&nodes, &local_key); - - let mut rng = OsRng; - let mut chosen = membership.choose_remote_nodes(&mut rng, 0); - assert!(chosen.next().is_none()); - } - - #[test] - fn test_filter_and_choose_remote_nodes() { - let nodes = vec![node(1, 1), node(2, 2), node(3, 3)]; - let local_key = key(99); - let membership = Membership::new(&nodes, &local_key); - let exclude_peers = HashSet::from([3]); - - let chosen: HashSet<_> = membership - .filter_and_choose_remote_nodes(&mut OsRng, 2, &exclude_peers) - .map(|node| node.id) - .collect(); - assert_eq!(chosen.len(), 2); - } - - #[test] - fn test_filter_and_choose_remote_nodes_all_excluded() { - let nodes = vec![node(1, 1), node(2, 2)]; - let local_key = key(99); - let membership = Membership::new(&nodes, &local_key); - let exclude_peers = HashSet::from([1, 2]); - - let chosen: HashSet<_> = membership - .filter_and_choose_remote_nodes(&mut OsRng, 2, &exclude_peers) - .map(|node| node.id) - .collect(); - assert!(chosen.is_empty()); - } - - #[test] - fn test_contains() { - let nodes = vec![node(1, 1)]; - let local_key = key(99); - let membership = Membership::new(&nodes, &local_key); - - assert!(membership.contains(&1)); - assert!(!membership.contains(&2)); - } - - #[test] - fn get_node_at() { - let nodes = vec![node(1, 1)]; - let local_key = key(99); - let membership = Membership::new(&nodes, &local_key); - - assert_eq!(membership.get_node_at(0), Some(&node(1, 1))); - assert_eq!(membership.get_node_at(1), None); - } - - #[test] - #[should_panic(expected = "Membership info contained a duplicate node.")] - fn duplicate_remote_node() { - let nodes = vec![node(1, 1), node(1, 2)]; - let local_key = key(99); - drop(Membership::new(&nodes, &local_key)); - } - - fn key(seed: u8) -> Ed25519PublicKey { - UnsecuredEd25519Key::from_bytes(&[seed; 32]).public_key() - } - - fn node(id: u32, seed: u8) -> Node { - Node { - id, - address: Multiaddr::empty(), - public_key: key(seed), - } - } -}