From 32516383695a5b6c8eae575d476bd4dbb2cd14b7 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Fri, 15 Sep 2023 18:28:39 -0400 Subject: [PATCH 01/25] alloy-rlp encode decode --- Cargo.toml | 7 +- src/discv5.rs | 2 +- src/discv5/test.rs | 8 +- src/error.rs | 2 +- src/packet/mod.rs | 5 +- src/rpc.rs | 236 +++++++++++++++++++++++---------------------- src/service.rs | 2 +- 7 files changed, 133 insertions(+), 129 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1190ce538..d2b1ae075 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,15 +12,16 @@ categories = ["network-programming", "asynchronous"] exclude = [".gitignore", ".github/*"] [dependencies] -enr = { version = "0.9.0", features = ["k256", "ed25519"] } +enr = { git = "https://github.com/armaganyildirak/enr", rev = "8c445fb31b8d5190ea32429fc360750e898dfe3f", features = ["k256", "ed25519"] } tokio = { version = "1.15.0", features = ["net", "sync", "macros", "rt"] } libp2p-core = { version = "0.40.0", optional = true } libp2p-identity = { version = "0.2.1", features = ["ed25519", "secp256k1"], optional = true } zeroize = { version = "1.4.3", features = ["zeroize_derive"] } futures = "0.3.19" uint = { version = "0.9.1", default-features = false } -rlp = "0.5.1" -# This version must be kept up to date do it uses the same dependencies as ENR +alloy-rlp = { version = "0.3.2", default-features = true } +alloy-rlp-derive = { version = "0.3.2", default-features = true }# This version must be kept up to date do it uses the same dependencies as ENR +bytes = "1" hkdf = "0.12.3" hex = "0.4.3" fnv = "1.0.7" diff --git a/src/discv5.rs b/src/discv5.rs index 1fe10e92b..248b77e21 100644 --- a/src/discv5.rs +++ b/src/discv5.rs @@ -426,7 +426,7 @@ impl Discv5

