From 8d54bb11292da5ffbad09b8fbafc5008b7ee6c01 Mon Sep 17 00:00:00 2001 From: rustaceanrob Date: Fri, 10 Oct 2025 09:58:05 +0100 Subject: [PATCH] net: Prefer `BufRead` From `tokio` documentation: > BufReader can improve the speed of programs that make small > and repeated read calls to the same file or network socket. This should indeed be the case as there is a small read followed by a larger read for all bitcoin p2p messages. Ignoring the writing side as the client reads far more than it writes. --- src/network/parsers.rs | 6 +++--- src/network/peer.rs | 5 +++-- src/network/reader.rs | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/network/parsers.rs b/src/network/parsers.rs index e0d8d65a..51cf4669 100644 --- a/src/network/parsers.rs +++ b/src/network/parsers.rs @@ -3,19 +3,19 @@ use bip324::{PacketReader, PacketType}; use bitcoin::consensus::{deserialize, deserialize_partial}; use bitcoin::p2p::message::RawNetworkMessage; use bitcoin::Network; -use tokio::io::AsyncReadExt; +use tokio::io::{AsyncBufReadExt, AsyncReadExt}; use super::error::ReaderError; use super::V1Header; const MAX_MESSAGE_BYTES: u32 = 1024 * 1024 * 32; -pub(crate) enum MessageParser { +pub(crate) enum MessageParser { V2(R, PacketReader), V1(R, Network), } -impl MessageParser { +impl MessageParser { pub async fn read_message(&mut self) -> Result, ReaderError> { match self { MessageParser::V2(stream, decryptor) => { diff --git a/src/network/peer.rs b/src/network/peer.rs index 93612e58..6d917f3d 100644 --- a/src/network/peer.rs +++ b/src/network/peer.rs @@ -5,7 +5,7 @@ use addrman::Record; use bip324::{AsyncProtocol, PacketReader, PacketWriter, Role}; use bitcoin::{p2p::ServiceFlags, Network}; use tokio::{ - io::{AsyncRead, AsyncWrite, AsyncWriteExt}, + io::{AsyncRead, AsyncWrite, AsyncWriteExt, BufReader}, net::TcpStream, select, sync::{ @@ -79,7 +79,8 @@ impl Peer { pub async fn run(&mut self, connection: TcpStream) -> Result<(), PeerError> { let start_time = Instant::now(); let (tx, mut rx) = mpsc::channel(32); - let (mut reader, mut writer) = connection.into_split(); + let (reader, mut writer) = connection.into_split(); + let mut reader = BufReader::new(reader); // If a peer signals for V2 we will use it, otherwise just use plaintext. let (mut outbound_messages, mut peer_reader) = if self.source.service_flags().has(ServiceFlags::P2P_V2) { diff --git a/src/network/reader.rs b/src/network/reader.rs index 0826842e..1d8c524e 100644 --- a/src/network/reader.rs +++ b/src/network/reader.rs @@ -3,7 +3,7 @@ use std::net::IpAddr; use bitcoin::p2p::address::AddrV2; use bitcoin::p2p::{message::NetworkMessage, message_blockdata::Inventory, ServiceFlags}; use bitcoin::{FeeRate, Wtxid}; -use tokio::io::AsyncReadExt; +use tokio::io::AsyncBufReadExt; use tokio::sync::mpsc::Sender; use crate::channel_messages::{CombinedAddr, ReaderMessage}; @@ -17,12 +17,12 @@ const MAX_ADDR: usize = 1_000; const MAX_INV: usize = 50_000; const MAX_HEADERS: usize = 2_000; -pub(crate) struct Reader { +pub(crate) struct Reader { parser: MessageParser, tx: Sender, } -impl Reader { +impl Reader { pub fn new(parser: MessageParser, tx: Sender) -> Self { Self { parser, tx } }