From 2687c177f2cebb7d7b661985f4f7036b0587ba5d Mon Sep 17 00:00:00 2001 From: Povilas Liubauskas Date: Fri, 16 Aug 2024 13:28:13 +0300 Subject: [PATCH] Update `eth2_libp2p` --- Cargo.lock | 17 ++++++- Cargo.toml | 2 + eip_7594/Cargo.toml | 20 ++++++++ eip_7594/src/lib.rs | 101 +++++++++++++++++++++++++++++++++++++++++ eth2_libp2p | 2 +- p2p/src/network.rs | 14 ++++-- scripts/ci/clippy.bash | 1 + ssz/src/uint256.rs | 3 +- types/src/config.rs | 5 ++ 9 files changed, 159 insertions(+), 6 deletions(-) create mode 100644 eip_7594/Cargo.toml create mode 100644 eip_7594/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index dfc1059..4db95c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2043,6 +2043,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "eip_7594" +version = "0.0.0" +dependencies = [ + "duplicate", + "num-traits", + "serde", + "sha2 0.10.8", + "spec_test_utils", + "ssz", + "test-generator", + "typenum", + "types", +] + [[package]] name = "either" version = "1.13.0" @@ -2330,6 +2345,7 @@ dependencies = [ "delay_map", "dirs", "discv5", + "eip_7594", "either", "enum-iterator", "exit-future", @@ -2340,7 +2356,6 @@ dependencies = [ "grandine_version", "helper_functions", "hex", - "lazy_static", "libp2p", "libp2p-mplex", "lru", diff --git a/Cargo.toml b/Cargo.toml index d17c38d..c42e66d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ members = [ 'deposit_tree', 'directories', 'eip_2335', + 'eip_7594', 'eth1', 'eth1_api', 'eth2_cache_utils', @@ -439,6 +440,7 @@ database = { path = 'database' } deposit_tree = { path = 'deposit_tree' } directories = { path = 'directories' } eip_2335 = { path = 'eip_2335' } +eip_7594 = { path = 'eip_7594' } eth1 = { path = 'eth1' } eth1_api = { path = 'eth1_api' } eth2_cache_utils = { path = 'eth2_cache_utils' } diff --git a/eip_7594/Cargo.toml b/eip_7594/Cargo.toml new file mode 100644 index 0000000..71e61b1 --- /dev/null +++ b/eip_7594/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = 'eip_7594' +edition = { workspace = true } +authors = ["Grandine "] + +[lints] +workspace = true + +[dependencies] +num-traits = { workspace = true } +ssz = { workspace = true} +sha2 = { workspace = true } +typenum = { workspace = true } +types = { workspace = true } + +[dev-dependencies] +duplicate = { workspace = true } +serde = { workspace = true } +spec_test_utils = { workspace = true } +test-generator = { workspace = true } diff --git a/eip_7594/src/lib.rs b/eip_7594/src/lib.rs new file mode 100644 index 0000000..6ed4c05 --- /dev/null +++ b/eip_7594/src/lib.rs @@ -0,0 +1,101 @@ +use num_traits::One as _; +use sha2::{Digest as _, Sha256}; +use ssz::Uint256; +use typenum::Unsigned as _; +use types::{ + eip7594::{ColumnIndex, NumberOfColumns, DATA_COLUMN_SIDECAR_SUBNET_COUNT}, + phase0::primitives::NodeId, +}; + +pub fn get_custody_columns(node_id: NodeId, custody_subnet_count: u64) -> Vec { + assert!(custody_subnet_count <= DATA_COLUMN_SIDECAR_SUBNET_COUNT); + + let mut subnet_ids = vec![]; + let mut current_id = node_id; + + while (subnet_ids.len() as u64) < custody_subnet_count { + let mut hasher = Sha256::new(); + let mut bytes: [u8; 32] = [0; 32]; + + current_id.into_raw().to_little_endian(&mut bytes); + + hasher.update(&bytes); + bytes = hasher.finalize().into(); + + let output_prefix = [ + bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], + ]; + + let output_prefix_u64 = u64::from_le_bytes(output_prefix); + let subnet_id = output_prefix_u64 % DATA_COLUMN_SIDECAR_SUBNET_COUNT; + + if !subnet_ids.contains(&subnet_id) { + subnet_ids.push(subnet_id); + } + + if current_id == Uint256::MAX { + current_id = Uint256::ZERO; + } + + current_id = current_id + Uint256::one(); + } + + let columns_per_subnet = NumberOfColumns::U64 / DATA_COLUMN_SIDECAR_SUBNET_COUNT; + let mut result = Vec::new(); + for i in 0..columns_per_subnet { + for &subnet_id in &subnet_ids { + result.push( + (DATA_COLUMN_SIDECAR_SUBNET_COUNT * i + subnet_id) + .try_into() + .unwrap(), + ); + } + } + + result.sort(); + result +} + +#[cfg(test)] +mod tests { + use duplicate::duplicate_item; + use serde::Deserialize; + use spec_test_utils::Case; + use test_generator::test_resources; + use types::{ + phase0::primitives::NodeId, + preset::{Mainnet, Minimal, Preset}, + }; + + use crate::{get_custody_columns, ColumnIndex}; + + #[derive(Deserialize)] + #[serde(deny_unknown_fields)] + struct Meta { + description: Option, + node_id: NodeId, + custody_subnet_count: u64, + result: Vec, + } + + #[duplicate_item( + glob function_name preset; + ["consensus-spec-tests/tests/mainnet/eip7594/networking/get_custody_columns/*/*"] [get_custody_columns_mainnet] [Mainnet]; + ["consensus-spec-tests/tests/minimal/eip7594/networking/get_custody_columns/*/*"] [get_custody_columns_minimal] [Minimal]; + )] + #[test_resources(glob)] + fn function_name(case: Case) { + run_case::(case); + } + + fn run_case(case: Case) { + let Meta { + description: _description, + node_id, + custody_subnet_count, + result, + } = case.yaml::("meta"); + + assert_eq!(get_custody_columns(node_id, custody_subnet_count), result); + } +} diff --git a/eth2_libp2p b/eth2_libp2p index 21eb72b..7e82119 160000 --- a/eth2_libp2p +++ b/eth2_libp2p @@ -1 +1 @@ -Subproject commit 21eb72b46ad02bb8ac3b78cee05e31726e598b85 +Subproject commit 7e821193da991f73978525bc8082c3bad27b669b diff --git a/p2p/src/network.rs b/p2p/src/network.rs index 55d56a4..109b0c4 100644 --- a/p2p/src/network.rs +++ b/p2p/src/network.rs @@ -135,7 +135,7 @@ impl Network

{ metrics: Option>, libp2p_registry: Option<&mut Registry>, ) -> Result { - let chain_config = controller.chain_config().as_ref(); + let chain_config = controller.chain_config(); let head_state = controller.head_state().value; let fork_context = Arc::new(ForkContext::new::

( @@ -157,8 +157,13 @@ impl Network

{ }; // Box the future to pass `clippy::large_futures`. - let (service, network_globals) = - Box::pin(Service::new(chain_config, executor, context, &logger)).await?; + let (service, network_globals) = Box::pin(Service::new( + chain_config.clone_arc(), + executor, + context, + &logger, + )) + .await?; let mut port_mappings = None; @@ -1318,6 +1323,9 @@ impl Network

{ block_seen, ); } + PubsubMessage::DataColumnSidecar(_) => { + // TODO + } PubsubMessage::AggregateAndProofAttestation(aggregate_and_proof) => { if let Some(metrics) = self.metrics.as_ref() { metrics.register_gossip_object(&["aggregate_and_proof_attestation"]); diff --git a/scripts/ci/clippy.bash b/scripts/ci/clippy.bash index 9d456c4..43de208 100755 --- a/scripts/ci/clippy.bash +++ b/scripts/ci/clippy.bash @@ -27,6 +27,7 @@ options=( --package deposit_tree --package directories --package eip_2335 + --package eip_7594 --package eth1 --package eth1_api --package eth2_cache_utils diff --git a/ssz/src/uint256.rs b/ssz/src/uint256.rs index 8691385..c95533f 100644 --- a/ssz/src/uint256.rs +++ b/ssz/src/uint256.rs @@ -271,7 +271,8 @@ impl Uint256 { Self(self.into_raw().saturating_mul(rhs.into_raw())) } - const fn into_raw(self) -> RawUint256 { + #[must_use] + pub const fn into_raw(self) -> RawUint256 { self.0 } } diff --git a/types/src/config.rs b/types/src/config.rs index 19c0cc9..383e882 100644 --- a/types/src/config.rs +++ b/types/src/config.rs @@ -708,6 +708,11 @@ impl Config { epoch >= self.eip7594_fork_epoch } + #[must_use] + pub const fn is_eip7594_fork_epoch_set(&self) -> bool { + self.eip7594_fork_epoch != FAR_FUTURE_EPOCH + } + fn fork_slots(&self) -> impl Iterator)> + '_ { enum_iterator::all().map(|phase| (phase, self.fork_slot::

(phase))) }