{ } /// Allows application layer to insert an arbitrary field into the local ENR. - pub fn enr_insert( + pub fn enr_insert( &self, key: &str, value: &T, diff --git a/src/discv5/test.rs b/src/discv5/test.rs index 07d3a9c47..9951ee7be 100644 --- a/src/discv5/test.rs +++ b/src/discv5/test.rs @@ -14,7 +14,7 @@ fn init() { .try_init(); } -fn update_enr(discv5: &mut Discv5, key: &str, value: &T) -> bool { +fn update_enr(discv5: &mut Discv5, key: &str, value: &T) -> bool { discv5.enr_insert(key, value).is_ok() } @@ -683,8 +683,8 @@ async fn test_predicate_search() { // Update `num_nodes` with the required attnet value let num_nodes = total_nodes / 2; - let required_attnet_value = vec![1, 0, 0, 0]; - let unwanted_attnet_value = vec![0, 0, 0, 0]; + let required_attnet_value: Vec = vec![1, 0, 0, 0]; + let unwanted_attnet_value: Vec = vec![0, 0, 0, 0]; println!("Bootstrap node: {}", bootstrap_node.local_enr().node_id()); println!("Target node: {}", target_node.local_enr().node_id()); @@ -831,4 +831,4 @@ async fn test_bucket_limits() { // Number of entries should be equal to `bucket_limit`. assert_eq!(discv5.kbuckets.read().iter_ref().count(), bucket_limit); -} +} \ No newline at end of file diff --git a/src/error.rs b/src/error.rs index 35b2b4768..f1d34300d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,5 +1,5 @@ use crate::{handler::Challenge, node_info::NonContactable}; -use rlp::DecoderError; +use alloy_rlp::Error as DecoderError; use std::fmt; #[derive(Debug)] diff --git a/src/packet/mod.rs b/src/packet/mod.rs index f071263bd..15ad802ae 100644 --- a/src/packet/mod.rs +++ b/src/packet/mod.rs @@ -14,6 +14,7 @@ use aes::{ cipher::{generic_array::GenericArray, NewCipher, StreamCipher}, Aes128Ctr, }; +use alloy_rlp::Decodable; use enr::NodeId; use rand::Rng; use std::convert::TryInto; @@ -173,7 +174,7 @@ impl PacketKind { } => { let sig_size = id_nonce_sig.len(); let pubkey_size = ephem_pubkey.len(); - let node_record = enr_record.as_ref().map(rlp::encode); + let node_record = enr_record.as_ref().map(alloy_rlp::encode); let expected_len = 34 + sig_size + pubkey_size @@ -259,7 +260,7 @@ impl PacketKind { let enr_record = if remaining_data.len() > total_size { Some( - rlp::decode::(&remaining_data[total_size..]) + ::decode(&mut &remaining_data[total_size..]) .map_err(PacketError::InvalidEnr)?, ) } else { diff --git a/src/rpc.rs b/src/rpc.rs index 160a849d7..2f407f83e 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -1,5 +1,6 @@ +use alloy_rlp::{Decodable, Encodable, Error as DecoderError, Header}; +use bytes::{Buf, Bytes, BytesMut}; use enr::{CombinedKey, Enr}; -use rlp::{DecoderError, RlpStream}; use std::net::{IpAddr, Ipv6Addr}; use tracing::{debug, warn}; @@ -122,28 +123,47 @@ impl Request { let id = &self.id; match self.body { RequestBody::Ping { enr_seq } => { - let mut s = RlpStream::new(); - s.begin_list(2); - s.append(&id.as_bytes()); - s.append(&enr_seq); - buf.extend_from_slice(&s.out()); + let mut list = Vec::::new(); + list.append(&mut id.as_bytes().to_vec()); + let mut tmp_enr_seq = alloy_rlp::encode(enr_seq); + if tmp_enr_seq.len() != 1 { + tmp_enr_seq.remove(0); + } + list.append(&mut tmp_enr_seq); + let header = Header { + list: true, + payload_length: list.len(), + }; + header.encode(&mut buf); + buf.extend_from_slice(&list); buf } RequestBody::FindNode { distances } => { - let mut s = RlpStream::new(); - s.begin_list(2); - s.append(&id.as_bytes()); - s.append_list(&distances); - buf.extend_from_slice(&s.out()); + let mut list = Vec::::new(); + list.append(&mut alloy_rlp::encode(id.as_bytes())); + list.append(&mut alloy_rlp::encode(distances)); + let header = Header { + list: true, + payload_length: list.len(), + }; + header.encode(&mut buf); + buf.extend_from_slice(&list); buf } - RequestBody::Talk { protocol, request } => { - let mut s = RlpStream::new(); - s.begin_list(3); - s.append(&id.as_bytes()); - s.append(&protocol); - s.append(&request); - buf.extend_from_slice(&s.out()); + RequestBody::Talk { + mut protocol, + mut request, + } => { + let mut list = Vec::::new(); + list.append(&mut id.as_bytes().to_vec()); + list.append(&mut protocol); + list.append(&mut request); + let header = Header { + list: true, + payload_length: list.len(), + }; + header.encode(&mut buf); + buf.extend_from_slice(&list); buf } } @@ -178,41 +198,62 @@ impl Response { let id = &self.id; match self.body { ResponseBody::Pong { enr_seq, ip, port } => { - let mut s = RlpStream::new(); - s.begin_list(4); - s.append(&id.as_bytes()); - s.append(&enr_seq); + let mut list = Vec::::new(); + list.append(&mut alloy_rlp::encode(id.as_bytes())); + list.append(&mut alloy_rlp::encode(enr_seq)); match ip { - IpAddr::V4(addr) => s.append(&(&addr.octets() as &[u8])), - IpAddr::V6(addr) => s.append(&(&addr.octets() as &[u8])), + IpAddr::V4(addr) => list.append(&mut alloy_rlp::encode(addr.octets())), + IpAddr::V6(addr) => list.append(&mut alloy_rlp::encode(addr.octets())), + }; + list.append(&mut alloy_rlp::encode(port)); + let header = Header { + list: true, + payload_length: list.len(), }; - s.append(&port); - buf.extend_from_slice(&s.out()); + header.encode(&mut buf); + buf.extend_from_slice(&list); buf } ResponseBody::Nodes { total, nodes } => { - let mut s = RlpStream::new(); - s.begin_list(3); - s.append(&id.as_bytes()); - s.append(&total); - - if nodes.is_empty() { - s.begin_list(0); - } else { - s.begin_list(nodes.len()); - for node in nodes { - s.append(&node); + let mut list = Vec::::new(); + list.append(&mut alloy_rlp::encode(id.as_bytes())); + list.append(&mut alloy_rlp::encode(total)); + if !nodes.is_empty() { + let mut out = BytesMut::new(); + for node in nodes.clone() { + node.encode(&mut out); } + let tmp = Header { + list: true, + payload_length: out.to_vec().len(), + }; + let mut tmp_out = BytesMut::new(); + tmp.encode(&mut tmp_out); + tmp_out.extend_from_slice(&out); + list.append(&mut tmp_out.to_vec()); + } else { + let mut out = BytesMut::new(); + nodes.encode(&mut out); + list.append(&mut out.to_vec()); } - buf.extend_from_slice(&s.out()); + let header = Header { + list: true, + payload_length: list.len(), + }; + header.encode(&mut buf); + buf.extend_from_slice(&list); buf } ResponseBody::Talk { response } => { - let mut s = RlpStream::new(); - s.begin_list(2); - s.append(&id.as_bytes()); - s.append(&response); - buf.extend_from_slice(&s.out()); + let mut list = Vec::::new(); + list.append(&mut alloy_rlp::encode(id.as_bytes())); + list.append(&mut alloy_rlp::encode(response)); + let header = Header { + list: true, + payload_length: list.len(), + }; + header.encode(&mut buf); + buf.extend_from_slice(&list); buf } } @@ -300,57 +341,39 @@ impl Message { pub fn decode(data: &[u8]) -> Result { if data.len() < 3 { - return Err(DecoderError::RlpIsTooShort); + return Err(DecoderError::InputTooShort); } let msg_type = data[0]; - let data = &data[1..]; - let rlp = rlp::Rlp::new(data); + let payload = &mut &data[1..]; - let list_len = rlp.item_count().and_then(|size| { - if size < 2 { - Err(DecoderError::RlpIncorrectListLen) - } else { - Ok(size) - } - })?; + let header = Header::decode(payload)?; + if !header.list { + return Err(DecoderError::Custom("Invalid format of header")); + } - // verify there is no extra data - let payload_info = rlp.payload_info()?; - if data.len() != payload_info.header_len + payload_info.value_len { - return Err(DecoderError::RlpInconsistentLengthAndData); + if payload.is_empty() { + return Err(DecoderError::Custom("Payload is empty")); } - let id = RequestId::decode(rlp.val_at::>(0)?)?; + let id_bytes = Bytes::decode(payload)?; + let id = RequestId(id_bytes.to_vec()); let message = match msg_type { 1 => { // PingRequest - if list_len != 2 { - debug!( - "Ping Request has an invalid RLP list length. Expected 2, found {}", - list_len - ); - return Err(DecoderError::RlpIncorrectListLen); - } Message::Request(Request { id, body: RequestBody::Ping { - enr_seq: rlp.val_at::(1)?, + enr_seq: u64::decode(payload)?, }, }) } 2 => { // PingResponse - if list_len != 4 { - debug!( - "Ping Response has an invalid RLP list length. Expected 4, found {}", - list_len - ); - return Err(DecoderError::RlpIncorrectListLen); - } - let ip_bytes = rlp.val_at::>(2)?; + let enr_seq = u64::decode(payload)?; + let ip_bytes = Bytes::decode(payload)?; let ip = match ip_bytes.len() { 4 => { let mut ip = [0u8; 4]; @@ -375,29 +398,18 @@ impl Message { } _ => { debug!("Ping Response has incorrect byte length for IP"); - return Err(DecoderError::RlpIncorrectListLen); + return Err(DecoderError::Custom("Incorrect List Length")); } }; - let port = rlp.val_at::(3)?; + let port = u16::decode(payload)?; Message::Response(Response { id, - body: ResponseBody::Pong { - enr_seq: rlp.val_at::(1)?, - ip, - port, - }, + body: ResponseBody::Pong { enr_seq, ip, port }, }) } 3 => { // FindNodeRequest - if list_len != 2 { - debug!( - "FindNode Request has an invalid RLP list length. Expected 2, found {}", - list_len - ); - return Err(DecoderError::RlpIncorrectListLen); - } - let distances = rlp.list_at::(1)?; + let distances = Vec::::decode(payload)?; for distance in distances.iter() { if distance > &256u64 { @@ -416,42 +428,34 @@ impl Message { } 4 => { // NodesResponse - if list_len != 3 { - debug!( - "Nodes Response has an invalid RLP list length. Expected 3, found {}", - list_len - ); - return Err(DecoderError::RlpIncorrectListLen); - } - + let total = u64::decode(payload)?; let nodes = { - let enr_list_rlp = rlp.at(2)?; + Header::decode(payload)?; + let mut enr_list_rlp = Vec::>::new(); + while !payload.is_empty() { + let enr_rlp = Enr::::decode(payload)?; + payload.advance(enr_rlp.length() - 2); + enr_list_rlp.append(&mut vec![enr_rlp]); + } if enr_list_rlp.is_empty() { // no records vec![] } else { - enr_list_rlp.as_list::>()? + enr_list_rlp } }; Message::Response(Response { id, body: ResponseBody::Nodes { - total: rlp.val_at::(1)?, + total, nodes, }, }) } 5 => { // Talk Request - if list_len != 3 { - debug!( - "Talk Request has an invalid RLP list length. Expected 3, found {}", - list_len - ); - return Err(DecoderError::RlpIncorrectListLen); - } - let protocol = rlp.val_at::>(1)?; - let request = rlp.val_at::>(2)?; + let protocol = Vec::::decode(payload)?; + let request = Vec::::decode(payload)?; Message::Request(Request { id, body: RequestBody::Talk { protocol, request }, @@ -459,17 +463,15 @@ impl Message { } 6 => { // Talk Response - if list_len != 2 { - debug!( - "Talk Response has an invalid RLP list length. Expected 2, found {}", - list_len - ); - return Err(DecoderError::RlpIncorrectListLen); + let response = Bytes::decode(payload)?; + if !payload.is_empty() { + return Err(DecoderError::Custom("Payload is empty")); } - let response = rlp.val_at::>(1)?; Message::Response(Response { id, - body: ResponseBody::Talk { response }, + body: ResponseBody::Talk { + response: response.to_vec(), + }, }) } _ => { diff --git a/src/service.rs b/src/service.rs index c20e55d36..7b5e5df0e 100644 --- a/src/service.rs +++ b/src/service.rs @@ -1050,7 +1050,7 @@ impl Service { let mut rpc_index = 0; to_send_nodes.push(Vec::new()); for enr in nodes_to_send.into_iter() { - let entry_size = rlp::encode(&enr).len(); + let entry_size = alloy_rlp::encode(&enr).len(); // Responses assume that a session is established. Thus, on top of the encoded // ENR's the packet should be a regular message. A regular message has an IV (16 // bytes), and a header of 55 bytes. The find-nodes RPC requires 16 bytes for the ID and the From d1ee3ac077988286d06ee411e813f6c512078b76 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Fri, 15 Sep 2023 18:36:54 -0400 Subject: [PATCH 02/25] fmt --- src/discv5/test.rs | 2 +- src/rpc.rs | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/discv5/test.rs b/src/discv5/test.rs index 9951ee7be..6bde67de9 100644 --- a/src/discv5/test.rs +++ b/src/discv5/test.rs @@ -831,4 +831,4 @@ async fn test_bucket_limits() { // Number of entries should be equal to `bucket_limit`. assert_eq!(discv5.kbuckets.read().iter_ref().count(), bucket_limit); -} \ No newline at end of file +} diff --git a/src/rpc.rs b/src/rpc.rs index 2f407f83e..b6146f802 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -446,10 +446,7 @@ impl Message { }; Message::Response(Response { id, - body: ResponseBody::Nodes { - total, - nodes, - }, + body: ResponseBody::Nodes { total, nodes }, }) } 5 => { From 33b7dae14745e1c4d1c776f96689eaeb290374e3 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Fri, 15 Sep 2023 19:00:36 -0400 Subject: [PATCH 03/25] remove unused dependency --- Cargo.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d2b1ae075..bc0b79c61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"] exclude = [".gitignore", ".github/*"] [dependencies] -enr = { git = "https://github.com/armaganyildirak/enr", rev = "8c445fb31b8d5190ea32429fc360750e898dfe3f", features = ["k256", "ed25519"] } +enr = { git = "https://github.com/armaganyildirak/enr", rev = "7e9224cde5a36ed8dab73dda5bfa8f8ebe2ee4c2", features = ["k256", "ed25519"] } tokio = { version = "1.15.0", features = ["net", "sync", "macros", "rt"] } libp2p-core = { version = "0.40.0", optional = true } libp2p-identity = { version = "0.2.1", features = ["ed25519", "secp256k1"], optional = true } @@ -20,7 +20,6 @@ zeroize = { version = "1.4.3", features = ["zeroize_derive"] } futures = "0.3.19" uint = { version = "0.9.1", default-features = false } alloy-rlp = { version = "0.3.2", default-features = true } -alloy-rlp-derive = { version = "0.3.2", default-features = true }# This version must be kept up to date do it uses the same dependencies as ENR bytes = "1" hkdf = "0.12.3" hex = "0.4.3" From ed9a5ba43baddaa8125f0d12f6961e0f7db945cc Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Mon, 18 Sep 2023 16:46:33 -0400 Subject: [PATCH 04/25] working on tests --- src/discv5/test.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/discv5/test.rs b/src/discv5/test.rs index 6bde67de9..6c5f18e19 100644 --- a/src/discv5/test.rs +++ b/src/discv5/test.rs @@ -1,6 +1,7 @@ #![cfg(test)] use crate::{socket::ListenConfig, Discv5, *}; +use bytes::Bytes; use enr::{k256, CombinedKey, Enr, EnrBuilder, EnrKey, NodeId}; use rand_core::{RngCore, SeedableRng}; use std::{ @@ -683,8 +684,9 @@ async fn test_predicate_search() { // Update `num_nodes` with the required attnet value let num_nodes = total_nodes / 2; - let required_attnet_value: Vec = vec![1, 0, 0, 0]; - let unwanted_attnet_value: Vec = vec![0, 0, 0, 0]; + + let required_attnet_value = Bytes::copy_from_slice(&vec![1, 0, 0, 0]); + let unwanted_attnet_value = Bytes::copy_from_slice(&vec![0, 0, 0, 0]); println!("Bootstrap node: {}", bootstrap_node.local_enr().node_id()); println!("Target node: {}", target_node.local_enr().node_id()); @@ -711,7 +713,7 @@ async fn test_predicate_search() { // Predicate function for filtering enrs let predicate = move |enr: &Enr| { if let Some(v) = enr.get("attnets") { - v == required_attnet_value.as_slice() + v == required_attnet_value.to_vec().as_slice() } else { false } From edb5707db1dc360621ee428bc9ae854c9476787e Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Mon, 18 Sep 2023 16:48:21 -0400 Subject: [PATCH 05/25] fmt --- src/discv5/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/discv5/test.rs b/src/discv5/test.rs index 6c5f18e19..e0889a478 100644 --- a/src/discv5/test.rs +++ b/src/discv5/test.rs @@ -684,7 +684,7 @@ async fn test_predicate_search() { // Update `num_nodes` with the required attnet value let num_nodes = total_nodes / 2; - + let required_attnet_value = Bytes::copy_from_slice(&vec![1, 0, 0, 0]); let unwanted_attnet_value = Bytes::copy_from_slice(&vec![0, 0, 0, 0]); println!("Bootstrap node: {}", bootstrap_node.local_enr().node_id()); From 68eb2829b7b8f420445d69f4472018fe5d5563b3 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Mon, 18 Sep 2023 16:57:25 -0400 Subject: [PATCH 06/25] clippy --- src/discv5/test.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/discv5/test.rs b/src/discv5/test.rs index e0889a478..2ec346071 100644 --- a/src/discv5/test.rs +++ b/src/discv5/test.rs @@ -685,8 +685,8 @@ async fn test_predicate_search() { // Update `num_nodes` with the required attnet value let num_nodes = total_nodes / 2; - let required_attnet_value = Bytes::copy_from_slice(&vec![1, 0, 0, 0]); - let unwanted_attnet_value = Bytes::copy_from_slice(&vec![0, 0, 0, 0]); + let required_attnet_value = Bytes::copy_from_slice(&[1, 0, 0, 0]); + let unwanted_attnet_value = Bytes::copy_from_slice(&[0, 0, 0, 0]); println!("Bootstrap node: {}", bootstrap_node.local_enr().node_id()); println!("Target node: {}", target_node.local_enr().node_id()); From e14790a4aa17454730e627f5d575b166d0d226a6 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Thu, 21 Sep 2023 18:26:23 -0400 Subject: [PATCH 07/25] improve encode decode --- src/rpc.rs | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/rpc.rs b/src/rpc.rs index b6146f802..004bd19c9 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -124,12 +124,8 @@ impl Request { match self.body { RequestBody::Ping { enr_seq } => { let mut list = Vec::::new(); - list.append(&mut id.as_bytes().to_vec()); - let mut tmp_enr_seq = alloy_rlp::encode(enr_seq); - if tmp_enr_seq.len() != 1 { - tmp_enr_seq.remove(0); - } - list.append(&mut tmp_enr_seq); + list.append(&mut alloy_rlp::encode(id.as_bytes())); + list.append(&mut alloy_rlp::encode(enr_seq)); let header = Header { list: true, payload_length: list.len(), @@ -150,14 +146,11 @@ impl Request { buf.extend_from_slice(&list); buf } - RequestBody::Talk { - mut protocol, - mut request, - } => { + RequestBody::Talk { protocol, request } => { let mut list = Vec::::new(); - list.append(&mut id.as_bytes().to_vec()); - list.append(&mut protocol); - list.append(&mut request); + list.append(&mut alloy_rlp::encode(id.as_bytes())); + list.append(&mut alloy_rlp::encode(Bytes::copy_from_slice(&protocol))); + list.append(&mut alloy_rlp::encode(Bytes::copy_from_slice(&request))); let header = Header { list: true, payload_length: list.len(), @@ -247,7 +240,7 @@ impl Response { ResponseBody::Talk { response } => { let mut list = Vec::::new(); list.append(&mut alloy_rlp::encode(id.as_bytes())); - list.append(&mut alloy_rlp::encode(response)); + list.append(&mut alloy_rlp::encode(Bytes::copy_from_slice(&response))); let header = Header { list: true, payload_length: list.len(), @@ -451,11 +444,14 @@ impl Message { } 5 => { // Talk Request - let protocol = Vec::::decode(payload)?; - let request = Vec::::decode(payload)?; + let protocol = Bytes::decode(payload)?; + let request = Bytes::decode(payload)?; Message::Request(Request { id, - body: RequestBody::Talk { protocol, request }, + body: RequestBody::Talk { + protocol: protocol.to_vec(), + request: request.to_vec(), + }, }) } 6 => { From a331c5bb0ef96b036adea77a45aa089d954bb118 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Mon, 25 Sep 2023 17:41:51 -0400 Subject: [PATCH 08/25] improve encode decode --- src/rpc.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/rpc.rs b/src/rpc.rs index 004bd19c9..3216435d1 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -192,13 +192,13 @@ impl Response { match self.body { ResponseBody::Pong { enr_seq, ip, port } => { let mut list = Vec::::new(); - list.append(&mut alloy_rlp::encode(id.as_bytes())); - list.append(&mut alloy_rlp::encode(enr_seq)); + id.as_bytes().encode(&mut list); + enr_seq.encode(&mut list); match ip { - IpAddr::V4(addr) => list.append(&mut alloy_rlp::encode(addr.octets())), - IpAddr::V6(addr) => list.append(&mut alloy_rlp::encode(addr.octets())), + IpAddr::V4(addr) => addr.encode(&mut list), + IpAddr::V6(addr) => addr.encode(&mut list), }; - list.append(&mut alloy_rlp::encode(port)); + port.encode(&mut list); let header = Header { list: true, payload_length: list.len(), @@ -209,21 +209,21 @@ impl Response { } ResponseBody::Nodes { total, nodes } => { let mut list = Vec::::new(); - list.append(&mut alloy_rlp::encode(id.as_bytes())); - list.append(&mut alloy_rlp::encode(total)); + id.as_bytes().encode(&mut list); + total.encode(&mut list); if !nodes.is_empty() { let mut out = BytesMut::new(); for node in nodes.clone() { node.encode(&mut out); } - let tmp = Header { + let tmp_header = Header { list: true, payload_length: out.to_vec().len(), }; let mut tmp_out = BytesMut::new(); - tmp.encode(&mut tmp_out); + tmp_header.encode(&mut tmp_out); tmp_out.extend_from_slice(&out); - list.append(&mut tmp_out.to_vec()); + list.extend_from_slice(&tmp_out); } else { let mut out = BytesMut::new(); nodes.encode(&mut out); @@ -239,8 +239,8 @@ impl Response { } ResponseBody::Talk { response } => { let mut list = Vec::::new(); - list.append(&mut alloy_rlp::encode(id.as_bytes())); - list.append(&mut alloy_rlp::encode(Bytes::copy_from_slice(&response))); + id.as_bytes().encode(&mut list); + response.encode(&mut list); let header = Header { list: true, payload_length: list.len(), @@ -427,7 +427,7 @@ impl Message { let mut enr_list_rlp = Vec::>::new(); while !payload.is_empty() { let enr_rlp = Enr::::decode(payload)?; - payload.advance(enr_rlp.length() - 2); + payload.advance(enr_rlp.size() - 2); enr_list_rlp.append(&mut vec![enr_rlp]); } if enr_list_rlp.is_empty() { From cf247bd6543b144afe8700ca53c504680088b555 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Mon, 25 Sep 2023 18:00:49 -0400 Subject: [PATCH 09/25] change enr version to my latest commit --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index bc0b79c61..556d59408 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"] exclude = [".gitignore", ".github/*"] [dependencies] -enr = { git = "https://github.com/armaganyildirak/enr", rev = "7e9224cde5a36ed8dab73dda5bfa8f8ebe2ee4c2", features = ["k256", "ed25519"] } +enr = { git = "https://github.com/armaganyildirak/enr", rev = "779b85e9bff9f41bc0d0816d564fd5e7e94ee6e3", features = ["k256", "ed25519"] } tokio = { version = "1.15.0", features = ["net", "sync", "macros", "rt"] } libp2p-core = { version = "0.40.0", optional = true } libp2p-identity = { version = "0.2.1", features = ["ed25519", "secp256k1"], optional = true } From 85ea39b5400da35fa93e44d9e17e8ba4e13cb8c5 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Wed, 27 Sep 2023 17:33:41 -0400 Subject: [PATCH 10/25] update rpc Request encode --- src/rpc.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/rpc.rs b/src/rpc.rs index 3216435d1..0e3ee6d8e 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -124,8 +124,8 @@ impl Request { match self.body { RequestBody::Ping { enr_seq } => { let mut list = Vec::::new(); - list.append(&mut alloy_rlp::encode(id.as_bytes())); - list.append(&mut alloy_rlp::encode(enr_seq)); + id.as_bytes().encode(&mut list); + enr_seq.encode(&mut list); let header = Header { list: true, payload_length: list.len(), @@ -136,8 +136,8 @@ impl Request { } RequestBody::FindNode { distances } => { let mut list = Vec::::new(); - list.append(&mut alloy_rlp::encode(id.as_bytes())); - list.append(&mut alloy_rlp::encode(distances)); + id.as_bytes().encode(&mut list); + distances.encode(&mut list); let header = Header { list: true, payload_length: list.len(), @@ -148,9 +148,9 @@ impl Request { } RequestBody::Talk { protocol, request } => { let mut list = Vec::::new(); - list.append(&mut alloy_rlp::encode(id.as_bytes())); - list.append(&mut alloy_rlp::encode(Bytes::copy_from_slice(&protocol))); - list.append(&mut alloy_rlp::encode(Bytes::copy_from_slice(&request))); + id.as_bytes().encode(&mut list); + protocol.encode(&mut list); + request.encode(&mut list); let header = Header { list: true, payload_length: list.len(), From c92175ef945d98fad380bbf763c0d06a259760b6 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Thu, 28 Sep 2023 12:24:58 -0400 Subject: [PATCH 11/25] reject the extra bytes --- src/rpc.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/rpc.rs b/src/rpc.rs index 0e3ee6d8e..2430b09a7 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -346,6 +346,10 @@ impl Message { return Err(DecoderError::Custom("Invalid format of header")); } + if header.payload_length != payload.len() { + return Err(DecoderError::Custom("Reject the extra data")); + } + if payload.is_empty() { return Err(DecoderError::Custom("Payload is empty")); } @@ -457,9 +461,6 @@ impl Message { 6 => { // Talk Response let response = Bytes::decode(payload)?; - if !payload.is_empty() { - return Err(DecoderError::Custom("Payload is empty")); - } Message::Response(Response { id, body: ResponseBody::Talk { @@ -763,5 +764,14 @@ mod tests { let data3 = [6, 194, 0, 75, 252]; Message::decode(&data3).expect_err("should reject extra data"); + + let data4 = [6, 193, 0, 63]; + Message::decode(&data4).expect_err("should reject extra data"); + + let data5 = [6, 193, 128, 75]; + Message::decode(&data5).expect_err("should reject extra data"); + + let data6 = [6, 193, 128, 128]; + Message::decode(&data6).expect_err("should reject extra data"); } } From c402e1c39e4074343ac75324a5dd69231ec6b514 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Fri, 29 Sep 2023 19:35:26 -0400 Subject: [PATCH 12/25] fix couple problems after run fuzzers --- src/rpc.rs | 49 +++++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/src/rpc.rs b/src/rpc.rs index 2430b09a7..da23d1d8a 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -227,7 +227,7 @@ impl Response { } else { let mut out = BytesMut::new(); nodes.encode(&mut out); - list.append(&mut out.to_vec()); + list.extend_from_slice(&out); } let header = Header { list: true, @@ -240,7 +240,7 @@ impl Response { ResponseBody::Talk { response } => { let mut list = Vec::::new(); id.as_bytes().encode(&mut list); - response.encode(&mut list); + response.as_slice().encode(&mut list); let header = Header { list: true, payload_length: list.len(), @@ -350,21 +350,19 @@ impl Message { return Err(DecoderError::Custom("Reject the extra data")); } - if payload.is_empty() { - return Err(DecoderError::Custom("Payload is empty")); - } - let id_bytes = Bytes::decode(payload)?; let id = RequestId(id_bytes.to_vec()); let message = match msg_type { 1 => { // PingRequest + let enr_seq = u64::decode(payload)?; + if !payload.is_empty() { + return Err(DecoderError::Custom("Payload should be empty")); + } Message::Request(Request { id, - body: RequestBody::Ping { - enr_seq: u64::decode(payload)?, - }, + body: RequestBody::Ping { enr_seq }, }) } 2 => { @@ -399,6 +397,9 @@ impl Message { } }; let port = u16::decode(payload)?; + if !payload.is_empty() { + return Err(DecoderError::Custom("Payload should be empty")); + } Message::Response(Response { id, body: ResponseBody::Pong { enr_seq, ip, port }, @@ -417,7 +418,9 @@ impl Message { return Err(DecoderError::Custom("FINDNODE request distance invalid")); } } - + if !payload.is_empty() { + return Err(DecoderError::Custom("Payload should be empty")); + } Message::Request(Request { id, body: RequestBody::FindNode { distances }, @@ -427,7 +430,10 @@ impl Message { // NodesResponse let total = u64::decode(payload)?; let nodes = { - Header::decode(payload)?; + let header = Header::decode(payload)?; + if !header.list { + return Err(DecoderError::Custom("Invalid format of header")); + } let mut enr_list_rlp = Vec::>::new(); while !payload.is_empty() { let enr_rlp = Enr::::decode(payload)?; @@ -441,6 +447,9 @@ impl Message { enr_list_rlp } }; + if !payload.is_empty() { + return Err(DecoderError::Custom("Payload should be empty")); + } Message::Response(Response { id, body: ResponseBody::Nodes { total, nodes }, @@ -448,19 +457,22 @@ impl Message { } 5 => { // Talk Request - let protocol = Bytes::decode(payload)?; - let request = Bytes::decode(payload)?; + let protocol = Vec::::decode(payload)?; + let request = Vec::::decode(payload)?; + if !payload.is_empty() { + return Err(DecoderError::Custom("Payload should be empty")); + } Message::Request(Request { id, - body: RequestBody::Talk { - protocol: protocol.to_vec(), - request: request.to_vec(), - }, + body: RequestBody::Talk { protocol, request }, }) } 6 => { // Talk Response let response = Bytes::decode(payload)?; + if !payload.is_empty() { + return Err(DecoderError::Custom("Payload should be empty")); + } Message::Response(Response { id, body: ResponseBody::Talk { @@ -481,7 +493,7 @@ impl Message { mod tests { use super::*; use enr::EnrBuilder; - use std::net::Ipv4Addr; + use std::net::{Ipv4Addr, Ipv6Addr}; #[test] fn ref_test_encode_request_ping() { @@ -758,6 +770,7 @@ mod tests { body: ResponseBody::Talk { response: vec![75] } }) ); + assert_eq!(data.to_vec(), msg.encode()); let data2 = [6, 193, 0, 75, 252]; Message::decode(&data2).expect_err("should reject extra data"); From d1fe67d75ddea43a143558506744948a8e4e6ea2 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Mon, 9 Oct 2023 18:18:39 -0400 Subject: [PATCH 13/25] change alloy_rlp and enr version --- Cargo.toml | 4 ++-- src/rpc.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 556d59408..716bc5670 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,14 +12,14 @@ categories = ["network-programming", "asynchronous"] exclude = [".gitignore", ".github/*"] [dependencies] -enr = { git = "https://github.com/armaganyildirak/enr", rev = "779b85e9bff9f41bc0d0816d564fd5e7e94ee6e3", features = ["k256", "ed25519"] } +enr = { git = "https://github.com/armaganyildirak/enr", rev = "b2b35ba8cafe45ca90524862db71003c3d62815f", features = ["k256", "ed25519"] } tokio = { version = "1.15.0", features = ["net", "sync", "macros", "rt"] } libp2p-core = { version = "0.40.0", optional = true } libp2p-identity = { version = "0.2.1", features = ["ed25519", "secp256k1"], optional = true } zeroize = { version = "1.4.3", features = ["zeroize_derive"] } futures = "0.3.19" uint = { version = "0.9.1", default-features = false } -alloy-rlp = { version = "0.3.2", default-features = true } +alloy-rlp = { version = "0.3.3", default-features = true } bytes = "1" hkdf = "0.12.3" hex = "0.4.3" diff --git a/src/rpc.rs b/src/rpc.rs index da23d1d8a..76307bd3f 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -218,7 +218,7 @@ impl Response { } let tmp_header = Header { list: true, - payload_length: out.to_vec().len(), + payload_length: out.len(), }; let mut tmp_out = BytesMut::new(); tmp_header.encode(&mut tmp_out); From ff0c21fe483342e9b0217bf57f29fe702667a779 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Thu, 12 Oct 2023 10:44:01 -0400 Subject: [PATCH 14/25] clippy --- src/handler/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/handler/mod.rs b/src/handler/mod.rs index 6df6ef835..c3c8f28f7 100644 --- a/src/handler/mod.rs +++ b/src/handler/mod.rs @@ -471,7 +471,7 @@ impl Handler { trace!("Request queued for node: {}", node_address); self.pending_requests .entry(node_address) - .or_insert_with(Vec::new) + .or_default() .push(PendingRequest { contact, request_id, From cc5ef2cfe70539daa5fa0411ad5a46a62edbd764 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Thu, 12 Oct 2023 19:31:23 -0400 Subject: [PATCH 15/25] fix max enr size issue --- src/rpc.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/rpc.rs b/src/rpc.rs index 76307bd3f..745e9dc2f 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -436,8 +436,14 @@ impl Message { } let mut enr_list_rlp = Vec::>::new(); while !payload.is_empty() { - let enr_rlp = Enr::::decode(payload)?; - payload.advance(enr_rlp.size() - 2); + let node_header = Header::decode(&mut &payload[..])?; + if !node_header.list { + return Err(DecoderError::Custom("Invalid format of header")); + } + let enr_rlp = Enr::::decode( + &mut &payload[..node_header.payload_length + 2], + )?; + payload.advance(enr_rlp.size()); enr_list_rlp.append(&mut vec![enr_rlp]); } if enr_list_rlp.is_empty() { From f0fc83293c2730ce7a80e529a47636aa3356fc91 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Fri, 20 Oct 2023 18:54:49 -0400 Subject: [PATCH 16/25] update enr create with latest commits --- Cargo.toml | 2 +- examples/custom_executor.rs | 4 ++-- examples/find_nodes.rs | 3 ++- examples/request_enr.rs | 4 ++-- examples/simple_server.rs | 4 ++-- src/discv5/test.rs | 36 ++++++++++-------------------------- src/handler/crypto/mod.rs | 6 +++--- src/handler/tests.rs | 26 +++++++++++--------------- src/ipmode.rs | 2 +- src/lib.rs | 4 ++-- src/rpc.rs | 7 +++---- src/service/test.rs | 18 +++++------------- 12 files changed, 44 insertions(+), 72 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 716bc5670..4531c9a66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"] exclude = [".gitignore", ".github/*"] [dependencies] -enr = { git = "https://github.com/armaganyildirak/enr", rev = "b2b35ba8cafe45ca90524862db71003c3d62815f", features = ["k256", "ed25519"] } +enr = { git = "https://github.com/armaganyildirak/enr", rev = "9151474e67c97c355014c88c977c3f3c9c29e792", features = ["k256", "ed25519"] } tokio = { version = "1.15.0", features = ["net", "sync", "macros", "rt"] } libp2p-core = { version = "0.40.0", optional = true } libp2p-identity = { version = "0.2.1", features = ["ed25519", "secp256k1"], optional = true } diff --git a/examples/custom_executor.rs b/examples/custom_executor.rs index 1d97d3561..444013aaf 100644 --- a/examples/custom_executor.rs +++ b/examples/custom_executor.rs @@ -9,7 +9,7 @@ //! $ cargo run --example custom_executor //! ``` -use discv5::{enr, enr::CombinedKey, ConfigBuilder, Discv5, Event, ListenConfig}; +use discv5::{enr, enr::CombinedKey, enr::Enr, ConfigBuilder, Discv5, Event, ListenConfig}; use std::net::Ipv4Addr; fn main() { @@ -29,7 +29,7 @@ fn main() { let enr_key = CombinedKey::generate_secp256k1(); // construct a local ENR - let enr = enr::EnrBuilder::new("v4").build(&enr_key).unwrap(); + let enr = Enr::builder().build(&enr_key).unwrap(); // build the tokio executor let runtime = tokio::runtime::Builder::new_multi_thread() diff --git a/examples/find_nodes.rs b/examples/find_nodes.rs index 383d141e8..d79f9f400 100644 --- a/examples/find_nodes.rs +++ b/examples/find_nodes.rs @@ -18,6 +18,7 @@ use clap::Parser; use discv5::{ enr, + enr::Enr, enr::{k256, CombinedKey}, ConfigBuilder, Discv5, Event, ListenConfig, }; @@ -90,7 +91,7 @@ async fn main() { }; let enr = { - let mut builder = enr::EnrBuilder::new("v4"); + let mut builder = Enr::builder(); if let Some(ip4) = args.enr_ip4 { // if the given address is the UNSPECIFIED address we want to advertise localhost if ip4.is_unspecified() { diff --git a/examples/request_enr.rs b/examples/request_enr.rs index e6986f1b3..0798c0f60 100644 --- a/examples/request_enr.rs +++ b/examples/request_enr.rs @@ -17,7 +17,7 @@ use discv5::ConfigBuilder; #[cfg(feature = "libp2p")] use discv5::ListenConfig; #[cfg(feature = "libp2p")] -use discv5::{enr, enr::CombinedKey, Discv5}; +use discv5::{enr::CombinedKey, enr::Enr, Discv5}; #[cfg(feature = "libp2p")] use std::net::Ipv4Addr; @@ -43,7 +43,7 @@ async fn main() { // generate a new enr key let enr_key = CombinedKey::generate_secp256k1(); // construct a local ENR - let enr = enr::EnrBuilder::new("v4").build(&enr_key).unwrap(); + let enr = Enr::builder().build(&enr_key).unwrap(); // default discv5 configuration let config = ConfigBuilder::new(listen_config).build(); diff --git a/examples/simple_server.rs b/examples/simple_server.rs index 41a925e57..18f06c673 100644 --- a/examples/simple_server.rs +++ b/examples/simple_server.rs @@ -10,7 +10,7 @@ //! $ cargo run --example simple_server -- //! ``` -use discv5::{enr, enr::CombinedKey, ConfigBuilder, Discv5, Event, ListenConfig}; +use discv5::{enr, enr::CombinedKey, enr::Enr, ConfigBuilder, Discv5, Event, ListenConfig}; use std::net::Ipv4Addr; #[tokio::main] @@ -46,7 +46,7 @@ async fn main() { // construct a local ENR let enr = { - let mut builder = enr::EnrBuilder::new("v4"); + let mut builder = Enr::builder(); // if an IP was specified, use it if let Some(external_address) = address { builder.ip4(external_address); diff --git a/src/discv5/test.rs b/src/discv5/test.rs index 2ec346071..a26bb6fbc 100644 --- a/src/discv5/test.rs +++ b/src/discv5/test.rs @@ -2,7 +2,7 @@ use crate::{socket::ListenConfig, Discv5, *}; use bytes::Bytes; -use enr::{k256, CombinedKey, Enr, EnrBuilder, EnrKey, NodeId}; +use enr::{k256, CombinedKey, Enr, EnrKey, NodeId}; use rand_core::{RngCore, SeedableRng}; use std::{ collections::HashMap, @@ -29,11 +29,7 @@ async fn build_nodes(n: usize, base_port: u16) -> Vec { let listen_config = ListenConfig::Ipv4 { ip, port }; let config = ConfigBuilder::new(listen_config).build(); - let enr = EnrBuilder::new("v4") - .ip4(ip) - .udp4(port) - .build(&enr_key) - .unwrap(); + let enr = Enr::builder().ip4(ip).udp4(port).build(&enr_key).unwrap(); // transport for building a swarm let mut discv5 = Discv5::new(enr, enr_key, config).unwrap(); discv5.start().await.unwrap(); @@ -53,11 +49,7 @@ async fn build_nodes_from_keypairs(keys: Vec, base_port: u16) -> Ve let listen_config = ListenConfig::Ipv4 { ip, port }; let config = ConfigBuilder::new(listen_config).build(); - let enr = EnrBuilder::new("v4") - .ip4(ip) - .udp4(port) - .build(&enr_key) - .unwrap(); + let enr = Enr::builder().ip4(ip).udp4(port).build(&enr_key).unwrap(); let mut discv5 = Discv5::new(enr, enr_key, config).unwrap(); discv5.start().await.unwrap(); @@ -78,7 +70,7 @@ async fn build_nodes_from_keypairs_ipv6(keys: Vec, base_port: u16) }; let config = ConfigBuilder::new(listen_config).build(); - let enr = EnrBuilder::new("v4") + let enr = Enr::builder() .ip6(Ipv6Addr::LOCALHOST) .udp6(port) .build(&enr_key) @@ -109,7 +101,7 @@ async fn build_nodes_from_keypairs_dual_stack( }; let config = ConfigBuilder::new(listen_config).build(); - let enr = EnrBuilder::new("v4") + let enr = Enr::builder() .ip4(Ipv4Addr::LOCALHOST) .udp4(ipv4_port) .ip6(Ipv6Addr::LOCALHOST) @@ -746,11 +738,7 @@ async fn test_table_limits() { let mut keypairs = generate_deterministic_keypair(12, 9487); let ip: Ipv4Addr = "127.0.0.1".parse().unwrap(); let enr_key: CombinedKey = keypairs.remove(0); - let enr = EnrBuilder::new("v4") - .ip4(ip) - .udp4(9050) - .build(&enr_key) - .unwrap(); + let enr = Enr::builder().ip4(ip).udp4(9050).build(&enr_key).unwrap(); let listen_config = ListenConfig::Ipv4 { ip: enr.ip4().unwrap(), port: enr.udp4().unwrap(), @@ -765,7 +753,7 @@ async fn test_table_limits() { .map(|i| { let ip: Ipv4Addr = Ipv4Addr::new(192, 168, 1, i as u8); let enr_key: CombinedKey = keypairs.remove(0); - EnrBuilder::new("v4") + Enr::builder() .ip4(ip) .udp4(9050 + i as u16) .build(&enr_key) @@ -784,11 +772,7 @@ async fn test_table_limits() { async fn test_bucket_limits() { let enr_key = CombinedKey::generate_secp256k1(); let ip: Ipv4Addr = "127.0.0.1".parse().unwrap(); - let enr = EnrBuilder::new("v4") - .ip4(ip) - .udp4(9500) - .build(&enr_key) - .unwrap(); + let enr = Enr::builder().ip4(ip).udp4(9500).build(&enr_key).unwrap(); let bucket_limit: usize = 2; // Generate `bucket_limit + 1` keypairs that go in `enr` node's 256th bucket. let keys = { @@ -796,7 +780,7 @@ async fn test_bucket_limits() { for _ in 0..bucket_limit + 1 { loop { let key = CombinedKey::generate_secp256k1(); - let enr_new = EnrBuilder::new("v4").build(&key).unwrap(); + let enr_new = Enr::builder().build(&key).unwrap(); let node_key: Key = enr.node_id().into(); let distance = node_key.log2_distance(&enr_new.node_id().into()).unwrap(); if distance == 256 { @@ -812,7 +796,7 @@ async fn test_bucket_limits() { .map(|i| { let kp = &keys[i - 1]; let ip: Ipv4Addr = Ipv4Addr::new(192, 168, 1, i as u8); - EnrBuilder::new("v4") + Enr::builder() .ip4(ip) .udp4(9500 + i as u16) .build(kp) diff --git a/src/handler/crypto/mod.rs b/src/handler/crypto/mod.rs index c96d7afdc..6b609d3a8 100644 --- a/src/handler/crypto/mod.rs +++ b/src/handler/crypto/mod.rs @@ -223,7 +223,7 @@ mod tests { use crate::packet::DefaultProtocolId; use super::*; - use enr::{CombinedKey, EnrBuilder, EnrKey}; + use enr::{CombinedKey, Enr, EnrKey}; use std::convert::TryInto; fn hex_decode(x: &'static str) -> Vec { @@ -341,12 +341,12 @@ mod tests { let node1_key = CombinedKey::generate_secp256k1(); let node2_key = CombinedKey::generate_secp256k1(); - let node1_enr = EnrBuilder::new("v4") + let node1_enr = Enr::builder() .ip("127.0.0.1".parse().unwrap()) .udp4(9000) .build(&node1_key) .unwrap(); - let node2_enr = EnrBuilder::new("v4") + let node2_enr = Enr::builder() .ip("127.0.0.1".parse().unwrap()) .udp4(9000) .build(&node2_key) diff --git a/src/handler/tests.rs b/src/handler/tests.rs index f46803659..abe86e0e0 100644 --- a/src/handler/tests.rs +++ b/src/handler/tests.rs @@ -14,7 +14,7 @@ use crate::{ RequestError::SelfRequest, }; use active_requests::ActiveRequests; -use enr::EnrBuilder; +use enr::Enr; use std::time::Duration; use tokio::time::sleep; @@ -25,7 +25,7 @@ fn init() { } async fn build_handler( - enr: Enr, + enr: Enr, key: CombinedKey, config: Config, ) -> ( @@ -105,12 +105,12 @@ async fn simple_session_message() { let key1 = CombinedKey::generate_secp256k1(); let key2 = CombinedKey::generate_secp256k1(); - let sender_enr = EnrBuilder::new("v4") + let sender_enr = Enr::builder() .ip4(ip) .udp4(sender_port) .build(&key1) .unwrap(); - let receiver_enr = EnrBuilder::new("v4") + let receiver_enr = Enr::builder() .ip4(ip) .udp4(receiver_port) .build(&key2) @@ -192,13 +192,13 @@ async fn multiple_messages() { let key1 = CombinedKey::generate_secp256k1(); let key2 = CombinedKey::generate_secp256k1(); - let sender_enr = EnrBuilder::new("v4") + let sender_enr = Enr::builder() .ip4(ip) .udp4(sender_port) .build(&key1) .unwrap(); - let receiver_enr = EnrBuilder::new("v4") + let receiver_enr = Enr::builder() .ip4(ip) .udp4(receiver_port) .build(&key2) @@ -342,11 +342,7 @@ async fn test_active_requests_insert() { let key = CombinedKey::generate_secp256k1(); - let enr = EnrBuilder::new("v4") - .ip4(ip) - .udp4(port) - .build(&key) - .unwrap(); + let enr = Enr::builder().ip4(ip).udp4(port).build(&key).unwrap(); let node_id = enr.node_id(); let contact: NodeContact = enr.into(); @@ -371,7 +367,7 @@ async fn test_self_request_ipv4() { init(); let key = CombinedKey::generate_secp256k1(); - let enr = EnrBuilder::new("v4") + let enr = Enr::builder() .ip4(Ipv4Addr::LOCALHOST) .udp4(5004) .build(&key) @@ -411,7 +407,7 @@ async fn test_self_request_ipv6() { init(); let key = CombinedKey::generate_secp256k1(); - let enr = EnrBuilder::new("v4") + let enr = Enr::builder() .ip6(Ipv6Addr::LOCALHOST) .udp6(5005) .build(&key) @@ -448,7 +444,7 @@ async fn test_self_request_ipv6() { async fn remove_one_time_session() { let config = ConfigBuilder::new(ListenConfig::default()).build(); let key = CombinedKey::generate_secp256k1(); - let enr = EnrBuilder::new("v4") + let enr = Enr::builder() .ip4(Ipv4Addr::LOCALHOST) .udp4(9000) .build(&key) @@ -457,7 +453,7 @@ async fn remove_one_time_session() { let enr = { let key = CombinedKey::generate_secp256k1(); - EnrBuilder::new("v4") + Enr::builder() .ip4(Ipv4Addr::LOCALHOST) .udp4(9000) .build(&key) diff --git a/src/ipmode.rs b/src/ipmode.rs index de66fd195..a92ffba6e 100644 --- a/src/ipmode.rs +++ b/src/ipmode.rs @@ -125,7 +125,7 @@ mod tests { fn test(&self) { let test_enr = { - let builder = &mut enr::EnrBuilder::new("v4"); + let builder = &mut enr::Enr::builder(); if let Some(ip4) = self.enr_ip4 { builder.ip4(ip4).udp4(IP4_TEST_PORT); } diff --git a/src/lib.rs b/src/lib.rs index e48990dcf..391d66ad1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,13 +53,13 @@ //! A simple example of creating this service is as follows: //! //! ```rust -//! use discv5::{enr, enr::{CombinedKey, NodeId}, TokioExecutor, Discv5, ConfigBuilder}; +//! use discv5::{enr, enr::{CombinedKey, Enr, NodeId}, TokioExecutor, Discv5, ConfigBuilder}; //! use discv5::socket::ListenConfig; //! use std::net::{Ipv4Addr, SocketAddr}; //! //! // construct a local ENR //! let enr_key = CombinedKey::generate_secp256k1(); -//! let enr = enr::EnrBuilder::new("v4").build(&enr_key).unwrap(); +//! let enr = Enr::builder().build(&enr_key).unwrap(); //! //! // build the tokio executor //! let mut runtime = tokio::runtime::Builder::new_multi_thread() diff --git a/src/rpc.rs b/src/rpc.rs index 745e9dc2f..bc190b557 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -498,7 +498,6 @@ impl Message { #[cfg(test)] mod tests { use super::*; - use enr::EnrBuilder; use std::net::{Ipv4Addr, Ipv6Addr}; #[test] @@ -734,17 +733,17 @@ mod tests { #[test] fn encode_decode_nodes_response() { let key = CombinedKey::generate_secp256k1(); - let enr1 = EnrBuilder::new("v4") + let enr1 = Enr::builder() .ip4("127.0.0.1".parse().unwrap()) .udp4(500) .build(&key) .unwrap(); - let enr2 = EnrBuilder::new("v4") + let enr2 = Enr::builder() .ip4("10.0.0.1".parse().unwrap()) .tcp4(8080) .build(&key) .unwrap(); - let enr3 = EnrBuilder::new("v4") + let enr3 = Enr::builder() .ip("10.4.5.6".parse().unwrap()) .build(&key) .unwrap(); diff --git a/src/service/test.rs b/src/service/test.rs index 24186a28c..5492ee6df 100644 --- a/src/service/test.rs +++ b/src/service/test.rs @@ -14,7 +14,7 @@ use crate::{ socket::ListenConfig, ConfigBuilder, Enr, }; -use enr::{CombinedKey, EnrBuilder}; +use enr::CombinedKey; use parking_lot::RwLock; use std::{collections::HashMap, sync::Arc, time::Duration}; use tokio::sync::{mpsc, oneshot}; @@ -103,14 +103,10 @@ async fn test_updating_connection_on_ping() { init(); let enr_key1 = CombinedKey::generate_secp256k1(); let ip = "127.0.0.1".parse().unwrap(); - let enr = EnrBuilder::new("v4") - .ip4(ip) - .udp4(10001) - .build(&enr_key1) - .unwrap(); + let enr = Enr::builder().ip4(ip).udp4(10001).build(&enr_key1).unwrap(); let ip2 = "127.0.0.1".parse().unwrap(); let enr_key2 = CombinedKey::generate_secp256k1(); - let enr2 = EnrBuilder::new("v4") + let enr2 = Enr::builder() .ip4(ip2) .udp4(10002) .build(&enr_key2) @@ -171,15 +167,11 @@ async fn test_connection_direction_on_inject_session_established() { let enr_key1 = CombinedKey::generate_secp256k1(); let ip = std::net::Ipv4Addr::LOCALHOST; - let enr = EnrBuilder::new("v4") - .ip4(ip) - .udp4(10001) - .build(&enr_key1) - .unwrap(); + let enr = Enr::builder().ip4(ip).udp4(10001).build(&enr_key1).unwrap(); let enr_key2 = CombinedKey::generate_secp256k1(); let ip2 = std::net::Ipv4Addr::LOCALHOST; - let enr2 = EnrBuilder::new("v4") + let enr2 = Enr::builder() .ip4(ip2) .udp4(10002) .build(&enr_key2) From 785e599cd530b9cc7f63cd9d5ea7251990fddfee Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Fri, 20 Oct 2023 19:05:39 -0400 Subject: [PATCH 17/25] fmt --- examples/custom_executor.rs | 6 +++++- examples/find_nodes.rs | 3 +-- examples/simple_server.rs | 6 +++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/examples/custom_executor.rs b/examples/custom_executor.rs index 444013aaf..b57a36a29 100644 --- a/examples/custom_executor.rs +++ b/examples/custom_executor.rs @@ -9,7 +9,11 @@ //! $ cargo run --example custom_executor //! ``` -use discv5::{enr, enr::CombinedKey, enr::Enr, ConfigBuilder, Discv5, Event, ListenConfig}; +use discv5::{ + enr, + enr::{CombinedKey, Enr}, + ConfigBuilder, Discv5, Event, ListenConfig, +}; use std::net::Ipv4Addr; fn main() { diff --git a/examples/find_nodes.rs b/examples/find_nodes.rs index d79f9f400..740d0ccbd 100644 --- a/examples/find_nodes.rs +++ b/examples/find_nodes.rs @@ -18,8 +18,7 @@ use clap::Parser; use discv5::{ enr, - enr::Enr, - enr::{k256, CombinedKey}, + enr::{k256, CombinedKey, Enr}, ConfigBuilder, Discv5, Event, ListenConfig, }; use std::{ diff --git a/examples/simple_server.rs b/examples/simple_server.rs index 18f06c673..bf41fcf64 100644 --- a/examples/simple_server.rs +++ b/examples/simple_server.rs @@ -10,7 +10,11 @@ //! $ cargo run --example simple_server -- //! ``` -use discv5::{enr, enr::CombinedKey, enr::Enr, ConfigBuilder, Discv5, Event, ListenConfig}; +use discv5::{ + enr, + enr::{CombinedKey, Enr}, + ConfigBuilder, Discv5, Event, ListenConfig, +}; use std::net::Ipv4Addr; #[tokio::main] From cb7a0f04b591fc5798dbab11207492bae1942ede Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Mon, 23 Oct 2023 09:24:40 -0400 Subject: [PATCH 18/25] fmt --- src/rpc.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/rpc.rs b/src/rpc.rs index e4a42fa2b..9012dadf0 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -1,5 +1,7 @@ -use alloy_rlp::bytes::{Buf, Bytes, BytesMut}; -use alloy_rlp::{Decodable, Encodable, Error as DecoderError, Header}; +use alloy_rlp::{ + bytes::{Buf, Bytes, BytesMut}, + Decodable, Encodable, Error as DecoderError, Header, +}; use enr::{CombinedKey, Enr}; use std::net::{IpAddr, Ipv6Addr}; use tracing::{debug, warn}; From 7d24962ee1655d879544b7fab1304cbd8183d563 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Wed, 29 Nov 2023 17:29:37 -0500 Subject: [PATCH 19/25] update enr version --- Cargo.toml | 2 +- src/discv5.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 817a32d90..a3bd0ed66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"] exclude = [".gitignore", ".github/*"] [dependencies] -enr = { git = "https://github.com/armaganyildirak/enr", rev = "106b0d7f24931cb1d308749a5b5e2198d7909984", features = ["k256", "ed25519"] } +enr = { git = "https://github.com/armaganyildirak/enr", rev = "77bde01922fb0b79b0c12bdecc1511b324e8f06c", features = ["k256", "ed25519"] } tokio = { version = "1", features = ["net", "sync", "macros", "rt"] } libp2p = { version = "0.52", features = ["ed25519", "secp256k1"], optional = true } zeroize = { version = "1", features = ["zeroize_derive"] } diff --git a/src/discv5.rs b/src/discv5.rs index 5561fb0c9..c109356c7 100644 --- a/src/discv5.rs +++ b/src/discv5.rs @@ -23,7 +23,7 @@ use crate::{ service::{QueryKind, Service, ServiceRequest, TalkRequest}, Config, DefaultProtocolId, Enr, IpMode, }; -use enr::{CombinedKey, EnrError, EnrKey, NodeId}; +use enr::{CombinedKey, EnrKey, Error as EnrError, NodeId}; use parking_lot::RwLock; use std::{ future::Future, From c344f54f4a6a6bf598eac0f17a0d5285dd2775cd Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Wed, 29 Nov 2023 17:59:06 -0500 Subject: [PATCH 20/25] check payload size for preventing crashes --- src/rpc.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/rpc.rs b/src/rpc.rs index d50d35c15..0c60f62e9 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -451,6 +451,9 @@ impl Message { if !node_header.list { return Err(DecoderError::Custom("Invalid format of header")); } + if node_header.payload_length +2 > payload.len() { + return Err(DecoderError::Custom("Payload size is smaller than payload_length")); + } let enr_rlp = Enr::::decode( &mut &payload[..node_header.payload_length + 2], )?; From 7d975fc28aac8576c98d4546b97b239d26d0046b Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Wed, 29 Nov 2023 18:00:46 -0500 Subject: [PATCH 21/25] fmt --- src/rpc.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/rpc.rs b/src/rpc.rs index 0c60f62e9..08b6d60b2 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -451,8 +451,10 @@ impl Message { if !node_header.list { return Err(DecoderError::Custom("Invalid format of header")); } - if node_header.payload_length +2 > payload.len() { - return Err(DecoderError::Custom("Payload size is smaller than payload_length")); + if node_header.payload_length + 2 > payload.len() { + return Err(DecoderError::Custom( + "Payload size is smaller than payload_length", + )); } let enr_rlp = Enr::::decode( &mut &payload[..node_header.payload_length + 2], From c767adfb4f3d54c02838279bd31746fa3e00eac1 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Thu, 30 Nov 2023 09:06:00 -0500 Subject: [PATCH 22/25] update enr version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a3bd0ed66..641acafca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"] exclude = [".gitignore", ".github/*"] [dependencies] -enr = { git = "https://github.com/armaganyildirak/enr", rev = "77bde01922fb0b79b0c12bdecc1511b324e8f06c", features = ["k256", "ed25519"] } +enr = { git = "https://github.com/sigp/enr", rev = "77bde01922fb0b79b0c12bdecc1511b324e8f06c", features = ["k256", "ed25519"] } tokio = { version = "1", features = ["net", "sync", "macros", "rt"] } libp2p = { version = "0.52", features = ["ed25519", "secp256k1"], optional = true } zeroize = { version = "1", features = ["zeroize_derive"] } From 9110d4ebf4d6bbf84478e03d18a45ffd60796c4f Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Fri, 15 Mar 2024 11:27:50 -0400 Subject: [PATCH 23/25] Change the enr version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 91aaeff4c..7b0915df3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"] exclude = [".gitignore", ".github/*"] [dependencies] -enr = { git = "https://github.com/sigp/enr", rev = "77bde01922fb0b79b0c12bdecc1511b324e8f06c", features = ["k256", "ed25519"] } +enr = { version = "0.10.1", features = ["k256", "ed25519"] } tokio = { version = "1", features = ["net", "sync", "macros", "rt"] } libp2p = { version = "0.53", features = ["ed25519", "secp256k1"], optional = true } zeroize = { version = "1", features = ["zeroize_derive"] } From 9914904c4791093b5d1f9ccb771102b9cba1316d Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Fri, 15 Mar 2024 11:33:57 -0400 Subject: [PATCH 24/25] Change the alloy-rlp version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 7b0915df3..841a29387 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ libp2p = { version = "0.53", features = ["ed25519", "secp256k1"], optional = tru zeroize = { version = "1", features = ["zeroize_derive"] } futures = "0.3" uint = { version = "0.9", default-features = false } -alloy-rlp = { version = "0.3.3", default-features = true } +alloy-rlp = { version = "0.3.4", default-features = true } # This version must be kept up to date do it uses the same dependencies as ENR hkdf = "0.12" hex = "0.4" From dece56b1f31c1aac43fd80a67e3df288d241db50 Mon Sep 17 00:00:00 2001 From: armaganyildirak Date: Mon, 18 Mar 2024 16:06:15 -0400 Subject: [PATCH 25/25] change enr version 10.1 to 11.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 841a29387..6bba8bd5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"] exclude = [".gitignore", ".github/*"] [dependencies] -enr = { version = "0.10.1", features = ["k256", "ed25519"] } +enr = { version = "0.11.0", features = ["k256", "ed25519"] } tokio = { version = "1", features = ["net", "sync", "macros", "rt"] } libp2p = { version = "0.53", features = ["ed25519", "secp256k1"], optional = true } zeroize = { version = "1", features = ["zeroize_derive"] }