Skip to content

Backport Thunder 0.12.2, bump version for release 0.12.2 #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
[submodule "mainchain"]
path = mainchain
url = https://github.com/LayerTwo-Labs/mainchain
[submodule "proto"]
path = proto
url = https://github.com/LayerTwo-Labs/cusf_sidechain_proto.git
11 changes: 6 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ authors = ["Ash Manning <[email protected]>"]
edition = "2024"
license-file = "LICENSE.txt"
publish = false
version = "0.12.1"
version = "0.12.2"

[workspace.dependencies]
anyhow = "1.0.72"
Expand Down
1 change: 1 addition & 0 deletions lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ bytes = "1.9.0"
clap = { workspace = true, features = ["derive"], optional = true }
ed25519-dalek = { version = "2.1.1", features = ["batch", "serde"] }
fallible-iterator = "0.3.0"
fatality = "0.1.1"
futures = { workspace = true }
hashlink = { version = "0.10.0", features = ["serde_impl"] }
fraction = { workspace = true }
Expand Down
94 changes: 94 additions & 0 deletions lib/net/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
use std::net::{IpAddr, SocketAddr};

use fatality::fatality;
use sneed::{db, env, rwtxn};
use thiserror::Error;
use transitive::Transitive;

use crate::net::PeerConnectionError;

#[derive(Debug, Error)]
#[error("already connected to peer at {0}")]
pub struct AlreadyConnected(pub SocketAddr);

