mirror of
https://github.com/logos-co/nomos-node.git
synced 2026-08-27 09:31:10 +00:00
chore(blend): restructure existing core crates (#3404)
This commit is contained in:
Generated
+34
-5
@@ -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",
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 = []
|
||||
@@ -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<NodeId> {
|
||||
/// All nodes, including local and remote.
|
||||
core_nodes: HashMap<NodeId, Node<NodeId>>,
|
||||
/// List of node indices, used for proof of selection generation. It
|
||||
/// contains all nodes in the `nodes` map.
|
||||
node_indices: Vec<NodeId>,
|
||||
/// 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<usize>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct Node<Id> {
|
||||
/// 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<NodeId> Membership<NodeId>
|
||||
where
|
||||
NodeId: Clone + Hash + Eq,
|
||||
{
|
||||
#[must_use]
|
||||
pub fn new(nodes: &[Node<NodeId>], 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<NodeId>]) -> 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<NodeId> Membership<NodeId>
|
||||
where
|
||||
NodeId: Eq + Hash,
|
||||
{
|
||||
/// Choose `amount` random remote nodes.
|
||||
pub fn choose_remote_nodes<R: Rng>(
|
||||
&self,
|
||||
rng: &mut R,
|
||||
amount: usize,
|
||||
) -> impl Iterator<Item = &Node<NodeId>> + 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<R: Rng>(
|
||||
&self,
|
||||
rng: &mut R,
|
||||
amount: usize,
|
||||
exclude_peers: &HashSet<NodeId>,
|
||||
) -> impl Iterator<Item = &Node<NodeId>> + 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<NodeId>> {
|
||||
self.core_nodes.get(self.node_indices.get(index)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<NodeId> Membership<NodeId> {
|
||||
#[must_use]
|
||||
pub const fn local_index(&self) -> Option<usize> {
|
||||
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()
|
||||
}
|
||||
}
|
||||
@@ -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<_>>(),
|
||||
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<_>>(),
|
||||
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::<u32>::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<u32> {
|
||||
Node {
|
||||
id,
|
||||
address: Multiaddr::empty(),
|
||||
public_key: key(seed),
|
||||
}
|
||||
}
|
||||
@@ -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<u8> {
|
||||
message.encode_to_vec()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn serialize_encapsulated_message_with_verified_signature(
|
||||
message: &EncapsulatedMessageWithVerifiedSignature,
|
||||
) -> Vec<u8> {
|
||||
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<EncapsulatedMessage, Error> {
|
||||
let (remaining, deserialized_message) = EncapsulatedMessage::decode(message, num_blend_layers)?;
|
||||
if !remaining.is_empty() {
|
||||
return Err(Error::MessageDeserializationFailed);
|
||||
}
|
||||
Ok(deserialized_message)
|
||||
}
|
||||
@@ -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};
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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};
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<ObservationWindowClockProvider, ProofsVerifier>
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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::{
|
||||
|
||||
@@ -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::{
|
||||
|
||||
@@ -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::{
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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 = []
|
||||
+2
-3
@@ -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.
|
||||
+8
-12
@@ -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]
|
||||
+14
-18
@@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
+5
-7
@@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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<u8> {
|
||||
message.encode_to_vec()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn serialize_encapsulated_message_with_verified_signature(
|
||||
message: &EncapsulatedMessageWithVerifiedSignature,
|
||||
) -> Vec<u8> {
|
||||
message.encode_to_vec()
|
||||
}
|
||||
|
||||
pub fn deserialize_encapsulated_message(
|
||||
message: &[u8],
|
||||
num_blend_layers: &NonZeroU64,
|
||||
) -> Result<EncapsulatedMessage, Error> {
|
||||
let (remaining, deserialized_message) = EncapsulatedMessage::decode(message, num_blend_layers)?;
|
||||
if !remaining.is_empty() {
|
||||
return Err(Error::MessageDeserializationFailed);
|
||||
}
|
||||
Ok(deserialized_message)
|
||||
}
|
||||
+1
-1
@@ -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,
|
||||
+1
-1
@@ -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},
|
||||
};
|
||||
+1
-1
@@ -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::{
|
||||
+2
-2
@@ -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<CorePoQGenerator> RealCoreAndLeaderProofsGenerator<CorePoQGenerator> {
|
||||
#[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 {
|
||||
+1
-1
@@ -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},
|
||||
+1
-1
@@ -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,
|
||||
+1
-1
@@ -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,
|
||||
+1
-1
@@ -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},
|
||||
};
|
||||
+1
-1
@@ -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::{
|
||||
+1
-1
@@ -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},
|
||||
+1
-1
@@ -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::{
|
||||
+1
-1
@@ -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;
|
||||
+1
-1
@@ -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::{
|
||||
+1
-1
@@ -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): (
|
||||
+14
-25
@@ -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"]
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<NodeId> {
|
||||
/// All nodes, including local and remote.
|
||||
core_nodes: HashMap<NodeId, Node<NodeId>>,
|
||||
/// List of node indices, used for proof of selection generation. It
|
||||
/// contains all nodes in the `nodes` map.
|
||||
node_indices: Vec<NodeId>,
|
||||
/// 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<usize>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct Node<Id> {
|
||||
/// 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<NodeId> Membership<NodeId>
|
||||
where
|
||||
NodeId: Clone + Hash + Eq,
|
||||
{
|
||||
#[must_use]
|
||||
pub fn new(nodes: &[Node<NodeId>], 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<NodeId>]) -> 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<NodeId> Membership<NodeId>
|
||||
where
|
||||
NodeId: Eq + Hash,
|
||||
{
|
||||
/// Choose `amount` random remote nodes.
|
||||
pub fn choose_remote_nodes<R: Rng>(
|
||||
&self,
|
||||
rng: &mut R,
|
||||
amount: usize,
|
||||
) -> impl Iterator<Item = &Node<NodeId>> + 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<R: Rng>(
|
||||
&self,
|
||||
rng: &mut R,
|
||||
amount: usize,
|
||||
exclude_peers: &HashSet<NodeId>,
|
||||
) -> impl Iterator<Item = &Node<NodeId>> + 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<NodeId>> {
|
||||
self.core_nodes.get(self.node_indices.get(index)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<NodeId> Membership<NodeId> {
|
||||
#[must_use]
|
||||
pub const fn local_index(&self) -> Option<usize> {
|
||||
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<_>>(),
|
||||
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<_>>(),
|
||||
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::<u32>::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<u32> {
|
||||
Node {
|
||||
id,
|
||||
address: Multiaddr::empty(),
|
||||
public_key: key(seed),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user