cometbft_p2p/
lib.rs

1#![doc = include_str!("../README.md")]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![forbid(unsafe_code)]
4#![warn(
5    clippy::all,
6    clippy::unwrap_used,
7    nonstandard_style,
8    trivial_casts,
9    trivial_numeric_casts,
10    unused_import_braces,
11    unused_qualifications
12)]
13
14//! # Usage
15//!
16//! The following example illustrates how to use the [`SecretConnection`] type as a TCP client which
17//! receives a hypothetical `ExampleMessage` type which is expected to impl the [`prost::Message`]
18//! trait:
19//!
20//! ```no_run
21//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
22//! # type ExampleMessage = String; // example that impls `prost::Message`
23//! # let expected_peer_id = cometbft_p2p::PeerId(Default::default());
24//! use std::net::TcpStream;
25//! use cometbft_p2p::{SecretConnection, IdentitySecret, ReadMsg, rand_core::OsRng};
26//!
27//! let node_identity = IdentitySecret::generate(&mut OsRng);
28//! let tcp_sock = TcpStream::connect("example.com:26656")?;
29//! let mut conn = SecretConnection::new(tcp_sock, &node_identity)?;
30//!
31//! // Verify remote peer ID (optional but highly encouraged)
32//! conn.peer_public_key().peer_id().verify(expected_peer_id)?;
33//!
34//! // Read Protobuf message from the remote peer
35//! // (note: you could also write here if initiating a request, see `WriteMsg`)
36//! let msg: ExampleMessage = conn.read_msg()?;
37//! # Ok(())
38//! # }
39//! ```
40//!
41//! The [`SecretConnection`] type (`conn`) impls the [`ReadMsg`] and [`WriteMsg`] traits which can
42//! be used to receive and send Protobuf messages which impl the [`prost::Message`] trait.
43//!
44//! ## Async usage
45//!
46//! Enable the `async` crate feature to take advantage of the async support in this crate, which is
47//! implemented using the Tokio async runtime:
48//!
49#![cfg_attr(feature = "async", doc = "```no_run")]
50#![cfg_attr(not(feature = "async"), doc = "```ignore")]
51//! # tokio_test::block_on(async {
52//! # type ExampleMessage = String; // example that impls `prost::Message`
53//! # let expected_peer_id = cometbft_p2p::PeerId(Default::default());
54//! use tokio::net::TcpStream;
55//! use cometbft_p2p::{AsyncSecretConnection, IdentitySecret, AsyncReadMsg, rand_core::OsRng};
56//!
57//! let node_identity = IdentitySecret::generate(&mut OsRng);
58//! let tcp_sock = TcpStream::connect("example.com:26656").await?;
59//! let mut conn = AsyncSecretConnection::new(tcp_sock, &node_identity).await?;
60//!
61//! // Verify remote peer ID (optional but highly encouraged)
62//! conn.peer_public_key().peer_id().verify(expected_peer_id)?;
63//!
64//! // Read Protobuf message from the remote peer
65//! // (note: you could also write here if initiating a request, see `AsyncWriteMsg`)
66//! let msg: ExampleMessage = conn.read_msg().await?;
67//! # Ok::<(), Box<dyn std::error::Error>>(())
68//! # });
69//! ```
70//!
71//! The [`AsyncSecretConnection`] type (`conn`) impls the [`AsyncReadMsg`] and [`AsyncWriteMsg`]
72//! traits which can be used to asynchronously receive and send Protobuf messages which impl the
73//! [`prost::Message`] trait.
74//!
75//! ## Splitting connections
76//!
77//! The [`SecretConnection::split`] and [`AsyncSecretConnection::split`] methods can be used to
78//! split a connection into separate read and write halves. This is particularly useful with async
79//! to be able to simultaneously read and write to a connection.
80
81mod async_secret_connection;
82mod encryption;
83mod error;
84mod handshake;
85mod kdf;
86mod peer_id;
87mod proto;
88mod public_key;
89mod secret_connection;
90mod test_vectors;
91mod traits;
92
93pub use crate::{
94    error::{CryptoError, Error, Result, VerifyPeerError},
95    peer_id::PeerId,
96    public_key::PublicKey,
97    secret_connection::{SecretConnection, SecretReader, SecretWriter},
98    traits::{ReadMsg, TryCloneIo, WriteMsg},
99};
100pub use rand_core;
101
102#[cfg(feature = "async")]
103pub use crate::{
104    async_secret_connection::{AsyncSecretConnection, AsyncSecretReader, AsyncSecretWriter},
105    traits::{AsyncReadMsg, AsyncWriteMsg},
106};
107
108/// Secret Connection node identity secret keys.
109///
110/// Ed25519 is currently the only supported signature algorithm.
111pub type IdentitySecret = ed25519::SigningKey;
112
113pub(crate) use curve25519_dalek::montgomery::MontgomeryPoint as EphemeralPublic;
114pub(crate) use ed25519_dalek as ed25519;
115
116/// Message size limit which applies to length-delimited messages read via the [`ReadMsg`] trait.
117///
118/// Ensures we won't allocate excessively large buffers when consuming incoming requests.
119pub const MAX_MSG_LEN: usize = 1_048_576; // 1 MiB