mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
Implement ETH P2P (#81)
* refactor: move things to types
* feat(ethwire): bring in message type from ethp2p
30c11138d5/src/message.rs
* feat(ethwire): add eth-stream with Stream/Sink impls
* feat(ethwire): make Sink error an EthStreamError
* feat(ecies): expose util module
* add more deps
* feat: add broadcast newblockhashes
* fix: rlp serialize with message-id first
* chore: cleanup doc
* wip: test eth connection
* bump cargo lock
* feat: add rlp codec and get stream tests working
* fix: convert RlpCodec to PassthroughCodec
we were rlp encoding twice
* Revert "fix: convert RlpCodec to PassthroughCodec"
This reverts commit 6e6e0a58112c14d7ffba62dc83f9747ddc280641.
This does not handle framing, which would fail decoding if a partial
write happened to the socket.
* add tracing
* refactor: add handshake error
* feat(ethwire): add status handshake
* test(ethwire): handshake works
* refactor: expose EthStream::new
* chore: clippy lints
* fix: get rid of rlp codec
we can instead use LengthLimitedCodec from Tokio IO, which we re-export
as PassthroughCodec
* fix(eth): add handshake + msg error checks
1. 10MB message lengths
2. Same Genesis, Version, Chain on Status Handshake
* chore: ignore result_large_err
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
committed by
GitHub
parent
5dfe5ac29b
commit
8009d997c0
@ -2,7 +2,7 @@ use crate::{
|
||||
algorithm::{ECIES, MAX_BODY_SIZE},
|
||||
ECIESError, EgressECIESValue, IngressECIESValue,
|
||||
};
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use bytes::BytesMut;
|
||||
use reth_primitives::H512 as PeerId;
|
||||
use secp256k1::SecretKey;
|
||||
use std::{fmt::Debug, io};
|
||||
@ -105,7 +105,8 @@ impl Decoder for ECIESCodec {
|
||||
}
|
||||
|
||||
let mut data = buf.split_to(self.ecies.body_len());
|
||||
let ret = Bytes::copy_from_slice(self.ecies.read_body(&mut data)?);
|
||||
let mut ret = BytesMut::new();
|
||||
ret.extend_from_slice(self.ecies.read_body(&mut data)?);
|
||||
|
||||
self.state = ECIESState::Header;
|
||||
return Ok(Some(IngressECIESValue::Message(ret)))
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::IngressECIESValue;
|
||||
use thiserror::Error;
|
||||
|
||||
/// An error that occurs while reading or writing to an ECIES stream.
|
||||
#[derive(Debug, Error)]
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#![allow(clippy::result_large_err)]
|
||||
#![warn(missing_docs, unreachable_pub)]
|
||||
#![deny(unused_must_use, rust_2018_idioms)]
|
||||
#![doc(test(
|
||||
@ -10,7 +11,7 @@
|
||||
pub mod algorithm;
|
||||
pub mod mac;
|
||||
pub mod stream;
|
||||
mod util;
|
||||
pub mod util;
|
||||
|
||||
mod error;
|
||||
pub use error::ECIESError;
|
||||
@ -38,5 +39,5 @@ pub enum IngressECIESValue {
|
||||
/// Receiving an ACK message
|
||||
Ack,
|
||||
/// Receiving a message
|
||||
Message(bytes::Bytes),
|
||||
Message(bytes::BytesMut),
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//! The ECIES Stream implementation which wraps over [`AsyncRead`] and [`AsyncWrite`].
|
||||
use crate::{ECIESError, EgressECIESValue, IngressECIESValue};
|
||||
use crate::{codec::ECIESCodec, ECIESError, EgressECIESValue, IngressECIESValue};
|
||||
use bytes::Bytes;
|
||||
use futures::{ready, Sink, SinkExt};
|
||||
use reth_primitives::H512 as PeerId;
|
||||
@ -19,8 +19,6 @@ use tokio_stream::{Stream, StreamExt};
|
||||
use tokio_util::codec::{Decoder, Framed};
|
||||
use tracing::{debug, instrument, trace};
|
||||
|
||||
use crate::codec::ECIESCodec;
|
||||
|
||||
/// `ECIES` stream over TCP exchanging raw bytes
|
||||
#[derive(Debug)]
|
||||
pub struct ECIESStream<Io> {
|
||||
@ -106,7 +104,7 @@ impl<Io> Stream for ECIESStream<Io>
|
||||
where
|
||||
Io: AsyncRead + Unpin,
|
||||
{
|
||||
type Item = Result<Bytes, io::Error>;
|
||||
type Item = Result<bytes::BytesMut, io::Error>;
|
||||
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
||||
match ready!(Pin::new(&mut self.get_mut().stream).poll_next(cx)) {
|
||||
@ -156,8 +154,6 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
// TODO: implement test for the proposed
|
||||
// API: https://github.com/foundry-rs/reth/issues/64#issue-1408708420
|
||||
async fn can_write_and_read() {
|
||||
let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap();
|
||||
let server_key = SecretKey::new(&mut rand::thread_rng());
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
//! Utility functions for hashing and encoding.
|
||||
|
||||
use hmac::{Hmac, Mac};
|
||||
use reth_primitives::{H256, H512 as PeerId};
|
||||
use secp256k1::PublicKey;
|
||||
@ -22,7 +24,7 @@ pub(crate) fn hmac_sha256(key: &[u8], input: &[&[u8]], auth_data: &[u8]) -> H256
|
||||
|
||||
/// Converts a [secp256k1::PublicKey] to a [PeerId] by stripping the
|
||||
/// SECP256K1_TAG_PUBKEY_UNCOMPRESSED tag and storing the rest of the slice in the [PeerId].
|
||||
pub(crate) fn pk2id(pk: &PublicKey) -> PeerId {
|
||||
pub fn pk2id(pk: &PublicKey) -> PeerId {
|
||||
PeerId::from_slice(&pk.serialize_uncompressed()[1..])
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user