/// Another connection can be accepted after a non-fatal error
#[derive(Transitive)]
#[fatality(splitable)]
#[transitive(
from(db::error::Put, db::Error),
from(env::error::WriteTxn, env::Error),
from(db::Error, sneed::Error),
from(env::Error, sneed::Error),
from(rwtxn::Error, sneed::Error)
)]
pub enum AcceptConnection {
#[error(transparent)]
AlreadyConnected(#[from] AlreadyConnected),
#[error("connection error (remote address: {remote_address})")]
Connection {
#[source]
error: quinn::ConnectionError,
remote_address: SocketAddr,
},
#[error(transparent)]
#[fatal]
Db(#[from] sneed::Error),
#[error("server endpoint closed")]
#[fatal]
ServerEndpointClosed,
}

#[allow(clippy::duplicated_attributes)]
#[derive(Debug, Error, Transitive)]
#[transitive(from(db::error::Put, db::Error))]
#[transitive(from(db::error::TryGet, db::Error))]
#[transitive(from(env::error::CreateDb, env::Error))]
#[transitive(from(env::error::OpenDb, env::Error))]
#[transitive(from(env::error::WriteTxn, env::Error))]
#[transitive(from(rwtxn::error::Commit, rwtxn::Error))]
pub enum Error {
#[error(transparent)]
AcceptConnection(#[from] <AcceptConnection as fatality::Split>::Fatal),
#[error("accept error")]
AcceptError,
#[error(transparent)]
AlreadyConnected(#[from] AlreadyConnected),
#[error("bincode error")]
Bincode(#[from] bincode::Error),
#[error("connect error")]
Connect(#[from] quinn::ConnectError),
#[error(transparent)]
Db(#[from] db::Error),
#[error("Database env error")]
DbEnv(#[from] env::Error),
#[error("Database write error")]
DbWrite(#[from] rwtxn::Error),
#[error("quinn error")]
Io(#[from] std::io::Error),
#[error("peer connection not found for {0}")]
MissingPeerConnection(SocketAddr),
/// Unspecified peer IP addresses cannot be connected to.
/// `0.0.0.0` is one example of an "unspecified" IP.
#[error("unspecified peer ip address (cannot connect to '{0}')")]
UnspecfiedPeerIP(IpAddr),
#[error(transparent)]
NoInitialCipherSuite(#[from] quinn::crypto::rustls::NoInitialCipherSuite),
#[error("peer connection")]
PeerConnection(#[source] Box<PeerConnectionError>),
#[error("quinn rustls error")]
QuinnRustls(#[from] quinn::crypto::rustls::Error),
#[error("rcgen")]
RcGen(#[from] rcgen::Error),
#[error("read to end error")]
ReadToEnd(#[from] quinn::ReadToEndError),
#[error("send datagram error")]
SendDatagram(#[from] quinn::SendDatagramError),
#[error("write error")]
Write(#[from] quinn::WriteError),
}

impl From<PeerConnectionError> for Error {
fn from(err: PeerConnectionError) -> Self {
Self::PeerConnection(Box::new(err))
}
}
86 changes: 13 additions & 73 deletions lib/net/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{
collections::{HashMap, HashSet, hash_map},
net::{IpAddr, SocketAddr},
net::SocketAddr,
sync::Arc,
};

Expand All @@ -9,9 +9,7 @@ use futures::{StreamExt, channel::mpsc};
use heed::types::{SerdeBincode, Unit};
use parking_lot::RwLock;
use quinn::{ClientConfig, Endpoint, ServerConfig};
use sneed::{
DatabaseUnique, DbError, EnvError, RwTxnError, UnitKey, db, env, rwtxn,
};
use sneed::{DatabaseUnique, DbError, EnvError, RwTxnError, UnitKey};
use tokio_stream::StreamNotifyClose;
use tracing::instrument;

Expand All @@ -21,8 +19,10 @@ use crate::{
types::{AuthorizedTransaction, Network, THIS_SIDECHAIN, VERSION, Version},
};

pub mod error;
mod peer;

pub use error::Error;
pub(crate) use peer::error::mailbox::Error as PeerConnectionMailboxError;
use peer::{
Connection, ConnectionContext as PeerConnectionCtxt,
Expand All @@ -35,67 +35,6 @@ pub use peer::{
message as peer_message,
};

#[allow(clippy::duplicated_attributes)]
#[derive(thiserror::Error, transitive::Transitive, Debug)]
#[transitive(from(db::error::Put, DbError))]
#[transitive(from(db::error::TryGet, DbError))]
#[transitive(from(env::error::CreateDb, EnvError))]
#[transitive(from(env::error::OpenDb, EnvError))]
#[transitive(from(env::error::WriteTxn, EnvError))]
#[transitive(from(rwtxn::error::Commit, RwTxnError))]
pub enum Error {
#[error("accept error")]
AcceptError,
#[error("already connected to peer at {0}")]
AlreadyConnected(SocketAddr),
#[error("bincode error")]
Bincode(#[from] bincode::Error),
#[error("connect error")]
Connect(#[from] quinn::ConnectError),
#[error("connection error (remote address: {remote_address})")]
Connection {
#[source]
error: quinn::ConnectionError,
remote_address: SocketAddr,
},
#[error(transparent)]
Db(#[from] DbError),
#[error("Database env error")]
DbEnv(#[from] sneed::env::Error),
#[error("Database write error")]
DbWrite(#[from] sneed::rwtxn::Error),
#[error("quinn error")]
Io(#[from] std::io::Error),
#[error("peer connection not found for {0}")]
MissingPeerConnection(SocketAddr),
#[error(transparent)]
NoInitialCipherSuite(#[from] quinn::crypto::rustls::NoInitialCipherSuite),
#[error("peer connection")]
PeerConnection(#[source] Box<PeerConnectionError>),
#[error("quinn rustls error")]
QuinnRustls(#[from] quinn::crypto::rustls::Error),
#[error("rcgen")]
RcGen(#[from] rcgen::Error),
#[error("read to end error")]
ReadToEnd(#[from] quinn::ReadToEndError),
#[error("send datagram error")]
SendDatagram(#[from] quinn::SendDatagramError),
#[error("server endpoint closed")]
ServerEndpointClosed,
/// Unspecified peer IP addresses cannot be connected to.
/// `0.0.0.0` is one example of an "unspecified" IP.
#[error("unspecified peer ip address (cannot connect to '{0}')")]
UnspecfiedPeerIP(IpAddr),
#[error("write error")]
Write(#[from] quinn::WriteError),
}

impl From<PeerConnectionError> for Error {
fn from(err: PeerConnectionError) -> Self {
Self::PeerConnection(Box::new(err))
}
}

/// Dummy certificate verifier that treats any certificate as valid.
/// NOTE, such verification is vulnerable to MITM attacks, but convenient for testing.
#[derive(Debug)]
Expand Down Expand Up @@ -243,13 +182,13 @@ impl Net {
&self,
addr: SocketAddr,
peer_connection_handle: PeerConnectionHandle,
) -> Result<(), Error> {
) -> Result<(), error::AlreadyConnected> {
tracing::trace!(%addr, "adding to active peers");
let mut active_peers_write = self.active_peers.write();
match active_peers_write.entry(addr) {
hash_map::Entry::Occupied(_) => {
tracing::error!(%addr, "already connected");
Err(Error::AlreadyConnected(addr))
Err(error::AlreadyConnected(addr))
}
hash_map::Entry::Vacant(active_peer_entry) => {
active_peer_entry.insert(peer_connection_handle);
Expand Down Expand Up @@ -302,7 +241,7 @@ impl Net {
) -> Result<(), Error> {
if self.active_peers.read().contains_key(&addr) {
tracing::error!("already connected");
return Err(Error::AlreadyConnected(addr));
return Err(error::AlreadyConnected(addr).into());
}
// This check happens within Quinn with a
// generic "invalid remote address". We run the
Expand Down Expand Up @@ -421,7 +360,7 @@ impl Net {
pub async fn accept_incoming(
&self,
env: sneed::Env,
) -> Result<Option<SocketAddr>, Error> {
) -> Result<Option<SocketAddr>, error::AcceptConnection> {
tracing::debug!(
"listening for connections on `{}`",
self.server
Expand All @@ -433,16 +372,17 @@ impl Net {
Some(conn) => {
let remote_address = conn.remote_address();
tracing::trace!(%remote_address, "accepting connection");
let raw_conn =
conn.await.map_err(|error| Error::Connection {
let raw_conn = conn.await.map_err(|error| {
error::AcceptConnection::Connection {
error,
remote_address,
})?;
}
})?;
Connection::from(raw_conn)
}
None => {
tracing::debug!("server endpoint closed");
return Err(Error::ServerEndpointClosed);
return Err(error::AcceptConnection::ServerEndpointClosed);
}
};
let addr = connection.addr();
Expand Down
8 changes: 7 additions & 1 deletion lib/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ pub enum Error {
#[error("mempool error")]
MemPool(#[from] mempool::Error),
#[error("net error")]
Net(#[from] net::Error),
Net(#[from] Box<net::Error>),
#[error("net task error")]
NetTask(#[source] Box<net_task::Error>),
#[error("No CUSF mainchain wallet client")]
Expand All @@ -91,6 +91,12 @@ pub enum Error {
Zmq(#[from] zeromq::ZmqError),
}

impl From<net::Error> for Error {
fn from(err: net::Error) -> Self {
Self::Net(Box::new(err))
}
}

impl From<net_task::Error> for Error {
fn from(err: net_task::Error) -> Self {
Self::NetTask(Box::new(err))
Expand Down
Loading
Loading