From 976d545fe778be9a96492c25ff96b25ed988b029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Wed, 17 Dec 2025 18:28:35 +0100 Subject: [PATCH 01/45] feat: implement echo connection check with ping/pong mechanism Fixes #1647 --- crates/node/src/p2p.rs | 107 ++++++++++++++++++++++++++++++++++------- 1 file changed, 89 insertions(+), 18 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 613bd4d4d9..47fe70b377 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -18,6 +18,7 @@ use rustls::{ClientConfig, CommonState}; use std::collections::HashMap; use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; use std::sync::Arc; +use std::time::Instant; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::{TcpListener, TcpStream}; use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender}; @@ -25,7 +26,7 @@ use tokio_rustls::TlsAcceptor; use tokio_util::sync::CancellationToken; use tracing::info; -/// Implements MeshNetworkTransportSender for sending messages over a TLS-based +/// Implements [`MeshNetworkTransportSender`] for sending messages over a TLS-based /// mesh network. pub struct TlsMeshSender { my_id: ParticipantId, @@ -34,7 +35,7 @@ pub struct TlsMeshSender { connectivities: Arc>, } -/// Implements MeshNetworkTransportReceiver. +/// Implements [`MeshNetworkTransportReceiver`]. pub struct TlsMeshReceiver { receiver: UnboundedReceiver, _incoming_connections_task: AutoAbortTask<()>, @@ -67,9 +68,9 @@ struct TlsConnection { /// sends it over the TLS connection. This task owns the connection, so /// dropping it closes the connection. _sender_task: AutoAbortTask<()>, - /// Task that periodically sends a Ping message to the other side. It does - /// not expect a Pong, it simply keeps the connection alive (so we can - /// quickly detect if the connection is broken). + /// Task that periodically sends Ping messages with incrementing sequence numbers. + /// This task only sends pings; the sender_task handles receiving Pong responses + /// and closing the connection if no pongs are received within PONG_TIMEOUT. _keepalive_task: AutoAbortTask<()>, /// This is cancelled when the connection is closed. Used to wait for the /// connection to close. @@ -87,7 +88,8 @@ impl Drop for DropToCancel { #[derive(BorshSerialize, BorshDeserialize)] enum Packet { - Ping, + Ping(u64), + Pong(u64), MpcMessage(MpcMessage), IndexerHeight(IndexerHeightMessage), } @@ -97,6 +99,12 @@ impl TlsConnection { /// the connection is considered not successful. const HANDSHAKE_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(2); + /// Interval between ping messages. + const PING_INTERVAL: std::time::Duration = std::time::Duration::from_secs(1); + + /// If we don't receive a pong response within this time, consider the connection dead. + const PONG_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5); + /// Makes a TLS/TCP connection to the given address, authenticating the /// other side as the given participant. async fn new( @@ -136,7 +144,20 @@ impl TlsConnection { async move { let _drop_to_cancel = DropToCancel(closed_clone); let mut sent_bytes: u64 = 0; + let mut received_bytes: u64 = 0; + let mut last_pong_time = Instant::now(); + let mut last_pong_seq: u64 = 0; loop { + // Check if we've timed out waiting for pong + if last_pong_time.elapsed() > Self::PONG_TIMEOUT { + tracing::warn!( + "No pong received from {} for {:?}, closing connection", + target_participant_id, + last_pong_time.elapsed() + ); + break; + } + tokio::select! { data = receiver.recv() => { let Some(data) = data else { @@ -150,13 +171,50 @@ impl TlsConnection { tracking::set_progress(&format!("Sent {} bytes", sent_bytes)); } - _ = tls_conn.read_u8() => { - // We do not expect any data from the other side. However, - // selecting on it will quickly return error if the connection - // is broken before we have data to send. That way we can - // immediately quit the loop as soon as the connection is broken - // (so we can reconnect). - break; + result = tokio::time::timeout( + std::time::Duration::from_millis(100), + async { + let len = tls_conn.read_u32().await?; + if len >= MAX_MESSAGE_LEN { + anyhow::bail!("Message too long"); + } + let mut buf = vec![0; len as usize]; + tls_conn.read_exact(&mut buf).await?; + received_bytes += 4 + len as u64; + + let packet = Packet::try_from_slice(&buf) + .context("Failed to deserialize packet")?; + anyhow::Ok(packet) + } + ) => { + match result { + Ok(Ok(Packet::Pong(seq))) => { + if seq > last_pong_seq { + last_pong_seq = seq; + let elapsed = last_pong_time.elapsed(); + last_pong_time = Instant::now(); + tracking::set_progress(&format!( + "Received pong {} from {}, RTT: {:?}", + seq, + target_participant_id, + elapsed + )); + } + } + Ok(Ok(_)) => { + tracing::warn!( + "Received unexpected packet type from {} on outgoing connection", + target_participant_id + ); + } + Ok(Err(e)) => { + tracing::warn!("Error reading from connection: {}", e); + break; + } + Err(_) => { + // Timeout is expected when no data is available + } + } } } } @@ -165,11 +223,13 @@ impl TlsConnection { ); let sender_clone = sender.clone(); let keepalive_task = tracking::spawn( - &format!("TCP keepalive for {}", target_participant_id), + &format!("Ping sender for {}", target_participant_id), async move { + let mut seq: u64 = 0; loop { - tokio::time::sleep(std::time::Duration::from_secs(1)).await; - if sender_clone.send(Packet::Ping).is_err() { + tokio::time::sleep(Self::PING_INTERVAL).await; + seq += 1; + if sender_clone.send(Packet::Ping(seq)).is_err() { // The receiver side will be dropped when the sender task is // dropped (i.e. connection is closed). break; @@ -393,8 +453,19 @@ pub async fn new_tls_mesh_network( let packet = Packet::try_from_slice(&buf).context("Failed to deserialize packet")?; match packet { - Packet::Ping => { - // Do nothing. Pings are just for TCP keepalive. + Packet::Ping(seq) => { + // Respond with Pong to echo the sequence number back + let pong = borsh::to_vec(&Packet::Pong(seq))?; + let len: u32 = pong.len().try_into().context("Message too long")?; + stream.write_u32(len).await?; + stream.write_all(&pong).await?; + } + Packet::Pong(_) => { + // Pong messages should not be received on incoming connections + tracing::warn!( + "Received unexpected Pong from {} on incoming connection", + peer_id + ); } Packet::MpcMessage(mpc_message) => { message_sender.send(PeerMessage::Mpc(MpcPeerMessage { From e51c6652f6b590309d299f2c7135a4db6a068807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Thu, 18 Dec 2025 14:53:29 +0100 Subject: [PATCH 02/45] Add more documentation to p2p.rs --- crates/node/src/p2p.rs | 127 ++++++++++++++++++++++++++++++++++------- 1 file changed, 106 insertions(+), 21 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 47fe70b377..db8cb2b7ad 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -26,54 +26,139 @@ use tokio_rustls::TlsAcceptor; use tokio_util::sync::CancellationToken; use tracing::info; -/// Implements [`MeshNetworkTransportSender`] for sending messages over a TLS-based -/// mesh network. +/// This struct manages **outgoing connections only** - one persistent TLS connection to each +/// peer in the network. When the application wants to send a message to a peer, it queues the +/// message through the corresponding [`PersistentConnection`], which handles automatic +/// reconnection if the connection drops. Each connection runs two background tasks: one for +/// sending/receiving data, and one for sending periodic ping heartbeats. +/// +/// Implements the [`MeshNetworkTransportSender`] trait to provide a high-level API for sending +/// messages (`.send()`, `.send_indexer_height()`) and checking connectivity status +/// (`.connectivity()`, `.wait_for_ready()`), while handling low-level connection management. pub struct TlsMeshSender { + /// The participant ID of this node. my_id: ParticipantId, + /// List of all participant IDs in the network (including this node). participants: Vec, + /// Outgoing connections to all peers (excludes this node). Each connection automatically + /// retries on failure. This is where actual message sending happens - when you call + /// `.send()`, it looks up the connection here and queues the message. connections: HashMap>, + /// Tracks connection state (incoming and outgoing) for all peers. This is separate from + /// `connections` because it monitors *both directions* - while `connections` only manages + /// our outgoing connections, `connectivities` tracks whether both our outgoing connection + /// to a peer AND their incoming connection to us are alive. Used by `.wait_for_ready()` + /// and `.connectivity()` to check bidirectional connectivity status. connectivities: Arc>, } -/// Implements [`MeshNetworkTransportReceiver`]. +/// This struct manages **incoming connections only** - it accepts TLS connections from all +/// peers and multiplexes their messages into a single channel. The application calls +/// `.receive()` to get the next message from any peer. Each incoming connection runs its own +/// background task that reads from the TLS stream, responds to Ping packets, and forwards +/// MPC/IndexerHeight messages to the unified receiver channel. +/// +/// Implements [`MeshNetworkTransportReceiver`] to receive messages from all peers in the +/// mesh network. pub struct TlsMeshReceiver { + /// Unified message queue receiving messages from all peers' incoming connections. + /// When any peer sends us a message, it gets queued here. The application calls + /// `.receive()` to dequeue the next message (which includes the sender's ID). receiver: UnboundedReceiver, + /// Background task running the TCP acceptor loop on our listening port. It continuously + /// accepts incoming TCP connections and spawns a new task for each one that: + /// 1) Performs TLS handshake and authenticates the peer's identity + /// 2) Registers the connection with `connectivities` for bidirectional tracking + /// 3) Reads messages from the peer in a loop + /// 4) Responds to Ping packets by echoing back Pong packets + /// 5) Forwards MpcMessage and IndexerHeight to the unified `receiver` channel + /// The `AutoAbortTask` wrapper ensures automatic cleanup on drop. _incoming_connections_task: AutoAbortTask<()>, } -/// Maps public keys to participant IDs. Used to identify incoming connections. +/// Maps public keys to [`ParticipantId`]s for authenticating incoming connections. +/// +/// This struct is populated at startup with the known public keys of all participants in the +/// network. When a peer establishes an incoming TLS connection, we extract their public key +/// from their TLS certificate and look it up in this map to determine their [`ParticipantId`]. +/// This ensures that only known participants can connect, and we can correctly attribute +/// incoming messages to the right peer. If a connection presents an unknown public key, it is +/// rejected during the authentication phase. #[derive(Default)] struct ParticipantIdentities { key_to_participant_id: HashMap, } -/// A retrying connection that will automatically reconnect if the TCP -/// connection is broken. +/// Maintains a persistent outgoing TLS connection to a single peer with automatic reconnection. +/// +/// This struct wraps a [`TlsConnection`] and ensures it stays alive throughout the lifetime of +/// the node. If the underlying TCP/TLS connection drops (due to network issues, peer restart, +/// etc.), the background task automatically attempts to reconnect after a 1-second delay. Each +/// [`TlsMeshSender`] owns one `PersistentConnection` per peer in the network (N-1 total). struct PersistentConnection { target_participant_id: ParticipantId, connectivity: Arc>, - // The task that loops to connect to the target. When `PersistentConnection` - // is dropped, this task is aborted. The task owns any active connection, - // so dropping it also frees any connection currently alive. + /// Background reconnection task that maintains the connection lifecycle. + /// + /// This task runs an infinite loop that: + /// 1. Attempts to establish a new [`TlsConnection`] to `target_participant_id` + /// 2. On success: Registers the connection with `connectivity` and blocks waiting for it + /// to close (via `wait_for_close()`) + /// 3. On failure: Logs the error and sleeps for [`CONNECTION_RETRY_DELAY`] before retrying + /// 4. When a connection closes (step 2 completes): Loops back to step 1 + /// + /// The task owns the active [`TlsConnection`] (wrapped in Arc), so when the task is + /// aborted (via dropping this `PersistentConnection`), the connection is automatically + /// cleaned up. The [`AutoAbortTask`] wrapper ensures the task is aborted when this struct + /// is dropped, providing RAII-style cleanup on node shutdown. _task: AutoAbortTask<()>, } -/// State for a single TLS/TCP connection to one participant. We only ever send -/// messages through this connection, so there is nothing to handle receiving. -/// Dropping this struct will automatically close the connection. +/// Represents an active outgoing TLS/TCP connection to a single peer participant. +/// +/// This struct encapsulates a single established TCP connection with TLS encryption to one peer. +/// It is **send-only** from the application's perspective - when you want to send a message to +/// a peer, you queue it through the `sender` channel, and the background `_sender_task` reads +/// from the channel and writes to the TLS stream. struct TlsConnection { - /// Used to send messages via the connection. + /// Channel for queuing outbound packets ([`Packet::Ping`], [`Packet::MpcMessage`], + /// [`Packet::IndexerHeight`]) to be sent. + /// + /// The application sends messages by calling `.send_mpc_message()` or `.send_indexer_height()`, + /// which queue packets into this channel. The `_sender_task` continuously reads from the + /// receiver end of this channel and writes packets to the TLS stream. This decouples message + /// sending from I/O operations, allowing the application to queue messages without blocking + /// on network writes. sender: UnboundedSender, - /// Task that reads messages from the channel (other side of `sender`) and - /// sends it over the TLS connection. This task owns the connection, so - /// dropping it closes the connection. + /// Background task that owns the TLS stream and handles I/O operations. + /// + /// This task performs two main responsibilities: + /// 1. **Outbound**: Reads all packet types from the `sender` channel and writes them to + /// the TLS stream + /// 2. **Inbound (Pong only)**: Reads from the TLS stream specifically looking for + /// [`Packet::Pong`] responses to verify the connection is alive. Other packet types + /// are ignored since application messages arrive via the separate incoming connection. + /// + /// The task tracks the last received Pong timestamp and closes the connection if no Pong is + /// received within [`Self::PONG_TIMEOUT`]. When this task is aborted (via [`AutoAbortTask`] + /// drop), it closes the underlying TLS/TCP stream, which triggers [`PersistentConnection`] + /// to reconnect. _sender_task: AutoAbortTask<()>, - /// Task that periodically sends Ping messages with incrementing sequence numbers. - /// This task only sends pings; the sender_task handles receiving Pong responses - /// and closing the connection if no pongs are received within PONG_TIMEOUT. + /// Background task that sends periodic Ping heartbeats to detect dead connections. + /// + /// Every [`Self::PING_INTERVAL`] (1 second), this task sends a Ping packet with an + /// incrementing sequence number through the `sender` channel. The peer is expected to + /// respond with a Pong containing the same sequence number. If the `_sender_task` doesn't + /// receive Pong responses within [`Self::PONG_TIMEOUT`] (5 seconds), it considers the + /// connection dead and closes it. This task only sends Pings; Pong validation is handled + /// by `_sender_task`. _keepalive_task: AutoAbortTask<()>, - /// This is cancelled when the connection is closed. Used to wait for the - /// connection to close. + /// Token that gets cancelled when the connection closes, allowing waiters to be notified. + /// + /// Used by [`PersistentConnection`] via the `wait_for_close()` method to block until the + /// connection dies (either due to network failure, timeout, or intentional shutdown). When + /// `_sender_task` exits, the [`DropToCancel`] guard automatically cancels this token, + /// unblocking any tasks waiting on it. closed: CancellationToken, } From 9f18a65350c2f57216145103e83edc21f4940894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Thu, 18 Dec 2025 18:20:06 +0100 Subject: [PATCH 03/45] Use separate channels for sending and receiving ping/pong messages --- crates/node/src/p2p.rs | 284 ++++++++++++++++++++++++----------------- 1 file changed, 166 insertions(+), 118 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index db8cb2b7ad..cfbd6f1540 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -1,36 +1,46 @@ -use crate::config::MpcConfig; -use crate::network::conn::{ - AllNodeConnectivities, ConnectionVersion, NodeConnectivity, NodeConnectivityInterface, -}; -use crate::network::constants::{MAX_MESSAGE_LEN, MESSAGE_READ_TIMEOUT_SECS}; -use crate::network::handshake::p2p_handshake; -use crate::network::{MeshNetworkTransportReceiver, MeshNetworkTransportSender}; -use crate::primitives::{ - IndexerHeightMessage, MpcMessage, MpcPeerMessage, ParticipantId, PeerIndexerHeightMessage, - PeerMessage, -}; -use crate::tracking::{self, AutoAbortTask, AutoAbortTaskCollection}; use anyhow::{anyhow, Context}; use async_trait::async_trait; use borsh::{BorshDeserialize, BorshSerialize}; use ed25519_dalek::VerifyingKey; use rustls::{ClientConfig, CommonState}; -use std::collections::HashMap; -use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; -use std::sync::Arc; -use std::time::Instant; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use tokio::net::{TcpListener, TcpStream}; -use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender}; +use std::{ + collections::HashMap, + net::{Ipv4Addr, SocketAddr, SocketAddrV4}, + sync::Arc, + time::Instant, +}; +use tokio::{ + io::{AsyncReadExt, AsyncWriteExt}, + net::{TcpListener, TcpStream}, + sync::mpsc::{self, UnboundedReceiver, UnboundedSender}, +}; use tokio_rustls::TlsAcceptor; use tokio_util::sync::CancellationToken; use tracing::info; +use crate::{ + config::MpcConfig, + network::{ + conn::{ + AllNodeConnectivities, ConnectionVersion, NodeConnectivity, NodeConnectivityInterface, + }, + constants::{MAX_MESSAGE_LEN, MESSAGE_READ_TIMEOUT_SECS}, + handshake::p2p_handshake, + MeshNetworkTransportReceiver, MeshNetworkTransportSender, + }, + primitives::{ + IndexerHeightMessage, MpcMessage, MpcPeerMessage, ParticipantId, PeerIndexerHeightMessage, + PeerMessage, + }, + tracking::{self, AutoAbortTask, AutoAbortTaskCollection}, +}; + /// This struct manages **outgoing connections only** - one persistent TLS connection to each /// peer in the network. When the application wants to send a message to a peer, it queues the /// message through the corresponding [`PersistentConnection`], which handles automatic -/// reconnection if the connection drops. Each connection runs two background tasks: one for -/// sending/receiving data, and one for sending periodic ping heartbeats. +/// reconnection if the connection drops. Each connection runs three background tasks: one for +/// sending data, one for sending periodic ping heartbeats, and one watchdog for monitoring pong +/// timeouts. /// /// Implements the [`MeshNetworkTransportSender`] trait to provide a high-level API for sending /// messages (`.send()`, `.send_indexer_height()`) and checking connectivity status @@ -55,9 +65,13 @@ pub struct TlsMeshSender { /// This struct manages **incoming connections only** - it accepts TLS connections from all /// peers and multiplexes their messages into a single channel. The application calls /// `.receive()` to get the next message from any peer. Each incoming connection runs its own -/// background task that reads from the TLS stream, responds to Ping packets, and forwards +/// background task that reads from the TLS stream, handles Ping/Pong packets, and forwards /// MPC/IndexerHeight messages to the unified receiver channel. /// +/// Ping/Pong handling uses cross-stream communication to maintain unidirectional I/O: when +/// receiving a Ping, this handler sends Pong via the outgoing connection to that peer; when +/// receiving a Pong, it updates the outgoing connection's shared pong_state for health monitoring. +/// /// Implements [`MeshNetworkTransportReceiver`] to receive messages from all peers in the /// mesh network. pub struct TlsMeshReceiver { @@ -69,9 +83,10 @@ pub struct TlsMeshReceiver { /// accepts incoming TCP connections and spawns a new task for each one that: /// 1) Performs TLS handshake and authenticates the peer's identity /// 2) Registers the connection with `connectivities` for bidirectional tracking - /// 3) Reads messages from the peer in a loop - /// 4) Responds to Ping packets by echoing back Pong packets - /// 5) Forwards MpcMessage and IndexerHeight to the unified `receiver` channel + /// 3) Reads messages from the peer in a loop (read-only stream usage) + /// 4) On Ping: Sends Pong via our outgoing connection to maintain unidirectional I/O + /// 5) On Pong: Updates the outgoing connection's pong_state directly for health tracking + /// 6) Forwards MpcMessage and IndexerHeight to the unified `receiver` channel /// The `AutoAbortTask` wrapper ensures automatic cleanup on drop. _incoming_connections_task: AutoAbortTask<()>, } @@ -117,9 +132,11 @@ struct PersistentConnection { /// Represents an active outgoing TLS/TCP connection to a single peer participant. /// /// This struct encapsulates a single established TCP connection with TLS encryption to one peer. -/// It is **send-only** from the application's perspective - when you want to send a message to -/// a peer, you queue it through the `sender` channel, and the background `_sender_task` reads -/// from the channel and writes to the TLS stream. +/// It uses **unidirectional I/O** - the TLS stream is write-only from this connection's +/// perspective. When you want to send a message to a peer, you queue it through the `sender` +/// channel, and the background `_sender_task` reads from the channel and writes to the TLS +/// stream. Pong responses arrive via the separate incoming connection and update the shared +/// `pong_state` for health monitoring. struct TlsConnection { /// Channel for queuing outbound packets ([`Packet::Ping`], [`Packet::MpcMessage`], /// [`Packet::IndexerHeight`]) to be sent. @@ -130,29 +147,31 @@ struct TlsConnection { /// sending from I/O operations, allowing the application to queue messages without blocking /// on network writes. sender: UnboundedSender, - /// Background task that owns the TLS stream and handles I/O operations. + /// Background task that owns the TLS stream and handles write-only I/O operations. /// - /// This task performs two main responsibilities: - /// 1. **Outbound**: Reads all packet types from the `sender` channel and writes them to - /// the TLS stream - /// 2. **Inbound (Pong only)**: Reads from the TLS stream specifically looking for - /// [`Packet::Pong`] responses to verify the connection is alive. Other packet types - /// are ignored since application messages arrive via the separate incoming connection. - /// - /// The task tracks the last received Pong timestamp and closes the connection if no Pong is - /// received within [`Self::PONG_TIMEOUT`]. When this task is aborted (via [`AutoAbortTask`] - /// drop), it closes the underlying TLS/TCP stream, which triggers [`PersistentConnection`] - /// to reconnect. + /// This task continuously reads packets from the `sender` channel and writes them to the + /// TLS stream. The stream is used unidirectionally - only for sending. Connection health + /// monitoring is handled by a separate watchdog task that cancels the `closed` token when + /// a pong timeout occurs. When this task is aborted (via [`AutoAbortTask`] drop), it closes + /// the underlying TLS/TCP stream, which triggers [`PersistentConnection`] to reconnect. _sender_task: AutoAbortTask<()>, /// Background task that sends periodic Ping heartbeats to detect dead connections. /// /// Every [`Self::PING_INTERVAL`] (1 second), this task sends a Ping packet with an /// incrementing sequence number through the `sender` channel. The peer is expected to - /// respond with a Pong containing the same sequence number. If the `_sender_task` doesn't - /// receive Pong responses within [`Self::PONG_TIMEOUT`] (5 seconds), it considers the - /// connection dead and closes it. This task only sends Pings; Pong validation is handled - /// by `_sender_task`. + /// respond with a Pong containing the same sequence number. The separate watchdog task + /// monitors the shared `pong_state` and closes the connection if no Pong is received within + /// [`Self::PONG_TIMEOUT`] (5 seconds). This task only sends Pings; Pong monitoring is + /// handled by the watchdog task. _keepalive_task: AutoAbortTask<()>, + /// Shared state for tracking Pong responses from the peer. + /// + /// The incoming connection handler updates this state when it receives a [`Packet::Pong`] + /// from this peer. The watchdog task checks this state after sleeping for PONG_TIMEOUT to + /// determine if the connection is still alive. This enables unidirectional I/O: Pongs arrive + /// on our incoming stream but update state monitored by the outgoing watchdog for health + /// tracking. + pong_state: Arc>, /// Token that gets cancelled when the connection closes, allowing waiters to be notified. /// /// Used by [`PersistentConnection`] via the `wait_for_close()` method to block until the @@ -171,6 +190,32 @@ impl Drop for DropToCancel { } } +/// Shared state for tracking Pong responses from a peer, enabling unidirectional I/O streams. +/// +/// This struct enables cross-stream health monitoring in our unidirectional I/O architecture: +/// each TLS connection only writes (outgoing) or only reads (incoming), but health checks +/// require coordination between both directions. +/// +/// **Why it's needed:** +/// - Outgoing connection sends Ping packets and needs to verify the peer is alive +/// - But Pong responses arrive on the separate incoming connection (not on the outgoing stream) +/// - This shared state bridges the gap: incoming handler writes, outgoing watchdog monitors +/// +/// **Context and usage:** +/// 1. **Writer (incoming handler)**: When our incoming connection receives a [`Packet::Pong`] +/// from a peer, it locks this state and updates `last_pong_time` and `last_pong_seq` +/// 2. **Reader (outgoing watchdog task)**: Sleeps for PONG_TIMEOUT and wakes to check if +/// enough time has elapsed without pong, then closes the connection +struct PongState { + /// Timestamp of the most recent Pong received from this peer. Updated by the incoming + /// handler when it receives a Pong packet. Checked by the outgoing watchdog task to + /// detect connection timeouts. + last_pong_time: Instant, + /// Sequence number of the most recent Pong received. Used to ignore duplicate or + /// out-of-order Pong responses and calculate round-trip time. + last_pong_seq: u64, +} + #[derive(BorshSerialize, BorshDeserialize)] enum Packet { Ping(u64), @@ -222,84 +267,69 @@ impl TlsConnection { .context("p2p handshake")?; let (sender, mut receiver) = mpsc::unbounded_channel::(); + let pong_state = Arc::new(std::sync::Mutex::new(PongState { + last_pong_time: Instant::now(), + last_pong_seq: 0, + })); let closed = CancellationToken::new(); let closed_clone = closed.clone(); + let pong_state_clone = pong_state.clone(); + + // Watchdog task that monitors for pong timeouts + let watchdog_cancel = CancellationToken::new(); + let watchdog_cancel_clone = watchdog_cancel.clone(); + let closed_for_watchdog = closed.clone(); + let watchdog_task = tracking::spawn( + &format!("Pong watchdog for {}", target_participant_id), + async move { + loop { + tokio::select! { + _ = tokio::time::sleep(Self::PONG_TIMEOUT) => { + // Timeout - close the connection + let elapsed = { + let state = pong_state_clone.lock().unwrap(); + state.last_pong_time.elapsed() + }; + if elapsed > Self::PONG_TIMEOUT { + tracing::warn!( + "No pong received from {} for {:?}, closing connection", + target_participant_id, + elapsed + ); + closed_for_watchdog.cancel(); + break; + } + } + _ = watchdog_cancel_clone.cancelled() => { + break; + } + } + } + }, + ); + let sender_task = tracking::spawn_checked( &format!("TLS connection to {}", target_participant_id), async move { let _drop_to_cancel = DropToCancel(closed_clone); + let _watchdog_task = watchdog_task; + let _watchdog_cancel = watchdog_cancel; let mut sent_bytes: u64 = 0; - let mut received_bytes: u64 = 0; - let mut last_pong_time = Instant::now(); - let mut last_pong_seq: u64 = 0; loop { - // Check if we've timed out waiting for pong - if last_pong_time.elapsed() > Self::PONG_TIMEOUT { - tracing::warn!( - "No pong received from {} for {:?}, closing connection", - target_participant_id, - last_pong_time.elapsed() - ); - break; - } - - tokio::select! { - data = receiver.recv() => { - let Some(data) = data else { - break; - }; + match receiver.recv().await { + Some(data) => { let serialized = borsh::to_vec(&data)?; - let len: u32 = serialized.len().try_into().context("Message too long")?; + let len: u32 = + serialized.len().try_into().context("Message too long")?; tls_conn.write_u32(len).await?; tls_conn.write_all(&serialized).await?; sent_bytes += 4 + len as u64; tracking::set_progress(&format!("Sent {} bytes", sent_bytes)); } - result = tokio::time::timeout( - std::time::Duration::from_millis(100), - async { - let len = tls_conn.read_u32().await?; - if len >= MAX_MESSAGE_LEN { - anyhow::bail!("Message too long"); - } - let mut buf = vec![0; len as usize]; - tls_conn.read_exact(&mut buf).await?; - received_bytes += 4 + len as u64; - - let packet = Packet::try_from_slice(&buf) - .context("Failed to deserialize packet")?; - anyhow::Ok(packet) - } - ) => { - match result { - Ok(Ok(Packet::Pong(seq))) => { - if seq > last_pong_seq { - last_pong_seq = seq; - let elapsed = last_pong_time.elapsed(); - last_pong_time = Instant::now(); - tracking::set_progress(&format!( - "Received pong {} from {}, RTT: {:?}", - seq, - target_participant_id, - elapsed - )); - } - } - Ok(Ok(_)) => { - tracing::warn!( - "Received unexpected packet type from {} on outgoing connection", - target_participant_id - ); - } - Ok(Err(e)) => { - tracing::warn!("Error reading from connection: {}", e); - break; - } - Err(_) => { - // Timeout is expected when no data is available - } - } + None => { + // Channel closed + break; } } } @@ -326,6 +356,7 @@ impl TlsConnection { sender, _sender_task: sender_task, _keepalive_task: keepalive_task, + pong_state, closed, }) } @@ -497,6 +528,7 @@ pub async fn new_tls_mesh_network( let connectivities_clone = connectivities.clone(); let my_id = config.my_participant_id; + let connections_for_incoming = connections.clone(); info!("Spawning incoming connections handler."); let incoming_connections_task = tracking::spawn("Handle incoming connections", async move { let mut tasks = AutoAbortTaskCollection::new(); @@ -505,6 +537,7 @@ pub async fn new_tls_mesh_network( let participant_identities = participant_identities.clone(); let tls_acceptor = tls_acceptor.clone(); let connectivities = connectivities_clone.clone(); + let connections = connections_for_incoming.clone(); tasks.spawn_checked::<_, ()>("Handle connection", async move { let mut stream = tls_acceptor.accept(tcp_stream).await?; let peer_id = verify_peer_identity(stream.get_ref().1, &participant_identities)?; @@ -539,18 +572,33 @@ pub async fn new_tls_mesh_network( Packet::try_from_slice(&buf).context("Failed to deserialize packet")?; match packet { Packet::Ping(seq) => { - // Respond with Pong to echo the sequence number back - let pong = borsh::to_vec(&Packet::Pong(seq))?; - let len: u32 = pong.len().try_into().context("Message too long")?; - stream.write_u32(len).await?; - stream.write_all(&pong).await?; + // Send Pong via our outgoing connection to the peer + if let Some(conn) = connections.get(&peer_id) { + if let Some(outgoing_conn) = + conn.connectivity.any_outgoing_connection() + { + let _ = outgoing_conn.sender.send(Packet::Pong(seq)); + } + } } - Packet::Pong(_) => { - // Pong messages should not be received on incoming connections - tracing::warn!( - "Received unexpected Pong from {} on incoming connection", - peer_id - ); + Packet::Pong(seq) => { + // Update the outgoing connection's pong state directly + if let Some(conn) = connections.get(&peer_id) { + if let Some(outgoing_conn) = + conn.connectivity.any_outgoing_connection() + { + let mut state = outgoing_conn.pong_state.lock().unwrap(); + if seq > state.last_pong_seq { + let elapsed = state.last_pong_time.elapsed(); + state.last_pong_seq = seq; + state.last_pong_time = Instant::now(); + tracking::set_progress(&format!( + "Received pong {} from {}, RTT: {:?}", + seq, peer_id, elapsed + )); + } + } + } } Packet::MpcMessage(mpc_message) => { message_sender.send(PeerMessage::Mpc(MpcPeerMessage { From 081fce59655ee930efcfccfc84d03163c8d6253d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Fri, 19 Dec 2025 12:56:04 +0100 Subject: [PATCH 04/45] Fix clippy --- crates/node/src/p2p.rs | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index cfbd6f1540..d5ff942684 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -87,7 +87,8 @@ pub struct TlsMeshReceiver { /// 4) On Ping: Sends Pong via our outgoing connection to maintain unidirectional I/O /// 5) On Pong: Updates the outgoing connection's pong_state directly for health tracking /// 6) Forwards MpcMessage and IndexerHeight to the unified `receiver` channel - /// The `AutoAbortTask` wrapper ensures automatic cleanup on drop. + /// + /// The [`AutoAbortTask`] wrapper ensures automatic cleanup on drop. _incoming_connections_task: AutoAbortTask<()>, } @@ -315,23 +316,14 @@ impl TlsConnection { let _watchdog_task = watchdog_task; let _watchdog_cancel = watchdog_cancel; let mut sent_bytes: u64 = 0; - loop { - match receiver.recv().await { - Some(data) => { - let serialized = borsh::to_vec(&data)?; - let len: u32 = - serialized.len().try_into().context("Message too long")?; - tls_conn.write_u32(len).await?; - tls_conn.write_all(&serialized).await?; - sent_bytes += 4 + len as u64; - - tracking::set_progress(&format!("Sent {} bytes", sent_bytes)); - } - None => { - // Channel closed - break; - } - } + while let Some(data) = receiver.recv().await { + let serialized = borsh::to_vec(&data)?; + let len: u32 = serialized.len().try_into().context("Message too long")?; + tls_conn.write_u32(len).await?; + tls_conn.write_all(&serialized).await?; + sent_bytes += 4 + len as u64; + + tracking::set_progress(&format!("Sent {} bytes", sent_bytes)); } anyhow::Ok(()) }, From ab7b91d0854f80846c5451f7e962cd57837a7eeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Fri, 19 Dec 2025 15:36:53 +0100 Subject: [PATCH 05/45] Fixes --- crates/node/src/p2p.rs | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index d5ff942684..4804c118a8 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -316,14 +316,29 @@ impl TlsConnection { let _watchdog_task = watchdog_task; let _watchdog_cancel = watchdog_cancel; let mut sent_bytes: u64 = 0; - while let Some(data) = receiver.recv().await { - let serialized = borsh::to_vec(&data)?; - let len: u32 = serialized.len().try_into().context("Message too long")?; - tls_conn.write_u32(len).await?; - tls_conn.write_all(&serialized).await?; - sent_bytes += 4 + len as u64; - - tracking::set_progress(&format!("Sent {} bytes", sent_bytes)); + loop { + tokio::select! { + data = receiver.recv() => { + let Some(data) = data else { + break; + }; + let serialized = borsh::to_vec(&data)?; + let len: u32 = serialized.len().try_into().context("Message too long")?; + tls_conn.write_u32(len).await?; + tls_conn.write_all(&serialized).await?; + sent_bytes += 4 + len as u64; + + tracking::set_progress(&format!("Sent {} bytes", sent_bytes)); + } + _ = tls_conn.read_u8() => { + // We do not expect any data from the other side. However, + // selecting on it will quickly return error if the connection + // is broken before we have data to send. That way we can + // immediately quit the loop as soon as the connection is broken + // (so we can reconnect). + break; + } + } } anyhow::Ok(()) }, @@ -582,6 +597,13 @@ pub async fn new_tls_mesh_network( let mut state = outgoing_conn.pong_state.lock().unwrap(); if seq > state.last_pong_seq { let elapsed = state.last_pong_time.elapsed(); + let expected_seq = state.last_pong_seq + 1; + if seq != expected_seq { + tracing::warn!( + "Received pong {} from {}, expected {}, lost {} pong(s)", + seq, peer_id, expected_seq, seq - expected_seq + ); + } state.last_pong_seq = seq; state.last_pong_time = Instant::now(); tracking::set_progress(&format!( From bbdcc29c9e366c4958d89005a75840ea07d7b621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Fri, 19 Dec 2025 19:16:04 +0100 Subject: [PATCH 06/45] Address Copilot's code review --- crates/node/src/p2p.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 4804c118a8..abe93a165f 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -584,7 +584,13 @@ pub async fn new_tls_mesh_network( if let Some(outgoing_conn) = conn.connectivity.any_outgoing_connection() { - let _ = outgoing_conn.sender.send(Packet::Pong(seq)); + if outgoing_conn.sender.send(Packet::Pong(seq)).is_err() { + tracing::info!( + "Outgoing connection to {} is dead, closing incoming connection for clean reconnect", + peer_id + ); + break; + } } } } @@ -635,6 +641,7 @@ pub async fn new_tls_mesh_network( received_bytes, peer_id )); } + anyhow::Ok(()) }); } }); From 47f630b3a91a8e1fa17e41e1d9ecd5cade2c1912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Mon, 22 Dec 2025 13:47:58 +0100 Subject: [PATCH 07/45] simplify --- crates/node/src/p2p.rs | 54 ++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index abe93a165f..554dfb4196 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -274,47 +274,11 @@ impl TlsConnection { })); let closed = CancellationToken::new(); let closed_clone = closed.clone(); - let pong_state_clone = pong_state.clone(); - - // Watchdog task that monitors for pong timeouts - let watchdog_cancel = CancellationToken::new(); - let watchdog_cancel_clone = watchdog_cancel.clone(); - let closed_for_watchdog = closed.clone(); - let watchdog_task = tracking::spawn( - &format!("Pong watchdog for {}", target_participant_id), - async move { - loop { - tokio::select! { - _ = tokio::time::sleep(Self::PONG_TIMEOUT) => { - // Timeout - close the connection - let elapsed = { - let state = pong_state_clone.lock().unwrap(); - state.last_pong_time.elapsed() - }; - if elapsed > Self::PONG_TIMEOUT { - tracing::warn!( - "No pong received from {} for {:?}, closing connection", - target_participant_id, - elapsed - ); - closed_for_watchdog.cancel(); - break; - } - } - _ = watchdog_cancel_clone.cancelled() => { - break; - } - } - } - }, - ); let sender_task = tracking::spawn_checked( &format!("TLS connection to {}", target_participant_id), async move { let _drop_to_cancel = DropToCancel(closed_clone); - let _watchdog_task = watchdog_task; - let _watchdog_cancel = watchdog_cancel; let mut sent_bytes: u64 = 0; loop { tokio::select! { @@ -344,12 +308,30 @@ impl TlsConnection { }, ); let sender_clone = sender.clone(); + let pong_state_clone = pong_state.clone(); + let closed_for_keepalive = closed.clone(); let keepalive_task = tracking::spawn( &format!("Ping sender for {}", target_participant_id), async move { let mut seq: u64 = 0; loop { tokio::time::sleep(Self::PING_INTERVAL).await; + + // Check for pong timeout + let elapsed = { + let state = pong_state_clone.lock().unwrap(); + state.last_pong_time.elapsed() + }; + if elapsed > Self::PONG_TIMEOUT { + tracing::warn!( + "No pong received from {} for {:?}, closing connection", + target_participant_id, + elapsed + ); + closed_for_keepalive.cancel(); + break; + } + seq += 1; if sender_clone.send(Packet::Ping(seq)).is_err() { // The receiver side will be dropped when the sender task is From 615a040ed62f3b269559d86a04193d49a9238471 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Mon, 22 Dec 2025 15:18:35 +0100 Subject: [PATCH 08/45] fixup! simplify --- crates/node/src/p2p.rs | 155 +++++++++++++++++------------------------ 1 file changed, 65 insertions(+), 90 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 554dfb4196..3ad35fb78e 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -38,9 +38,8 @@ use crate::{ /// This struct manages **outgoing connections only** - one persistent TLS connection to each /// peer in the network. When the application wants to send a message to a peer, it queues the /// message through the corresponding [`PersistentConnection`], which handles automatic -/// reconnection if the connection drops. Each connection runs three background tasks: one for -/// sending data, one for sending periodic ping heartbeats, and one watchdog for monitoring pong -/// timeouts. +/// reconnection if the connection drops. Each connection runs two background tasks: one for +/// sending data, and one for sending periodic ping heartbeats and monitoring pong responses. /// /// Implements the [`MeshNetworkTransportSender`] trait to provide a high-level API for sending /// messages (`.send()`, `.send_indexer_height()`) and checking connectivity status @@ -70,7 +69,7 @@ pub struct TlsMeshSender { /// /// Ping/Pong handling uses cross-stream communication to maintain unidirectional I/O: when /// receiving a Ping, this handler sends Pong via the outgoing connection to that peer; when -/// receiving a Pong, it updates the outgoing connection's shared pong_state for health monitoring. +/// receiving a Pong, it notifies the outgoing connection's keepalive task via a watch channel. /// /// Implements [`MeshNetworkTransportReceiver`] to receive messages from all peers in the /// mesh network. @@ -85,7 +84,7 @@ pub struct TlsMeshReceiver { /// 2) Registers the connection with `connectivities` for bidirectional tracking /// 3) Reads messages from the peer in a loop (read-only stream usage) /// 4) On Ping: Sends Pong via our outgoing connection to maintain unidirectional I/O - /// 5) On Pong: Updates the outgoing connection's pong_state directly for health tracking + /// 5) On Pong: Notifies the outgoing connection's keepalive task via watch channel /// 6) Forwards MpcMessage and IndexerHeight to the unified `receiver` channel /// /// The [`AutoAbortTask`] wrapper ensures automatic cleanup on drop. @@ -136,8 +135,8 @@ struct PersistentConnection { /// It uses **unidirectional I/O** - the TLS stream is write-only from this connection's /// perspective. When you want to send a message to a peer, you queue it through the `sender` /// channel, and the background `_sender_task` reads from the channel and writes to the TLS -/// stream. Pong responses arrive via the separate incoming connection and update the shared -/// `pong_state` for health monitoring. +/// stream. Pong responses arrive via the separate incoming connection and are forwarded to +/// the keepalive task via the `pong_tx` watch channel for health monitoring. struct TlsConnection { /// Channel for queuing outbound packets ([`Packet::Ping`], [`Packet::MpcMessage`], /// [`Packet::IndexerHeight`]) to be sent. @@ -152,27 +151,25 @@ struct TlsConnection { /// /// This task continuously reads packets from the `sender` channel and writes them to the /// TLS stream. The stream is used unidirectionally - only for sending. Connection health - /// monitoring is handled by a separate watchdog task that cancels the `closed` token when + /// monitoring is handled by the keepalive task which cancels the `closed` token when /// a pong timeout occurs. When this task is aborted (via [`AutoAbortTask`] drop), it closes /// the underlying TLS/TCP stream, which triggers [`PersistentConnection`] to reconnect. _sender_task: AutoAbortTask<()>, - /// Background task that sends periodic Ping heartbeats to detect dead connections. + /// Background task that sends Ping heartbeats and monitors Pong responses. /// - /// Every [`Self::PING_INTERVAL`] (1 second), this task sends a Ping packet with an - /// incrementing sequence number through the `sender` channel. The peer is expected to - /// respond with a Pong containing the same sequence number. The separate watchdog task - /// monitors the shared `pong_state` and closes the connection if no Pong is received within - /// [`Self::PONG_TIMEOUT`] (5 seconds). This task only sends Pings; Pong monitoring is - /// handled by the watchdog task. + /// Unlike classical ping which sends at fixed intervals, this task sends a Ping with an + /// incrementing sequence number and then waits for either a Pong response (via the `pong_tx` + /// watch channel) or a timeout. When a Pong is received, it validates the sequence number, + /// calculates RTT, and immediately sends the next Ping. If no Pong is received within + /// [`Self::PONG_TIMEOUT`] (5 seconds), it closes the connection by cancelling the `closed` + /// token. This approach ensures pings are only sent when the connection is responsive. _keepalive_task: AutoAbortTask<()>, - /// Shared state for tracking Pong responses from the peer. + /// Watch channel sender for receiving pong notifications from the incoming connection handler. /// - /// The incoming connection handler updates this state when it receives a [`Packet::Pong`] - /// from this peer. The watchdog task checks this state after sleeping for PONG_TIMEOUT to - /// determine if the connection is still alive. This enables unidirectional I/O: Pongs arrive - /// on our incoming stream but update state monitored by the outgoing watchdog for health - /// tracking. - pong_state: Arc>, + /// The incoming handler sends PongInfo when it receives a Pong packet. The keepalive task + /// monitors this channel to detect connection health and calculate RTT. This enables clean + /// async communication without mutexes. + pong_tx: tokio::sync::watch::Sender, /// Token that gets cancelled when the connection closes, allowing waiters to be notified. /// /// Used by [`PersistentConnection`] via the `wait_for_close()` method to block until the @@ -191,30 +188,12 @@ impl Drop for DropToCancel { } } -/// Shared state for tracking Pong responses from a peer, enabling unidirectional I/O streams. -/// -/// This struct enables cross-stream health monitoring in our unidirectional I/O architecture: -/// each TLS connection only writes (outgoing) or only reads (incoming), but health checks -/// require coordination between both directions. -/// -/// **Why it's needed:** -/// - Outgoing connection sends Ping packets and needs to verify the peer is alive -/// - But Pong responses arrive on the separate incoming connection (not on the outgoing stream) -/// - This shared state bridges the gap: incoming handler writes, outgoing watchdog monitors -/// -/// **Context and usage:** -/// 1. **Writer (incoming handler)**: When our incoming connection receives a [`Packet::Pong`] -/// from a peer, it locks this state and updates `last_pong_time` and `last_pong_seq` -/// 2. **Reader (outgoing watchdog task)**: Sleeps for PONG_TIMEOUT and wakes to check if -/// enough time has elapsed without pong, then closes the connection -struct PongState { - /// Timestamp of the most recent Pong received from this peer. Updated by the incoming - /// handler when it receives a Pong packet. Checked by the outgoing watchdog task to - /// detect connection timeouts. - last_pong_time: Instant, - /// Sequence number of the most recent Pong received. Used to ignore duplicate or - /// out-of-order Pong responses and calculate round-trip time. - last_pong_seq: u64, +/// Information about the last received pong, sent via watch channel from incoming handler +/// to keepalive task for health monitoring. +#[derive(Clone, Copy)] +struct PongInfo { + /// Sequence number of the most recent Pong received. + seq: u64, } #[derive(BorshSerialize, BorshDeserialize)] @@ -230,9 +209,6 @@ impl TlsConnection { /// the connection is considered not successful. const HANDSHAKE_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(2); - /// Interval between ping messages. - const PING_INTERVAL: std::time::Duration = std::time::Duration::from_secs(1); - /// If we don't receive a pong response within this time, consider the connection dead. const PONG_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5); @@ -268,10 +244,7 @@ impl TlsConnection { .context("p2p handshake")?; let (sender, mut receiver) = mpsc::unbounded_channel::(); - let pong_state = Arc::new(std::sync::Mutex::new(PongState { - last_pong_time: Instant::now(), - last_pong_seq: 0, - })); + let (pong_tx, mut pong_rx) = tokio::sync::watch::channel(PongInfo { seq: 0 }); let closed = CancellationToken::new(); let closed_clone = closed.clone(); @@ -308,36 +281,53 @@ impl TlsConnection { }, ); let sender_clone = sender.clone(); - let pong_state_clone = pong_state.clone(); let closed_for_keepalive = closed.clone(); let keepalive_task = tracking::spawn( &format!("Ping sender for {}", target_participant_id), async move { let mut seq: u64 = 0; + let mut last_received_pong_seq: u64 = 0; loop { - tokio::time::sleep(Self::PING_INTERVAL).await; - - // Check for pong timeout - let elapsed = { - let state = pong_state_clone.lock().unwrap(); - state.last_pong_time.elapsed() - }; - if elapsed > Self::PONG_TIMEOUT { - tracing::warn!( - "No pong received from {} for {:?}, closing connection", - target_participant_id, - elapsed - ); - closed_for_keepalive.cancel(); - break; - } - seq += 1; + let ping_sent_at = Instant::now(); if sender_clone.send(Packet::Ping(seq)).is_err() { // The receiver side will be dropped when the sender task is // dropped (i.e. connection is closed). break; } + + // Wait for either a pong response or timeout + tokio::select! { + _ = pong_rx.changed() => { + // Pong received, validate and calculate RTT + let pong_info = pong_rx.borrow(); + if pong_info.seq > last_received_pong_seq { + let expected_seq = last_received_pong_seq + 1; + if pong_info.seq != expected_seq { + tracing::warn!( + "Received pong {} from {}, expected {}, lost {} pong(s)", + pong_info.seq, target_participant_id, expected_seq, pong_info.seq - expected_seq + ); + } + last_received_pong_seq = pong_info.seq; + let rtt = ping_sent_at.elapsed(); + tracking::set_progress(&format!( + "Received pong {} from {}, RTT: {:?}", + pong_info.seq, target_participant_id, rtt + )); + } + continue; + } + _ = tokio::time::sleep(Self::PONG_TIMEOUT) => { + tracing::warn!( + "No pong received from {} for {:?}, closing connection", + target_participant_id, + Self::PONG_TIMEOUT + ); + closed_for_keepalive.cancel(); + break; + } + } } }, ); @@ -345,7 +335,7 @@ impl TlsConnection { sender, _sender_task: sender_task, _keepalive_task: keepalive_task, - pong_state, + pong_tx, closed, }) } @@ -577,28 +567,13 @@ pub async fn new_tls_mesh_network( } } Packet::Pong(seq) => { - // Update the outgoing connection's pong state directly + // Notify the keepalive task of the pong via the watch channel if let Some(conn) = connections.get(&peer_id) { if let Some(outgoing_conn) = conn.connectivity.any_outgoing_connection() { - let mut state = outgoing_conn.pong_state.lock().unwrap(); - if seq > state.last_pong_seq { - let elapsed = state.last_pong_time.elapsed(); - let expected_seq = state.last_pong_seq + 1; - if seq != expected_seq { - tracing::warn!( - "Received pong {} from {}, expected {}, lost {} pong(s)", - seq, peer_id, expected_seq, seq - expected_seq - ); - } - state.last_pong_seq = seq; - state.last_pong_time = Instant::now(); - tracking::set_progress(&format!( - "Received pong {} from {}, RTT: {:?}", - seq, peer_id, elapsed - )); - } + // Send the new pong info via watch channel + let _ = outgoing_conn.pong_tx.send(PongInfo { seq }); } } } From cd9ffb5fdddb5fa3cfeb8ed5fc0eb688357eb58b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Mon, 22 Dec 2025 15:22:04 +0100 Subject: [PATCH 09/45] fixup! fixup! simplify --- crates/node/src/p2p.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 3ad35fb78e..0f7ed1b290 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -315,6 +315,11 @@ impl TlsConnection { "Received pong {} from {}, RTT: {:?}", pong_info.seq, target_participant_id, rtt )); + } else { + tracing::warn!( + "Received stale pong {} from {}, already received {}", + pong_info.seq, target_participant_id, last_received_pong_seq + ); } continue; } From e85ca872feeed5eef72623ba02adcce57272fa4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Mon, 22 Dec 2025 18:05:40 +0100 Subject: [PATCH 10/45] fixup! fixup! fixup! simplify --- crates/node/src/p2p.rs | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 0f7ed1b290..4646e5cf04 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -39,7 +39,7 @@ use crate::{ /// peer in the network. When the application wants to send a message to a peer, it queues the /// message through the corresponding [`PersistentConnection`], which handles automatic /// reconnection if the connection drops. Each connection runs two background tasks: one for -/// sending data, and one for sending periodic ping heartbeats and monitoring pong responses. +/// sending data, and one for sending 1-second interval ping heartbeats and monitoring pong responses. /// /// Implements the [`MeshNetworkTransportSender`] trait to provide a high-level API for sending /// messages (`.send()`, `.send_indexer_height()`) and checking connectivity status @@ -157,12 +157,13 @@ struct TlsConnection { _sender_task: AutoAbortTask<()>, /// Background task that sends Ping heartbeats and monitors Pong responses. /// - /// Unlike classical ping which sends at fixed intervals, this task sends a Ping with an - /// incrementing sequence number and then waits for either a Pong response (via the `pong_tx` - /// watch channel) or a timeout. When a Pong is received, it validates the sequence number, - /// calculates RTT, and immediately sends the next Ping. If no Pong is received within - /// [`Self::PONG_TIMEOUT`] (5 seconds), it closes the connection by cancelling the `closed` - /// token. This approach ensures pings are only sent when the connection is responsive. + /// This task sends a Ping with an incrementing sequence number and then waits for either a + /// Pong response (via the `pong_tx` watch channel) or a timeout. When a Pong is received, + /// it validates the sequence number, calculates RTT, and waits until [`Self::PING_INTERVAL`] + /// (1 second) has elapsed since the ping was sent before sending the next one. If no Pong is + /// received within [`Self::PONG_TIMEOUT`] (5 seconds), it closes the connection by cancelling + /// the `closed` token. This ensures pings are sent at exactly 1-second intervals while only + /// sending when the previous ping received a response. _keepalive_task: AutoAbortTask<()>, /// Watch channel sender for receiving pong notifications from the incoming connection handler. /// @@ -212,6 +213,10 @@ impl TlsConnection { /// If we don't receive a pong response within this time, consider the connection dead. const PONG_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5); + /// Interval between consecutive pings. A new ping is sent 1 second after the previous + /// ping was sent, but only after receiving its pong response. + const PING_INTERVAL: std::time::Duration = std::time::Duration::from_secs(1); + /// Makes a TLS/TCP connection to the given address, authenticating the /// other side as the given participant. async fn new( @@ -300,7 +305,7 @@ impl TlsConnection { tokio::select! { _ = pong_rx.changed() => { // Pong received, validate and calculate RTT - let pong_info = pong_rx.borrow(); + let pong_info = *pong_rx.borrow_and_update(); if pong_info.seq > last_received_pong_seq { let expected_seq = last_received_pong_seq + 1; if pong_info.seq != expected_seq { @@ -316,12 +321,16 @@ impl TlsConnection { pong_info.seq, target_participant_id, rtt )); } else { - tracing::warn!( + tracing::debug!( "Received stale pong {} from {}, already received {}", pong_info.seq, target_participant_id, last_received_pong_seq ); } - continue; + // Wait until PING_INTERVAL has elapsed since ping was sent + let elapsed = ping_sent_at.elapsed(); + if elapsed < Self::PING_INTERVAL { + tokio::time::sleep(Self::PING_INTERVAL - elapsed).await; + } } _ = tokio::time::sleep(Self::PONG_TIMEOUT) => { tracing::warn!( @@ -413,7 +422,7 @@ impl PersistentConnection { my_id, target_participant_id ); - new_conn + Arc::new(new_conn) } Err(e) => { tracing::info!( @@ -428,7 +437,6 @@ impl PersistentConnection { continue; } }; - let new_conn = Arc::new(new_conn); connectivity.set_outgoing_connection(&new_conn); new_conn.wait_for_close().await; } @@ -579,7 +587,11 @@ pub async fn new_tls_mesh_network( { // Send the new pong info via watch channel let _ = outgoing_conn.pong_tx.send(PongInfo { seq }); + } else { + tracing::warn!("No outgoing connection to {} to forward Pong({})", peer_id, seq); } + } else { + tracing::warn!("No connection found for peer {} to forward Pong({})", peer_id, seq); } } Packet::MpcMessage(mpc_message) => { From d047c9a243217bca2aae55961cd2cb1b4c56c1e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Mon, 22 Dec 2025 20:20:55 +0100 Subject: [PATCH 11/45] skip test_parallel_sign_calls for now --- pytest/tests/robust_ecdsa/test_parallel_sign_calls.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pytest/tests/robust_ecdsa/test_parallel_sign_calls.py b/pytest/tests/robust_ecdsa/test_parallel_sign_calls.py index 88509cf8fe..1e4b71ef01 100644 --- a/pytest/tests/robust_ecdsa/test_parallel_sign_calls.py +++ b/pytest/tests/robust_ecdsa/test_parallel_sign_calls.py @@ -19,6 +19,7 @@ @pytest.mark.parametrize("num_parallel_requests", [3]) @pytest.mark.no_atexit_cleanup +@pytest.mark.skip def test_parallel_sign_calls( compile_parallel_contract, num_parallel_requests, shared_cluster: shared.MpcCluster ): From b026830d2a261ff14cb5ec2a8147540d4cbc909d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Tue, 23 Dec 2025 11:41:52 +0100 Subject: [PATCH 12/45] Implement Pong buffering in PersistentConnection for improved connection handling --- crates/node/src/p2p.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 4646e5cf04..b4e3b76ab7 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -113,6 +113,8 @@ struct ParticipantIdentities { struct PersistentConnection { target_participant_id: ParticipantId, connectivity: Arc>, + /// Channel for buffering Pongs when outgoing connection is temporarily unavailable. + pong_buffer: UnboundedSender, /// Background reconnection task that maintains the connection lifecycle. /// /// This task runs an infinite loop that: @@ -404,6 +406,7 @@ impl PersistentConnection { connectivity: Arc>, ) -> anyhow::Result { let connectivity_clone = connectivity.clone(); + let (pong_buffer_tx, mut pong_buffer_rx) = mpsc::unbounded_channel::(); let task = tracking::spawn( &format!("Persistent connection to {}", target_participant_id), async move { @@ -438,6 +441,12 @@ impl PersistentConnection { } }; connectivity.set_outgoing_connection(&new_conn); + + // Drain buffered Pongs and send them now that connection is available + while let Ok(seq) = pong_buffer_rx.try_recv() { + let _ = new_conn.sender.send(Packet::Pong(seq)); + } + new_conn.wait_for_close().await; } }, @@ -445,6 +454,7 @@ impl PersistentConnection { Ok(PersistentConnection { target_participant_id, connectivity: connectivity_clone, + pong_buffer: pong_buffer_tx, _task: task, }) } @@ -564,7 +574,8 @@ pub async fn new_tls_mesh_network( Packet::try_from_slice(&buf).context("Failed to deserialize packet")?; match packet { Packet::Ping(seq) => { - // Send Pong via our outgoing connection to the peer + // Send Pong via our outgoing connection to the peer, maintaining + // unidirectional I/O design. If outgoing isn't ready, buffer the Pong. if let Some(conn) = connections.get(&peer_id) { if let Some(outgoing_conn) = conn.connectivity.any_outgoing_connection() @@ -576,7 +587,20 @@ pub async fn new_tls_mesh_network( ); break; } + } else { + // Outgoing connection not ready yet, buffer the Pong + if conn.pong_buffer.send(seq).is_err() { + tracing::warn!( + "Cannot buffer Pong({}) for {}: pong buffer channel closed", + seq, peer_id + ); + } } + } else { + tracing::warn!( + "Cannot send Pong({}) to {}: connection not found in HashMap", + seq, peer_id + ); } } Packet::Pong(seq) => { From ff536cd48ebae9f1fedbf178884fe17eae3051d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Tue, 23 Dec 2025 12:38:04 +0100 Subject: [PATCH 13/45] fix clippy --- crates/node/src/p2p.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index b4e3b76ab7..671709ec78 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -441,12 +441,12 @@ impl PersistentConnection { } }; connectivity.set_outgoing_connection(&new_conn); - + // Drain buffered Pongs and send them now that connection is available while let Ok(seq) = pong_buffer_rx.try_recv() { let _ = new_conn.sender.send(Packet::Pong(seq)); } - + new_conn.wait_for_close().await; } }, From d4fd604dd2a9a4c86f8426f9e928e62e606066f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Tue, 23 Dec 2025 12:38:27 +0100 Subject: [PATCH 14/45] Revert "skip test_parallel_sign_calls for now" This reverts commit d047c9a243217bca2aae55961cd2cb1b4c56c1e1. --- pytest/tests/robust_ecdsa/test_parallel_sign_calls.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pytest/tests/robust_ecdsa/test_parallel_sign_calls.py b/pytest/tests/robust_ecdsa/test_parallel_sign_calls.py index 1e4b71ef01..88509cf8fe 100644 --- a/pytest/tests/robust_ecdsa/test_parallel_sign_calls.py +++ b/pytest/tests/robust_ecdsa/test_parallel_sign_calls.py @@ -19,7 +19,6 @@ @pytest.mark.parametrize("num_parallel_requests", [3]) @pytest.mark.no_atexit_cleanup -@pytest.mark.skip def test_parallel_sign_calls( compile_parallel_contract, num_parallel_requests, shared_cluster: shared.MpcCluster ): From 430dc767f91623998ab51f57cb5610455513d734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Mon, 5 Jan 2026 10:54:56 +0100 Subject: [PATCH 15/45] Bump PONG_TIMEOUT to 20 seconds --- crates/node/src/p2p.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 671709ec78..43b46ee542 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -213,7 +213,7 @@ impl TlsConnection { const HANDSHAKE_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(2); /// If we don't receive a pong response within this time, consider the connection dead. - const PONG_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5); + const PONG_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(20); /// Interval between consecutive pings. A new ping is sent 1 second after the previous /// ping was sent, but only after receiving its pong response. From b8490a8291bc341249adf31f98b74fbbd9a40cc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Mon, 5 Jan 2026 13:42:19 +0100 Subject: [PATCH 16/45] Update docstrings --- crates/node/src/p2p.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 43b46ee542..20d66ac773 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -160,10 +160,10 @@ struct TlsConnection { /// Background task that sends Ping heartbeats and monitors Pong responses. /// /// This task sends a Ping with an incrementing sequence number and then waits for either a - /// Pong response (via the `pong_tx` watch channel) or a timeout. When a Pong is received, + /// Pong response (via the `pong_rx` watch channel) or a timeout. When a Pong is received, /// it validates the sequence number, calculates RTT, and waits until [`Self::PING_INTERVAL`] /// (1 second) has elapsed since the ping was sent before sending the next one. If no Pong is - /// received within [`Self::PONG_TIMEOUT`] (5 seconds), it closes the connection by cancelling + /// received within [`Self::PONG_TIMEOUT`] (20 seconds), it closes the connection by cancelling /// the `closed` token. This ensures pings are sent at exactly 1-second intervals while only /// sending when the previous ping received a response. _keepalive_task: AutoAbortTask<()>, From 22bb772d71cd4d20d82cd7834eb9851ef79a7cbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Mon, 5 Jan 2026 16:33:21 +0100 Subject: [PATCH 17/45] Code cleanup --- crates/node/src/p2p.rs | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 98b94a8d3f..1c1562ea74 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -414,49 +414,46 @@ impl PersistentConnection { participant_identities: Arc, connectivity: Arc>, ) -> anyhow::Result { - let connectivity_clone = connectivity.clone(); + let connectivity_clone = Arc::clone(&connectivity); let (pong_buffer_tx, mut pong_buffer_rx) = mpsc::unbounded_channel::(); let task = tracking::spawn( &format!("Persistent connection to {}", target_participant_id), async move { loop { - let new_conn = match TlsConnection::new( - client_config.clone(), + match TlsConnection::new( + Arc::clone(&client_config), &target_address, target_participant_id, &participant_identities, ) .await { - Ok(new_conn) => { + Ok(conn) => { + let new_conn = Arc::new(conn); tracing::info!( "Outgoing {} --> {} connected", my_id, target_participant_id ); - Arc::new(new_conn) + + // Register connection and drain any buffered Pongs + connectivity.set_outgoing_connection(&new_conn); + while let Ok(seq) = pong_buffer_rx.try_recv() { + let _ = new_conn.sender.send(Packet::Pong(seq)); + } + + new_conn.wait_for_close().await; } Err(e) => { - tracing::info!( - "Could not connect to {}, retrying: {}, me {}", + tracing::warn!( + "Could not connect to {}: {:#}, retrying (me: {})", target_participant_id, e, my_id ); - // Don't immediately retry, to avoid spamming the network with - // connection attempts. tokio::time::sleep(Self::CONNECTION_RETRY_DELAY).await; - continue; } - }; - connectivity.set_outgoing_connection(&new_conn); - - // Drain buffered Pongs and send them now that connection is available - while let Ok(seq) = pong_buffer_rx.try_recv() { - let _ = new_conn.sender.send(Packet::Pong(seq)); } - - new_conn.wait_for_close().await; } }, ); From 4a14196df34978ad8a111931fda8d7ef46755b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Wed, 7 Jan 2026 14:17:46 +0100 Subject: [PATCH 18/45] refactor: replace pong buffer with watch channel for pending pongs --- crates/node/src/p2p.rs | 60 ++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 1c1562ea74..f4066e0860 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -12,7 +12,10 @@ use std::{ use tokio::{ io::{AsyncReadExt, AsyncWriteExt}, net::{TcpListener, TcpStream}, - sync::mpsc::{self, UnboundedReceiver, UnboundedSender}, + sync::{ + mpsc::{self, UnboundedReceiver, UnboundedSender}, + watch, + }, }; use tokio_rustls::TlsAcceptor; use tokio_util::sync::CancellationToken; @@ -73,8 +76,9 @@ pub struct TlsMeshSender { /// MPC/IndexerHeight messages to the unified receiver channel. /// /// Ping/Pong handling uses cross-stream communication to maintain unidirectional I/O: when -/// receiving a Ping, this handler sends Pong via the outgoing connection to that peer; when -/// receiving a Pong, it notifies the outgoing connection's keepalive task via a watch channel. +/// receiving a Ping, this handler sends Pong via the outgoing connection to that peer (or +/// buffers it if the outgoing connection isn't ready yet); when receiving a Pong, it notifies +/// the outgoing connection's keepalive task via a watch channel. /// /// Implements [`MeshNetworkTransportReceiver`] to receive messages from all peers in the /// mesh network. @@ -88,7 +92,8 @@ pub struct TlsMeshReceiver { /// 1) Performs TLS handshake and authenticates the peer's identity /// 2) Registers the connection with `connectivities` for bidirectional tracking /// 3) Reads messages from the peer in a loop (read-only stream usage) - /// 4) On Ping: Sends Pong via our outgoing connection to maintain unidirectional I/O + /// 4) On Ping: Sends Pong via our outgoing connection to maintain unidirectional I/O; + /// if outgoing connection isn't ready, buffers the pong to send when it connects /// 5) On Pong: Notifies the outgoing connection's keepalive task via watch channel /// 6) Forwards MpcMessage and IndexerHeight to the unified `receiver` channel /// @@ -118,14 +123,15 @@ struct ParticipantIdentities { struct PersistentConnection { target_participant_id: ParticipantId, connectivity: Arc>, - /// Channel for buffering Pongs when outgoing connection is temporarily unavailable. - pong_buffer: UnboundedSender, + /// Stores the latest pong sequence number to send when outgoing connection becomes ready. + /// Uses a watch channel so we only keep the most recent value. + pending_pong: watch::Sender, /// Background reconnection task that maintains the connection lifecycle. /// /// This task runs an infinite loop that: /// 1. Attempts to establish a new [`TlsConnection`] to `target_participant_id` - /// 2. On success: Registers the connection with `connectivity` and blocks waiting for it - /// to close (via `wait_for_close()`) + /// 2. On success: Registers the connection with `connectivity`, sends any buffered + /// pending pong, and blocks waiting for it to close (via `wait_for_close()`) /// 3. On failure: Logs the error and sleeps for [`CONNECTION_RETRY_DELAY`] before retrying /// 4. When a connection closes (step 2 completes): Loops back to step 1 /// @@ -415,7 +421,7 @@ impl PersistentConnection { connectivity: Arc>, ) -> anyhow::Result { let connectivity_clone = Arc::clone(&connectivity); - let (pong_buffer_tx, mut pong_buffer_rx) = mpsc::unbounded_channel::(); + let (pending_pong_tx, mut pending_pong_rx) = watch::channel(0u64); let task = tracking::spawn( &format!("Persistent connection to {}", target_participant_id), async move { @@ -436,10 +442,19 @@ impl PersistentConnection { target_participant_id ); - // Register connection and drain any buffered Pongs connectivity.set_outgoing_connection(&new_conn); - while let Ok(seq) = pong_buffer_rx.try_recv() { - let _ = new_conn.sender.send(Packet::Pong(seq)); + + // Send the latest pending pong if there is one + let pending_seq = *pending_pong_rx.borrow_and_update(); + if pending_seq > 0 { + if new_conn.sender.send(Packet::Pong(pending_seq)).is_err() { + tracing::warn!( + "Failed to send pending pong {} to {}, reconnecting", + pending_seq, + target_participant_id + ); + continue; + } } new_conn.wait_for_close().await; @@ -460,7 +475,7 @@ impl PersistentConnection { Ok(PersistentConnection { target_participant_id, connectivity: connectivity_clone, - pong_buffer: pong_buffer_tx, + pending_pong: pending_pong_tx, _task: task, }) } @@ -585,7 +600,8 @@ pub async fn new_tls_mesh_network( match packet { Packet::Ping(seq) => { // Send Pong via our outgoing connection to the peer, maintaining - // unidirectional I/O design. If outgoing isn't ready, buffer the Pong. + // unidirectional I/O design. If outgoing isn't ready, store the pong + // to be sent when the connection becomes ready. if let Some(conn) = connections.get(&peer_id) { if let Some(outgoing_conn) = conn.connectivity.any_outgoing_connection() @@ -598,19 +614,11 @@ pub async fn new_tls_mesh_network( break; } } else { - // Outgoing connection not ready yet, buffer the Pong - if conn.pong_buffer.send(seq).is_err() { - tracing::warn!( - "Cannot buffer Pong({}) for {}: pong buffer channel closed", - seq, peer_id - ); - } + // Outgoing connection not ready yet, store the latest pong. + // Ignore error: send only fails if the receiver is dropped, + // meaning the PersistentConnection is shutting down anyway. + let _ = conn.pending_pong.send(seq); } - } else { - tracing::warn!( - "Cannot send Pong({}) to {}: connection not found in HashMap", - seq, peer_id - ); } } Packet::Pong(seq) => { From d04ed38b3f97179aa9696dd56d0ec4776cbfab3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Wed, 7 Jan 2026 14:32:07 +0100 Subject: [PATCH 19/45] fix clippy --- crates/node/src/p2p.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index f4066e0860..decdd716de 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -446,15 +446,15 @@ impl PersistentConnection { // Send the latest pending pong if there is one let pending_seq = *pending_pong_rx.borrow_and_update(); - if pending_seq > 0 { - if new_conn.sender.send(Packet::Pong(pending_seq)).is_err() { - tracing::warn!( - "Failed to send pending pong {} to {}, reconnecting", - pending_seq, - target_participant_id - ); - continue; - } + if pending_seq > 0 + && new_conn.sender.send(Packet::Pong(pending_seq)).is_err() + { + tracing::warn!( + "Failed to send pending pong {} to {}, reconnecting", + pending_seq, + target_participant_id + ); + continue; } new_conn.wait_for_close().await; From 873e1e0c30b5d311dbaf176bdce58b8ace8ba6dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Wed, 7 Jan 2026 15:41:13 +0100 Subject: [PATCH 20/45] structured logging --- crates/node/src/p2p.rs | 62 ++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index decdd716de..85f5500a24 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -260,7 +260,7 @@ impl TlsConnection { ); } - info!("Performing P2P handshake with: {:?}", target_address); + info!(target_address, "Performing P2P handshake"); p2p_handshake(&mut tls_conn, Self::HANDSHAKE_TIMEOUT) .await .context("p2p handshake")?; @@ -287,7 +287,7 @@ impl TlsConnection { tls_conn.write_all(&serialized).await?; sent_bytes += 4 + len as u64; - tracking::set_progress(&format!("Sent {} bytes", sent_bytes)); + tracking::set_progress(&format!("Sent {sent_bytes} bytes")); } _ = tls_conn.read_u8() => { // We do not expect any data from the other side. However, @@ -327,20 +327,25 @@ impl TlsConnection { let expected_seq = last_received_pong_seq + 1; if pong_info.seq != expected_seq { tracing::warn!( - "Received pong {} from {}, expected {}, lost {} pong(s)", - pong_info.seq, target_participant_id, expected_seq, pong_info.seq - expected_seq + seq = pong_info.seq, + peer = %target_participant_id, + expected = expected_seq, + lost = pong_info.seq - expected_seq, + "Received pong with unexpected sequence, lost pong(s)" ); } last_received_pong_seq = pong_info.seq; let rtt = ping_sent_at.elapsed(); tracking::set_progress(&format!( - "Received pong {} from {}, RTT: {:?}", - pong_info.seq, target_participant_id, rtt + "Received pong {} from {target_participant_id}, RTT: {rtt:?}", + pong_info.seq )); } else { tracing::debug!( - "Received stale pong {} from {}, already received {}", - pong_info.seq, target_participant_id, last_received_pong_seq + seq = pong_info.seq, + peer = %target_participant_id, + last_received = last_received_pong_seq, + "Received stale pong, already received newer" ); } // Wait until PING_INTERVAL has elapsed since ping was sent @@ -351,9 +356,9 @@ impl TlsConnection { } _ = tokio::time::sleep(Self::PONG_TIMEOUT) => { tracing::warn!( - "No pong received from {} for {:?}, closing connection", - target_participant_id, - Self::PONG_TIMEOUT + peer = %target_participant_id, + timeout = ?Self::PONG_TIMEOUT, + "No pong received, closing connection" ); closed_for_keepalive.cancel(); break; @@ -437,9 +442,9 @@ impl PersistentConnection { Ok(conn) => { let new_conn = Arc::new(conn); tracing::info!( - "Outgoing {} --> {} connected", - my_id, - target_participant_id + from = %my_id, + to = %target_participant_id, + "Outgoing connection established" ); connectivity.set_outgoing_connection(&new_conn); @@ -450,9 +455,9 @@ impl PersistentConnection { && new_conn.sender.send(Packet::Pong(pending_seq)).is_err() { tracing::warn!( - "Failed to send pending pong {} to {}, reconnecting", - pending_seq, - target_participant_id + seq = pending_seq, + peer = %target_participant_id, + "Failed to send pending pong, reconnecting" ); continue; } @@ -461,10 +466,10 @@ impl PersistentConnection { } Err(e) => { tracing::warn!( - "Could not connect to {}: {:#}, retrying (me: {})", - target_participant_id, - e, - my_id + peer = %target_participant_id, + error = format!("{e:#}"), + me = %my_id, + "Could not connect, retrying" ); tokio::time::sleep(Self::CONNECTION_RETRY_DELAY).await; } @@ -568,11 +573,11 @@ pub async fn new_tls_mesh_network( let mut stream = tls_acceptor.accept(tcp_stream).await?; let peer_id = verify_peer_identity(stream.get_ref().1, &participant_identities)?; - tracking::set_progress(&format!("Authenticated as {}", peer_id)); + tracking::set_progress(&format!("Authenticated as {peer_id}")); p2p_handshake(&mut stream, TlsConnection::HANDSHAKE_TIMEOUT) .await .context("p2p handshake")?; - tracing::info!("Incoming {} <-- {} connected", my_id, peer_id); + tracing::info!(to = %my_id, from = %peer_id, "Incoming connection established"); let incoming_conn = Arc::new(()); connectivities .get(peer_id)? @@ -608,8 +613,8 @@ pub async fn new_tls_mesh_network( { if outgoing_conn.sender.send(Packet::Pong(seq)).is_err() { tracing::info!( - "Outgoing connection to {} is dead, closing incoming connection for clean reconnect", - peer_id + peer = %peer_id, + "Outgoing connection is dead, closing incoming connection for clean reconnect" ); break; } @@ -630,10 +635,10 @@ pub async fn new_tls_mesh_network( // Send the new pong info via watch channel let _ = outgoing_conn.pong_tx.send(PongInfo { seq }); } else { - tracing::warn!("No outgoing connection to {} to forward Pong({})", peer_id, seq); + tracing::warn!(peer = %peer_id, seq, "No outgoing connection to forward Pong"); } } else { - tracing::warn!("No connection found for peer {} to forward Pong({})", peer_id, seq); + tracing::warn!(peer = %peer_id, seq, "No connection found for peer to forward Pong"); } } Packet::MpcMessage(mpc_message) => { @@ -653,8 +658,7 @@ pub async fn new_tls_mesh_network( } tracking::set_progress(&format!( - "Received {} bytes from {}", - received_bytes, peer_id + "Received {received_bytes} bytes from {peer_id}" )); } anyhow::Ok(()) From a1fe9db5bd6b649c9e843992c66384748f1ade08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Wed, 7 Jan 2026 15:50:13 +0100 Subject: [PATCH 21/45] refactor: improve comment clarity for pong forwarding in keepalive task --- crates/node/src/p2p.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 85f5500a24..103671e520 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -632,7 +632,9 @@ pub async fn new_tls_mesh_network( if let Some(outgoing_conn) = conn.connectivity.any_outgoing_connection() { - // Send the new pong info via watch channel + // Forward pong to keepalive task via watch channel. + // Ignore error: send only fails if the receiver is dropped, + // meaning the connection is already closing. let _ = outgoing_conn.pong_tx.send(PongInfo { seq }); } else { tracing::warn!(peer = %peer_id, seq, "No outgoing connection to forward Pong"); From 25fb3113d4cc6dcbf4ead8a0ffef37dbd9ce7733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Wed, 7 Jan 2026 15:58:23 +0100 Subject: [PATCH 22/45] use tokio::time::timeout instead of tokio::select --- crates/node/src/p2p.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 103671e520..a8fbfe7ddf 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -318,9 +318,9 @@ impl TlsConnection { break; } - // Wait for either a pong response or timeout - tokio::select! { - _ = pong_rx.changed() => { + // Wait for pong response with timeout + match tokio::time::timeout(Self::PONG_TIMEOUT, pong_rx.changed()).await { + Ok(Ok(())) => { // Pong received, validate and calculate RTT let pong_info = *pong_rx.borrow_and_update(); if pong_info.seq > last_received_pong_seq { @@ -354,7 +354,12 @@ impl TlsConnection { tokio::time::sleep(Self::PING_INTERVAL - elapsed).await; } } - _ = tokio::time::sleep(Self::PONG_TIMEOUT) => { + Ok(Err(_)) => { + // Watch sender dropped, connection is closing + break; + } + Err(_) => { + // Timeout tracing::warn!( peer = %target_participant_id, timeout = ?Self::PONG_TIMEOUT, From b2c02feacd5c158d1f4e48a4f2fa0ef910dca4d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Wed, 7 Jan 2026 17:22:02 +0100 Subject: [PATCH 23/45] fix: add comment to clarify handling of dead outgoing connections in TLS mesh network --- crates/node/src/p2p.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index a8fbfe7ddf..d6052be0c6 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -617,6 +617,7 @@ pub async fn new_tls_mesh_network( conn.connectivity.any_outgoing_connection() { if outgoing_conn.sender.send(Packet::Pong(seq)).is_err() { + // Close incoming so peer detects disconnect and both sides reconnect cleanly tracing::info!( peer = %peer_id, "Outgoing connection is dead, closing incoming connection for clean reconnect" From 57d91e4e0d8c697782246331da56f718c4378509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Wed, 7 Jan 2026 17:40:20 +0100 Subject: [PATCH 24/45] refactor: clarify ping interval description and log message for unexpected pong sequence --- crates/node/src/p2p.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index d6052be0c6..299123fc9f 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -226,8 +226,8 @@ impl TlsConnection { /// If we don't receive a pong response within this time, consider the connection dead. const PONG_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(20); - /// Interval between consecutive pings. A new ping is sent 1 second after the previous - /// ping was sent, but only after receiving its pong response. + /// Pings are sent at 1-second intervals from when the previous ping was sent, + /// waiting for pong response before sending the next. const PING_INTERVAL: std::time::Duration = std::time::Duration::from_secs(1); /// Makes a TLS/TCP connection to the given address, authenticating the @@ -331,7 +331,7 @@ impl TlsConnection { peer = %target_participant_id, expected = expected_seq, lost = pong_info.seq - expected_seq, - "Received pong with unexpected sequence, lost pong(s)" + "Unexpected pong sequence gap" ); } last_received_pong_seq = pong_info.seq; From 9cf267a91fa2c3c84748865eaa3062c6540d6d5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Wed, 7 Jan 2026 17:51:11 +0100 Subject: [PATCH 25/45] fix: handle case where peer sends Ping but is not in connections map --- crates/node/src/p2p.rs | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 299123fc9f..7de1d696aa 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -612,24 +612,27 @@ pub async fn new_tls_mesh_network( // Send Pong via our outgoing connection to the peer, maintaining // unidirectional I/O design. If outgoing isn't ready, store the pong // to be sent when the connection becomes ready. - if let Some(conn) = connections.get(&peer_id) { - if let Some(outgoing_conn) = - conn.connectivity.any_outgoing_connection() - { - if outgoing_conn.sender.send(Packet::Pong(seq)).is_err() { - // Close incoming so peer detects disconnect and both sides reconnect cleanly - tracing::info!( - peer = %peer_id, - "Outgoing connection is dead, closing incoming connection for clean reconnect" - ); - break; - } - } else { - // Outgoing connection not ready yet, store the latest pong. - // Ignore error: send only fails if the receiver is dropped, - // meaning the PersistentConnection is shutting down anyway. - let _ = conn.pending_pong.send(seq); + let Some(conn) = connections.get(&peer_id) else { + // Peer authenticated but not in connections map - indicates a bug + tracing::warn!(peer = %peer_id, seq, "Received Ping from peer not in connections map"); + continue; + }; + if let Some(outgoing_conn) = + conn.connectivity.any_outgoing_connection() + { + if outgoing_conn.sender.send(Packet::Pong(seq)).is_err() { + // Close incoming so peer detects disconnect and both sides reconnect cleanly + tracing::info!( + peer = %peer_id, + "Outgoing connection is dead, closing incoming connection for clean reconnect" + ); + break; } + } else { + // Outgoing connection not ready yet, store the latest pong. + // Ignore error: send only fails if the receiver is dropped, + // meaning the PersistentConnection is shutting down anyway. + let _ = conn.pending_pong.send(seq); } } Packet::Pong(seq) => { From 7ec54a52111ec6897e4d110bc6afeeaf315350e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Wed, 7 Jan 2026 17:55:06 +0100 Subject: [PATCH 26/45] refactor: update comment for pong notification channel in TlsConnection struct --- crates/node/src/p2p.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 7de1d696aa..31591e64a2 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -178,7 +178,7 @@ struct TlsConnection { /// the `closed` token. This ensures pings are sent at exactly 1-second intervals while only /// sending when the previous ping received a response. _keepalive_task: AutoAbortTask<()>, - /// Watch channel sender for receiving pong notifications from the incoming connection handler. + /// Watch channel sender for delivering pong notifications to the keepalive task. /// /// The incoming handler sends PongInfo when it receives a Pong packet. The keepalive task /// monitors this channel to detect connection health and calculate RTT. This enables clean From fe4b30631096d6409eb0e3493bd6f0f050c6251d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Wed, 7 Jan 2026 18:39:59 +0100 Subject: [PATCH 27/45] fix: improve ping/pong handling to ensure proper timeout management See: https://github.com/near/mpc/pull/1687#discussion_r2669215067 --- crates/node/src/p2p.rs | 80 ++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 45 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 31591e64a2..068c32507f 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -308,66 +308,56 @@ impl TlsConnection { &format!("Ping sender for {}", target_participant_id), async move { let mut seq: u64 = 0; - let mut last_received_pong_seq: u64 = 0; loop { seq += 1; let ping_sent_at = Instant::now(); if sender_clone.send(Packet::Ping(seq)).is_err() { // The receiver side will be dropped when the sender task is // dropped (i.e. connection is closed). - break; + return; } - // Wait for pong response with timeout - match tokio::time::timeout(Self::PONG_TIMEOUT, pong_rx.changed()).await { - Ok(Ok(())) => { - // Pong received, validate and calculate RTT - let pong_info = *pong_rx.borrow_and_update(); - if pong_info.seq > last_received_pong_seq { - let expected_seq = last_received_pong_seq + 1; - if pong_info.seq != expected_seq { - tracing::warn!( - seq = pong_info.seq, - peer = %target_participant_id, - expected = expected_seq, - lost = pong_info.seq - expected_seq, - "Unexpected pong sequence gap" - ); + // Wait for pong matching this ping, ignoring stale pongs + let deadline = Instant::now() + Self::PONG_TIMEOUT; + loop { + let remaining = deadline.saturating_duration_since(Instant::now()); + match tokio::time::timeout(remaining, pong_rx.changed()).await { + Ok(Ok(())) => { + let pong_info = *pong_rx.borrow_and_update(); + if pong_info.seq == seq { + let rtt = ping_sent_at.elapsed(); + tracking::set_progress(&format!( + "Received pong {} from {target_participant_id}, RTT: {rtt:?}", + seq + )); + break; } - last_received_pong_seq = pong_info.seq; - let rtt = ping_sent_at.elapsed(); - tracking::set_progress(&format!( - "Received pong {} from {target_participant_id}, RTT: {rtt:?}", - pong_info.seq - )); - } else { tracing::debug!( - seq = pong_info.seq, peer = %target_participant_id, - last_received = last_received_pong_seq, - "Received stale pong, already received newer" + received_seq = pong_info.seq, + expected_seq = seq, + "Received stale pong, waiting for expected sequence" ); } - // Wait until PING_INTERVAL has elapsed since ping was sent - let elapsed = ping_sent_at.elapsed(); - if elapsed < Self::PING_INTERVAL { - tokio::time::sleep(Self::PING_INTERVAL - elapsed).await; + Ok(Err(_)) => { + // Exit to trigger reconnection by PersistentConnection + return; + } + Err(_) => { + tracing::warn!( + peer = %target_participant_id, + timeout = ?Self::PONG_TIMEOUT, + "No pong received, closing connection" + ); + closed_for_keepalive.cancel(); + return; } } - Ok(Err(_)) => { - // Watch sender dropped, connection is closing - break; - } - Err(_) => { - // Timeout - tracing::warn!( - peer = %target_participant_id, - timeout = ?Self::PONG_TIMEOUT, - "No pong received, closing connection" - ); - closed_for_keepalive.cancel(); - break; - } + } + // Wait until PING_INTERVAL has elapsed since ping was sent + let elapsed = ping_sent_at.elapsed(); + if elapsed < Self::PING_INTERVAL { + tokio::time::sleep(Self::PING_INTERVAL - elapsed).await; } } }, From 57ac85644fc35fc33a8ba04dce93f8b60aca379b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Wed, 7 Jan 2026 19:05:20 +0100 Subject: [PATCH 28/45] Remove lru dependency from Cargo.toml files and update deny.toml to address advisory RUSTSEC-2026-0002. Added skips for near-sdk related dependencies to resolve version conflicts. --- Cargo.lock | 1458 +++++++++++++++++++++++----------------- Cargo.toml | 1 - crates/node/Cargo.toml | 1 - deny.toml | 11 +- 4 files changed, 839 insertions(+), 632 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 65b14b08b2..d303ecaf41 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,9 +90,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy" -version = "1.0.41" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae62e633fa48b4190af5e841eb05179841bb8b713945103291e2c0867037c0d1" +checksum = "cf23ee5a0d40c75ade22bf33f117058461fc30a95e84d48b01c845c28f4ea7c5" dependencies = [ "alloy-core", "alloy-signer", @@ -101,9 +101,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "1.0.41" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9b151e38e42f1586a01369ec52a6934702731d07e8509a7307331b09f6c46dc" +checksum = "41e46a465e50a339a817070ec23f06eb3fc9fbb8af71612868367b875a9d49e3" dependencies = [ "alloy-eips", "alloy-primitives", @@ -112,8 +112,9 @@ dependencies = [ "alloy-trie", "alloy-tx-macros", "auto_impl", + "borsh", "c-kzg", - "derive_more 2.0.1", + "derive_more 2.1.1", "either", "k256", "once_cell", @@ -127,9 +128,9 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "1.0.41" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2d5e8668ef6215efdb7dcca6f22277b4e483a5650e05f5de22b2350971f4b8" +checksum = "07001b1693af794c7526aab400b42e38075f986ef8fef78841e5ebc745473e56" dependencies = [ "alloy-consensus", "alloy-eips", @@ -141,9 +142,9 @@ dependencies = [ [[package]] name = "alloy-core" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca96214615ec8cf3fa2a54b32f486eb49100ca7fe7eb0b8c1137cd316e7250a" +checksum = "9d4087016b0896051dd3d03e0bedda2f4d4d1689af8addc8450288c63a9e5f68" dependencies = [ "alloy-primitives", ] @@ -163,32 +164,34 @@ dependencies = [ [[package]] name = "alloy-eip2930" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b82752a889170df67bbb36d42ca63c531eb16274f0d7299ae2a680facba17bd" +checksum = "9441120fa82df73e8959ae0e4ab8ade03de2aaae61be313fbf5746277847ce25" dependencies = [ "alloy-primitives", "alloy-rlp", + "borsh", "serde", ] [[package]] name = "alloy-eip7702" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d4769c6ffddca380b0070d71c8b7f30bed375543fe76bb2f74ec0acf4b7cd16" +checksum = "2919c5a56a1007492da313e7a3b6d45ef5edc5d33416fdec63c0d7a2702a0d20" dependencies = [ "alloy-primitives", "alloy-rlp", + "borsh", "serde", "thiserror 2.0.17", ] [[package]] name = "alloy-eips" -version = "1.0.41" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5434834adaf64fa20a6fb90877bc1d33214c41b055cc49f82189c98614368cc" +checksum = "707337efeb051ddbaece17a73eaec5150945a5a5541112f4146508248edc2e40" dependencies = [ "alloy-eip2124", "alloy-eip2930", @@ -197,8 +200,9 @@ dependencies = [ "alloy-rlp", "alloy-serde", "auto_impl", + "borsh", "c-kzg", - "derive_more 2.0.1", + "derive_more 2.1.1", "either", "serde", "serde_with", @@ -208,9 +212,9 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5513d5e6bd1cba6bdcf5373470f559f320c05c8c59493b6e98912fbe6733943f" +checksum = "84e3cf01219c966f95a460c95f1d4c30e12f6c18150c21a30b768af2a2a29142" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -220,13 +224,13 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "1.0.41" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c69f6c9c68a1287c9d5ff903d0010726934de0dac10989be37b75a29190d55" +checksum = "48562f9b4c4e1514cab54af16feaffc18194a38216bbd0c23004ec4667ad696b" dependencies = [ "alloy-primitives", "alloy-sol-types", - "http 1.3.1", + "http 1.4.0", "serde", "serde_json", "thiserror 2.0.17", @@ -235,9 +239,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "1.0.41" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf2ae05219e73e0979cb2cf55612aafbab191d130f203079805eaf881cca58" +checksum = "364a5eaa598437d7a57bcbcb4b7fcb0518e192cf809a19b09b2b5cf73b9ba1cd" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -252,7 +256,7 @@ dependencies = [ "alloy-sol-types", "async-trait", "auto_impl", - "derive_more 2.0.1", + "derive_more 2.1.1", "futures-utils-wasm", "serde", "serde_json", @@ -261,9 +265,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "1.0.41" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e58f4f345cef483eab7374f2b6056973c7419ffe8ad35e994b7a7f5d8e0c7ba4" +checksum = "21af5255bd276e528ee625d97033884916e879a1c6edcd5b70a043bd440c0710" dependencies = [ "alloy-consensus", "alloy-eips", @@ -274,24 +278,25 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "355bf68a433e0fd7f7d33d5a9fc2583fde70bf5c530f63b80845f8da5505cf28" +checksum = "f6a0fb18dd5fb43ec5f0f6a20be1ce0287c79825827de5744afaa6c957737c33" dependencies = [ "alloy-rlp", "bytes", "cfg-if 1.0.4", "const-hex", - "derive_more 2.0.1", + "derive_more 2.1.1", "foldhash 0.2.0", - "hashbrown 0.16.0", - "indexmap 2.12.0", + "hashbrown 0.16.1", + "indexmap 2.13.0", "itoa", "k256", "keccak-asm", "paste", "proptest", "rand 0.9.2", + "rapidhash", "ruint", "rustc-hash 2.1.1", "serde", @@ -318,14 +323,14 @@ checksum = "64b728d511962dda67c1bc7ea7c03736ec275ed2cf4c35d9585298ac9ccf3b73" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] name = "alloy-rpc-types-any" -version = "1.0.41" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbde0801a32d21c5f111f037bee7e22874836fba7add34ed4a6919932dd7cf23" +checksum = "6ebc96cf29095c10a183fb7106a097fe12ca8dd46733895582da255407f54b29" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", @@ -334,9 +339,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "1.0.41" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "361cd87ead4ba7659bda8127902eda92d17fa7ceb18aba1676f7be10f7222487" +checksum = "9cc3f354a5079480acca0a6533d1d3838177a03ea494ef0ae8d1679efea88274" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -355,9 +360,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "1.0.41" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64600fc6c312b7e0ba76f73a381059af044f4f21f43e07f51f1fa76c868fe302" +checksum = "a438ce4cd49ec4bc213868c1fe94f2fe103d4c3f22f6a42073db974f9c0962da" dependencies = [ "alloy-primitives", "serde", @@ -366,9 +371,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "1.0.41" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5772858492b26f780468ae693405f895d6a27dea6e3eab2c36b6217de47c2647" +checksum = "389372d6ae4d62b88c8dca8238e4f7d0a7727b66029eb8a5516a908a03161450" dependencies = [ "alloy-primitives", "async-trait", @@ -381,9 +386,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "1.0.41" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4195b803d0a992d8dbaab2ca1986fc86533d4bc80967c0cce7668b26ad99ef9" +checksum = "69c260e78b9c104c444f8a202f283d5e8c6637e6fa52a83f649ad6aaa0b91fd0" dependencies = [ "alloy-consensus", "alloy-network", @@ -397,41 +402,41 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3ce480400051b5217f19d6e9a82d9010cdde20f1ae9c00d53591e4a1afbb312" +checksum = "09eb18ce0df92b4277291bbaa0ed70545d78b02948df756bbd3d6214bf39a218" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] name = "alloy-sol-macro-expander" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d792e205ed3b72f795a8044c52877d2e6b6e9b1d13f431478121d8d4eaa9028" +checksum = "95d9fa2daf21f59aa546d549943f10b5cce1ae59986774019fbedae834ffe01b" dependencies = [ "alloy-sol-macro-input", "const-hex", "heck 0.5.0", - "indexmap 2.12.0", + "indexmap 2.13.0", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", "syn-solidity", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bd1247a8f90b465ef3f1207627547ec16940c35597875cdc09c49d58b19693c" +checksum = "9396007fe69c26ee118a19f4dee1f5d1d6be186ea75b3881adf16d87f8444686" dependencies = [ "const-hex", "dunce", @@ -439,15 +444,15 @@ dependencies = [ "macro-string", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", "syn-solidity", ] [[package]] name = "alloy-sol-type-parser" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "954d1b2533b9b2c7959652df3076954ecb1122a28cc740aa84e7b0a49f6ac0a9" +checksum = "af67a0b0dcebe14244fc92002cd8d96ecbf65db4639d479f5fcd5805755a4c27" dependencies = [ "serde", "winnow", @@ -455,9 +460,9 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70319350969a3af119da6fb3e9bddb1bce66c9ea933600cb297c8b1850ad2a3c" +checksum = "09aeea64f09a7483bdcd4193634c7e5cf9fd7775ee767585270cd8ce2d69dc95" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -467,14 +472,14 @@ dependencies = [ [[package]] name = "alloy-trie" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3412d52bb97c6c6cc27ccc28d4e6e8cf605469101193b50b0bd5813b1f990b5" +checksum = "428aa0f0e0658ff091f8f667c406e034b431cb10abd39de4f507520968acc499" dependencies = [ "alloy-primitives", "alloy-rlp", "arrayvec", - "derive_more 2.0.1", + "derive_more 2.1.1", "nybbles", "serde", "smallvec", @@ -483,15 +488,14 @@ dependencies = [ [[package]] name = "alloy-tx-macros" -version = "1.0.41" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8e52276fdb553d3c11563afad2898f4085165e4093604afe3d78b69afbf408f" +checksum = "99dac443033e83b14f68fac56e8c27e76421f1253729574197ceccd06598f3ef" dependencies = [ - "alloy-primitives", "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -535,22 +539,22 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.10" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -570,9 +574,12 @@ dependencies = [ [[package]] name = "arc-swap" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" +checksum = "51d03449bb8ca2cc2ef70869af31463d1ae5ccc8fa3e334b307203fbf815207e" +dependencies = [ + "rustversion", +] [[package]] name = "ark-ff" @@ -659,7 +666,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -697,7 +704,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -796,7 +803,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", "synstructure", ] @@ -808,7 +815,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -825,9 +832,9 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "async-compression" -version = "0.4.32" +version = "0.4.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0" +checksum = "98ec5f6c2f8bc326c994cb9e241cc257ddaba9afa8555a43cffbb5dd86efaa37" dependencies = [ "compression-codecs", "compression-core", @@ -855,7 +862,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -866,7 +873,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -890,7 +897,7 @@ version = "3.2.0" dependencies = [ "borsh", "dcap-qvl", - "derive_more 2.0.1", + "derive_more 2.1.1", "dstack-sdk-types", "hex", "serde", @@ -926,7 +933,7 @@ checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -976,10 +983,10 @@ dependencies = [ "axum-core 0.4.5", "bytes", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.7.0", + "hyper 1.8.1", "hyper-util", "itoa", "matchit 0.7.3", @@ -1002,19 +1009,19 @@ dependencies = [ [[package]] name = "axum" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18ed336352031311f4e0b4dd2ff392d4fbb370777c9d18d7fc9d7359f73871" +checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" dependencies = [ - "axum-core 0.5.5", + "axum-core 0.5.6", "axum-macros", "bytes", "form_urlencoded", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.7.0", + "hyper 1.8.1", "hyper-util", "itoa", "matchit 0.8.4", @@ -1043,7 +1050,7 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", "mime", @@ -1057,13 +1064,13 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" dependencies = [ "bytes", "futures-core", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", "mime", @@ -1082,7 +1089,7 @@ checksum = "604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -1108,7 +1115,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -1121,7 +1128,7 @@ dependencies = [ "ed25519-dalek", "mpc-contract", "mpc-node", - "near-account-id 2.0.0", + "near-account-id 2.5.0", "rand 0.8.5", "rand_core 0.6.4", "serde", @@ -1157,26 +1164,26 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.8.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" +checksum = "7d809780667f4410e7c41b07f52439b94d2bdf8528eeedc287fa38d3b7f95d82" [[package]] name = "binary-install" -version = "0.2.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93bff426ff93f3610dd2b946f3eb8cb2d1285ca8682834d43be531a3f93db2ff" +checksum = "5252e41a4ed7657f79827123f232443077984ec55c540adf48e8fe67b6ec0763" dependencies = [ "anyhow", "dirs-next", "flate2", - "fs2", + "fs4", "hex", "is_executable", "siphasher", "tar", "ureq", - "zip 0.6.6", + "zip 2.4.2", ] [[package]] @@ -1197,7 +1204,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -1215,7 +1222,7 @@ dependencies = [ "regex", "rustc-hash 2.1.1", "shlex", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -1235,15 +1242,15 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitcoin-io" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf" +checksum = "2dee39a0ee5b4095224a0cfc6bf4cc1baf0f9624b96b367e53b66d974e51d953" [[package]] name = "bitcoin_hashes" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" +checksum = "26ec84b80c482df901772e931a9a681e26a1b9ee2302edeff23cb30328745c8b" dependencies = [ "bitcoin-io", "hex-conservative", @@ -1360,14 +1367,14 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] name = "borsh" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" +checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" dependencies = [ "borsh-derive", "cfg_aliases", @@ -1375,15 +1382,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" +checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -1413,9 +1420,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" dependencies = [ "allocator-api2", ] @@ -1446,7 +1453,7 @@ checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -1457,9 +1464,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" dependencies = [ "serde", ] @@ -1475,12 +1482,11 @@ dependencies = [ [[package]] name = "bzip2" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" dependencies = [ "bzip2-sys", - "libc", ] [[package]] @@ -1510,9 +1516,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" dependencies = [ "serde_core", ] @@ -1563,9 +1569,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.43" +version = "1.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739eb0f94557554b3ca9a86d2d37bebd49c5e6d0c1d2bda35ba5bdac830befc2" +checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" dependencies = [ "find-msvc-tools", "jobserver", @@ -1611,7 +1617,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -1632,7 +1638,7 @@ dependencies = [ "blstrs", "clap", "contract-interface", - "derive_more 2.0.1", + "derive_more 2.1.1", "elliptic-curve", "hex", "hkdf", @@ -1656,9 +1662,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.50" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623" +checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" dependencies = [ "clap_builder", "clap_derive", @@ -1666,9 +1672,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.50" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0" +checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" dependencies = [ "anstream", "anstyle", @@ -1685,7 +1691,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -1721,9 +1727,9 @@ dependencies = [ [[package]] name = "compression-codecs" -version = "0.4.31" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23" +checksum = "b0f7ac3e5b97fdce45e8922fb05cae2c37f7bbd63d30dd94821dacfd8f3f2bf2" dependencies = [ "compression-core", "flate2", @@ -1732,9 +1738,9 @@ dependencies = [ [[package]] name = "compression-core" -version = "0.4.29" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb" +checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" [[package]] name = "console" @@ -1795,9 +1801,9 @@ dependencies = [ [[package]] name = "constant_time_eq" -version = "0.1.5" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" [[package]] name = "contract-history" @@ -1805,7 +1811,7 @@ version = "3.2.0" dependencies = [ "bs58 0.5.1", "clap", - "reqwest 0.12.24", + "reqwest 0.12.28", "serde", "serde_json", "sha2", @@ -1818,7 +1824,7 @@ version = "3.2.0" dependencies = [ "borsh", "bs58 0.5.1", - "derive_more 2.0.1", + "derive_more 2.1.1", "near-sdk", "schemars 0.8.22", "serde", @@ -1838,6 +1844,15 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8" +[[package]] +name = "convert_case" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -1933,7 +1948,7 @@ dependencies = [ "rustc-hash 2.1.1", "serde", "smallvec", - "target-lexicon 0.13.3", + "target-lexicon 0.13.4", "wasmtime-internal-math", ] @@ -1985,7 +2000,7 @@ dependencies = [ "cranelift-codegen", "log", "smallvec", - "target-lexicon 0.13.3", + "target-lexicon 0.13.4", ] [[package]] @@ -2002,7 +2017,7 @@ checksum = "be7b57410e388de0828fa9178e8693abe996bf2356a7f55be35719ee5b162755" dependencies = [ "cranelift-codegen", "libc", - "target-lexicon 0.13.3", + "target-lexicon 0.13.4", ] [[package]] @@ -2013,9 +2028,9 @@ checksum = "bd9641751da85481f0e04033228403eca2becd2a3d9aff56f6c8bed8b9147bfc" [[package]] name = "crc" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" dependencies = [ "crc-catalog", ] @@ -2117,9 +2132,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -2162,7 +2177,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -2195,7 +2210,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -2210,7 +2225,7 @@ dependencies = [ "quote", "serde", "strsim", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -2221,7 +2236,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -2232,7 +2247,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core 0.21.3", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -2303,6 +2318,12 @@ version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f400d0750c0c069e8493f2256cb4da6f604b6d2eeb69a0ca8863acde352f8400" +[[package]] +name = "deflate64" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26bf8fc351c5ed29b5c2f0cbbac1b209b74f60ecd62e675a998df72c49af5204" + [[package]] name = "der" version = "0.7.10" @@ -2338,7 +2359,7 @@ checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -2370,7 +2391,7 @@ checksum = "74ef43543e701c01ad77d3a5922755c6a1d71b22d942cb8042be4994b380caff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -2381,7 +2402,7 @@ checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -2392,7 +2413,7 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -2405,7 +2426,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -2419,11 +2440,11 @@ dependencies = [ [[package]] name = "derive_more" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" dependencies = [ - "derive_more-impl 2.0.1", + "derive_more-impl 2.1.1", ] [[package]] @@ -2434,18 +2455,20 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] name = "derive_more-impl" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ + "convert_case 0.10.0", "proc-macro2", "quote", - "syn 2.0.108", + "rustc_version 0.4.1", + "syn 2.0.114", "unicode-xid", ] @@ -2519,7 +2542,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -2560,9 +2583,9 @@ dependencies = [ "bon", "dstack-sdk-types", "hex", - "http 1.3.1", + "http 1.4.0", "http-client-unix-domain-socket", - "reqwest 0.12.24", + "reqwest 0.12.28", "serde", "serde_json", "sha2", @@ -2681,7 +2704,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -2749,7 +2772,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -2769,7 +2792,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -2789,7 +2812,7 @@ checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -2810,7 +2833,7 @@ dependencies = [ "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -2904,9 +2927,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" +checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" [[package]] name = "finite-wasm" @@ -3118,6 +3141,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "fs4" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eeb4ed9e12f43b7fa0baae3f9cdda28352770132ef2e09a23760c29cae8bd47" +dependencies = [ + "rustix 0.38.44", + "windows-sys 0.48.0", +] + [[package]] name = "funty" version = "2.0.0" @@ -3193,7 +3226,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -3248,12 +3281,12 @@ dependencies = [ "bytes", "chrono", "futures", - "hyper 1.7.0", + "hyper 1.8.1", "jsonwebtoken", "once_cell", "prost 0.13.5", "prost-types 0.13.5", - "reqwest 0.12.24", + "reqwest 0.12.28", "secret-vault-value", "serde", "serde_json", @@ -3268,9 +3301,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.9" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -3321,15 +3354,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" dependencies = [ "fallible-iterator", - "indexmap 2.12.0", + "indexmap 2.13.0", "stable_deref_trait", ] [[package]] name = "git2" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2deb07a133b1520dc1a5690e9bd08950108873d7ed5de38dcc74d3b5ebffa110" +checksum = "3e2b37e2f62729cdada11f0e6b3b6fe383c69c29fc619e391223e12856af308c" dependencies = [ "bitflags 2.10.0", "libc", @@ -3381,7 +3414,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.12.0", + "indexmap 2.13.0", "slab", "tokio", "tokio-util", @@ -3390,17 +3423,17 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" dependencies = [ "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "http 1.3.1", - "indexmap 2.12.0", + "http 1.4.0", + "indexmap 2.13.0", "slab", "tokio", "tokio-util", @@ -3445,12 +3478,13 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ "foldhash 0.2.0", "serde", + "serde_core", ] [[package]] @@ -3496,9 +3530,9 @@ dependencies = [ [[package]] name = "hex-conservative" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" +checksum = "fda06d18ac606267c40c04e41b9947729bf8b9efe74bd4e82b61a5f26a510b9f" dependencies = [ "arrayvec", ] @@ -3569,11 +3603,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -3589,12 +3623,11 @@ dependencies = [ [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "fnv", "itoa", ] @@ -3616,7 +3649,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.3.1", + "http 1.4.0", ] [[package]] @@ -3627,7 +3660,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "pin-project-lite", ] @@ -3638,10 +3671,10 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40dfebe8708af3772e3d5121077aaa18045dd9f43fc4b5046c31345cdffb7354" dependencies = [ - "axum 0.8.6", - "axum-core 0.5.5", + "axum 0.8.8", + "axum-core 0.5.6", "http-body-util", - "hyper 1.7.0", + "hyper 1.8.1", "hyper-util", "serde", "serde_json", @@ -3692,16 +3725,16 @@ dependencies = [ [[package]] name = "hyper" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" dependencies = [ "atomic-waker", "bytes", "futures-channel", "futures-core", - "h2 0.4.12", - "http 1.3.1", + "h2 0.4.13", + "http 1.4.0", "http-body 1.0.1", "httparse", "httpdate", @@ -3719,8 +3752,8 @@ version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "http 1.3.1", - "hyper 1.7.0", + "http 1.4.0", + "hyper 1.8.1", "hyper-util", "rustls", "rustls-native-certs", @@ -3728,7 +3761,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots 1.0.3", + "webpki-roots 1.0.5", ] [[package]] @@ -3737,7 +3770,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" dependencies = [ - "hyper 1.7.0", + "hyper 1.8.1", "hyper-util", "pin-project-lite", "tokio", @@ -3765,7 +3798,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.7.0", + "hyper 1.8.1", "hyper-util", "native-tls", "tokio", @@ -3775,18 +3808,18 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.17" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" dependencies = [ "base64 0.22.1", "bytes", "futures-channel", "futures-core", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", - "hyper 1.7.0", + "hyper 1.8.1", "ipnet", "libc", "percent-encoding", @@ -3871,9 +3904,9 @@ checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ "icu_collections", "icu_locale_core", @@ -3885,9 +3918,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" @@ -3962,7 +3995,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -3975,7 +4008,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -3997,12 +4030,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown 0.16.0", + "hashbrown 0.16.1", "serde", "serde_core", ] @@ -4032,9 +4065,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.43.2" +version = "1.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fdb647ebde000f43b5b53f773c30cf9b0cb4300453208713fa38b2c70935a0" +checksum = "1b66886d14d18d420ab5052cbff544fc5d34d0b2cdd35eb5976aaa10a4a472e5" dependencies = [ "console", "once_cell", @@ -4042,6 +4075,7 @@ dependencies = [ "pest_derive", "serde", "similar", + "tempfile", ] [[package]] @@ -4073,9 +4107,9 @@ checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "iri-string" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" dependencies = [ "memchr", "serde", @@ -4134,9 +4168,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jobserver" @@ -4150,9 +4184,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.82" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", @@ -4265,15 +4299,15 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.177" +version = "0.2.179" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "c5a2d376baa530d1238d133232d15e239abad80d05838b4b59354e5268af431f" [[package]] name = "libgit2-sys" -version = "0.18.2+1.9.1" +version = "0.18.3+1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c42fe03df2bd3c53a3a9c7317ad91d80c81cd1fb0caec8d7cc4cd2bfa10c222" +checksum = "c9b3acc4b91781bb0b3386669d325163746af5f6e4f73e6d2d630e09a35f3487" dependencies = [ "cc", "libc", @@ -4288,7 +4322,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if 1.0.4", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -4299,13 +4333,13 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ "bitflags 2.10.0", "libc", - "redox_syscall 0.5.18", + "redox_syscall 0.7.0", ] [[package]] @@ -4327,18 +4361,18 @@ dependencies = [ [[package]] name = "libz-rs-sys" -version = "0.5.2" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "840db8cf39d9ec4dd794376f38acc40d0fc65eec2a8f484f7fd375b84602becd" +checksum = "c10501e7805cee23da17c7790e59df2870c0d4043ec6d03f67d31e2b53e77415" dependencies = [ "zlib-rs", ] [[package]] name = "libz-sys" -version = "1.1.22" +version = "1.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" +checksum = "15d118bbf3771060e7311cc7bb0545b01d08a8b4a7de949198dec1fa0ca1c0f7" dependencies = [ "cc", "libc", @@ -4382,9 +4416,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "lru" @@ -4420,6 +4454,16 @@ dependencies = [ "libc", ] +[[package]] +name = "lzma-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" +dependencies = [ + "byteorder", + "crc", +] + [[package]] name = "lzma-sys" version = "0.1.20" @@ -4448,7 +4492,7 @@ checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -4480,7 +4524,7 @@ checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -4511,7 +4555,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad38eb12aea514a0466ea40a80fd8cc83637065948eb4a426e4aa46261175227" dependencies = [ - "rustix 1.1.2", + "rustix 1.1.3", ] [[package]] @@ -4602,9 +4646,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", "wasi", @@ -4634,14 +4678,14 @@ dependencies = [ "cfg-if 1.0.4", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] name = "moka" -version = "0.12.11" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8261cd88c312e0004c1d51baad2980c66528dfdb2bee62003e643a4d8f86b077" +checksum = "a3dec6bd31b08944e08b58fd99373893a6c17054d6f3ea5006cc894f4f4eee2a" dependencies = [ "crossbeam-channel", "crossbeam-epoch", @@ -4649,7 +4693,6 @@ dependencies = [ "equivalent", "parking_lot 0.12.5", "portable-atomic", - "rustc_version 0.4.1", "smallvec", "tagptr", "uuid", @@ -4668,7 +4711,7 @@ dependencies = [ "attestation", "borsh", "dcap-qvl", - "derive_more 2.0.1", + "derive_more 2.1.1", "hex", "include-measurements", "mpc-primitives", @@ -4691,7 +4734,7 @@ dependencies = [ "contract-history", "contract-interface", "curve25519-dalek", - "derive_more 2.0.1", + "derive_more 2.1.1", "digest 0.10.7", "ecdsa", "elliptic-curve", @@ -4704,7 +4747,7 @@ dependencies = [ "mpc-contract", "mpc-primitives", "near-abi", - "near-account-id 2.0.0", + "near-account-id 2.5.0", "near-sdk", "near-workspaces", "rand 0.8.5", @@ -4722,7 +4765,7 @@ dependencies = [ "threshold-signatures", "tokio", "utilities", - "zstd 0.13.3", + "zstd", ] [[package]] @@ -4739,7 +4782,7 @@ dependencies = [ "futures", "hex", "mpc-contract", - "near-account-id 2.0.0", + "near-account-id 2.5.0", "near-crypto 0.28.0", "near-jsonrpc-client 0.15.1", "near-jsonrpc-primitives 0.28.0", @@ -4747,7 +4790,7 @@ dependencies = [ "near-sdk", "node-types", "rand 0.9.2", - "reqwest 0.12.24", + "reqwest 0.12.28", "serde", "serde_json", "serde_yaml", @@ -4772,7 +4815,7 @@ dependencies = [ "built", "clap", "contract-interface", - "derive_more 2.0.1", + "derive_more 2.1.1", "ed25519-dalek", "flume", "futures", @@ -4782,12 +4825,11 @@ dependencies = [ "hyper 0.14.32", "itertools 0.12.1", "k256", - "lru 0.12.5", "mockall", "mpc-attestation", "mpc-contract", "mpc-tls", - "near-account-id 2.0.0", + "near-account-id 2.5.0", "near-async", "near-client", "near-config-utils 2.10.3", @@ -4830,7 +4872,7 @@ name = "mpc-primitives" version = "3.2.0" dependencies = [ "borsh", - "derive_more 2.0.1", + "derive_more 2.1.1", "hex", "rand 0.8.5", "schemars 0.8.22", @@ -4868,7 +4910,7 @@ checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -4902,7 +4944,7 @@ dependencies = [ "libc", "log", "openssl", - "openssl-probe", + "openssl-probe 0.1.6", "openssl-sys", "schannel", "security-framework 2.11.1", @@ -4912,9 +4954,9 @@ dependencies = [ [[package]] name = "near-abi" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c49593c9e94454a2368a4c0a511bf4bf1413aff4d23f16e1d8f4e64b5215351" +checksum = "2fe0c8cdaf8369d8c78f2577d95673007c7f256c85752a66672be5244e2681a6" dependencies = [ "borsh", "schemars 0.8.22", @@ -4969,15 +5011,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "975bb8e272af403d97656893f71e095e1b178ccee571b3ec4a193152be0248f5" dependencies = [ "borsh", - "schemars 0.8.22", "serde", ] [[package]] name = "near-account-id" -version = "2.0.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7d8c37ea9408d536af7e998bd0d4f9699de1f6b0d12280d28ae46977c4501" +checksum = "91f75ff8eee73815c247d0e17f3c0b705f0e993922a5548acd2ad377aeb67fca" dependencies = [ "borsh", "schemars 0.8.22", @@ -5010,7 +5051,7 @@ source = "git+https://github.com/near/nearcore?tag=2.10.3#3caaf44631859fb8a962b7 dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -5104,7 +5145,7 @@ dependencies = [ "anyhow", "bytesize", "chrono", - "derive_more 2.0.1", + "derive_more 2.1.1", "near-config-utils 0.31.1", "near-crypto 0.31.1", "near-parameters 0.31.1", @@ -5128,7 +5169,7 @@ dependencies = [ "anyhow", "bytesize", "chrono", - "derive_more 2.0.1", + "derive_more 2.1.1", "near-config-utils 2.10.3", "near-crypto 2.10.3", "near-o11y", @@ -5233,7 +5274,7 @@ dependencies = [ "rayon", "reed-solomon-erasure", "regex", - "reqwest 0.12.24", + "reqwest 0.12.28", "rust-s3", "serde", "serde_json", @@ -5288,6 +5329,18 @@ dependencies = [ "tracing", ] +[[package]] +name = "near-config-utils" +version = "0.34.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d501df6fa01064f325daaf19329183a4cd1ad54b7a1b5b8b0281b07f7e7c540" +dependencies = [ + "anyhow", + "json_comments", + "thiserror 2.0.17", + "tracing", +] + [[package]] name = "near-config-utils" version = "2.10.3" @@ -5335,7 +5388,7 @@ dependencies = [ "borsh", "bs58 0.4.0", "curve25519-dalek", - "derive_more 2.0.1", + "derive_more 2.1.1", "ed25519-dalek", "hex", "near-account-id 1.1.4", @@ -5351,6 +5404,31 @@ dependencies = [ "thiserror 2.0.17", ] +[[package]] +name = "near-crypto" +version = "0.34.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c8bfbd0f159e817402936e188bdd1d38167b0679c7693652f5199b5a36bc804" +dependencies = [ + "blake2", + "borsh", + "bs58 0.4.0", + "curve25519-dalek", + "derive_more 2.1.1", + "ed25519-dalek", + "hex", + "near-account-id 2.5.0", + "near-config-utils 0.34.3", + "near-schema-checker-lib 0.34.3", + "near-stdx 0.34.3", + "primitive-types 0.10.1", + "secp256k1 0.27.0", + "serde", + "serde_json", + "subtle", + "thiserror 2.0.17", +] + [[package]] name = "near-crypto" version = "2.10.3" @@ -5360,10 +5438,10 @@ dependencies = [ "borsh", "bs58 0.4.0", "curve25519-dalek", - "derive_more 2.0.1", + "derive_more 2.1.1", "ed25519-dalek", "hex", - "near-account-id 2.0.0", + "near-account-id 2.5.0", "near-config-utils 2.10.3", "near-schema-checker-lib 2.10.3", "near-stdx 2.10.3", @@ -5438,7 +5516,7 @@ dependencies = [ "near-chain-configs 2.10.3", "object_store", "percent-encoding", - "reqwest 0.12.24", + "reqwest 0.12.28", "rust-s3", "serde", "serde_json", @@ -5463,6 +5541,15 @@ dependencies = [ "near-primitives-core 0.31.1", ] +[[package]] +name = "near-fmt" +version = "0.34.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb22e3081a4d0de5795cf0f44b1152ec70bb31a95d6f463e723d9a81e9aac50" +dependencies = [ + "near-primitives-core 0.34.3", +] + [[package]] name = "near-fmt" version = "2.10.3" @@ -5473,9 +5560,9 @@ dependencies = [ [[package]] name = "near-gas" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ca4044222f2f392ab61d27d0aefc5106b1ece4dcd22c5c987e3c75371d2a37" +checksum = "1cecd5d9463587f34f2b7ff4c7104297483a543be8a68a4a04a8ac96c419d1a1" dependencies = [ "borsh", "schemars 0.8.22", @@ -5523,7 +5610,7 @@ name = "near-jsonrpc" version = "2.10.3" source = "git+https://github.com/near/nearcore?tag=2.10.3#3caaf44631859fb8a962b70c883f699bcc10f318" dependencies = [ - "axum 0.8.6", + "axum 0.8.8", "bs58 0.4.0", "easy-ext", "near-async", @@ -5555,7 +5642,7 @@ dependencies = [ "near-crypto 0.28.0", "near-jsonrpc-primitives 0.28.0", "near-primitives 0.28.0", - "reqwest 0.12.24", + "reqwest 0.12.28", "serde", "serde_json", "thiserror 2.0.17", @@ -5574,7 +5661,7 @@ dependencies = [ "near-crypto 0.31.1", "near-jsonrpc-primitives 0.31.1", "near-primitives 0.31.1", - "reqwest 0.12.24", + "reqwest 0.12.28", "serde", "serde_json", "thiserror 2.0.17", @@ -5588,7 +5675,7 @@ dependencies = [ "futures", "near-jsonrpc-primitives 2.10.3", "near-primitives 2.10.3", - "reqwest 0.12.24", + "reqwest 0.12.28", "serde", "serde_json", "url", @@ -5652,7 +5739,7 @@ name = "near-mainnet-res" version = "2.10.3" source = "git+https://github.com/near/nearcore?tag=2.10.3#3caaf44631859fb8a962b70c883f699bcc10f318" dependencies = [ - "near-account-id 2.0.0", + "near-account-id 2.5.0", "near-chain-configs 2.10.3", "near-primitives 2.10.3", "serde_json", @@ -5764,6 +5851,25 @@ dependencies = [ "thiserror 2.0.17", ] +[[package]] +name = "near-parameters" +version = "0.34.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10010e4e9badbb7608bf7feddf99027a954dcdfc64439f0f86a014c6277bfe53" +dependencies = [ + "borsh", + "enum-map", + "near-account-id 2.5.0", + "near-primitives-core 0.34.3", + "near-schema-checker-lib 0.34.3", + "num-rational", + "serde", + "serde_repr", + "serde_yaml", + "strum 0.24.1", + "thiserror 2.0.17", +] + [[package]] name = "near-parameters" version = "2.10.3" @@ -5771,7 +5877,7 @@ source = "git+https://github.com/near/nearcore?tag=2.10.3#3caaf44631859fb8a962b7 dependencies = [ "borsh", "enum-map", - "near-account-id 2.0.0", + "near-account-id 2.5.0", "near-primitives-core 2.10.3", "near-schema-checker-lib 2.10.3", "num-rational", @@ -5797,7 +5903,7 @@ version = "2.10.3" source = "git+https://github.com/near/nearcore?tag=2.10.3#3caaf44631859fb8a962b70c883f699bcc10f318" dependencies = [ "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -5851,7 +5957,7 @@ dependencies = [ "strum 0.24.1", "thiserror 2.0.17", "tracing", - "zstd 0.13.3", + "zstd", ] [[package]] @@ -5867,7 +5973,7 @@ dependencies = [ "bytes", "bytesize", "chrono", - "derive_more 2.0.1", + "derive_more 2.1.1", "easy-ext", "enum-map", "hex", @@ -5892,7 +5998,47 @@ dependencies = [ "strum 0.24.1", "thiserror 2.0.17", "tracing", - "zstd 0.13.3", + "zstd", +] + +[[package]] +name = "near-primitives" +version = "0.34.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ffba1d49adc30ec0808d1aef3cc2a3395ade82a99216ef3cf387355c7b46658" +dependencies = [ + "arbitrary", + "base64 0.21.7", + "bitvec", + "borsh", + "bytes", + "bytesize", + "chrono", + "derive_more 2.1.1", + "easy-ext", + "enum-map", + "hex", + "itertools 0.14.0", + "near-crypto 0.34.3", + "near-fmt 0.34.3", + "near-parameters 0.34.3", + "near-primitives-core 0.34.3", + "near-schema-checker-lib 0.34.3", + "near-stdx 0.34.3", + "near-time 0.34.3", + "num-rational", + "ordered-float", + "primitive-types 0.10.1", + "serde", + "serde_json", + "serde_with", + "sha3", + "smallvec", + "smart-default 0.7.1", + "strum 0.24.1", + "thiserror 2.0.17", + "tracing", + "zstd", ] [[package]] @@ -5907,7 +6053,7 @@ dependencies = [ "bytes", "bytesize", "chrono", - "derive_more 2.0.1", + "derive_more 2.1.1", "easy-ext", "enum-map", "hex", @@ -5934,7 +6080,7 @@ dependencies = [ "strum 0.24.1", "thiserror 2.0.17", "tracing", - "zstd 0.13.3", + "zstd", ] [[package]] @@ -5968,7 +6114,7 @@ dependencies = [ "base64 0.21.7", "borsh", "bs58 0.4.0", - "derive_more 2.0.1", + "derive_more 2.1.1", "enum-map", "near-account-id 1.1.4", "near-schema-checker-lib 0.31.1", @@ -5979,6 +6125,30 @@ dependencies = [ "thiserror 2.0.17", ] +[[package]] +name = "near-primitives-core" +version = "0.34.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "becb94101c8b7883231a027a0aec85e4f92b4366a17a665d9b68a852937d2bdd" +dependencies = [ + "arbitrary", + "base64 0.21.7", + "borsh", + "bs58 0.4.0", + "derive_more 2.1.1", + "enum-map", + "near-account-id 2.5.0", + "near-gas", + "near-schema-checker-lib 0.34.3", + "near-token", + "num-rational", + "serde", + "serde_repr", + "serde_with", + "sha2", + "thiserror 2.0.17", +] + [[package]] name = "near-primitives-core" version = "2.10.3" @@ -5988,9 +6158,9 @@ dependencies = [ "base64 0.21.7", "borsh", "bs58 0.4.0", - "derive_more 2.0.1", + "derive_more 2.1.1", "enum-map", - "near-account-id 2.0.0", + "near-account-id 2.5.0", "near-gas", "near-schema-checker-lib 2.10.3", "near-token", @@ -6007,12 +6177,12 @@ name = "near-rosetta-rpc" version = "2.10.3" source = "git+https://github.com/near/nearcore?tag=2.10.3#3caaf44631859fb8a962b70c883f699bcc10f318" dependencies = [ - "axum 0.8.6", - "derive_more 2.0.1", + "axum 0.8.8", + "derive_more 2.1.1", "futures", "hex", "insta", - "near-account-id 2.0.0", + "near-account-id 2.5.0", "near-async", "near-chain-configs 2.10.3", "near-client", @@ -6035,14 +6205,13 @@ dependencies = [ [[package]] name = "near-sandbox-utils" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66ea2772bc3fb37be43b52c57c0a998b1add4675e609fd89113c600c7c016443" +checksum = "0479c989de7c9c99c849fe452181a9a2d9826eaebd737a562e76627e2ba0ccdc" dependencies = [ "anyhow", "binary-install", - "fs2", - "home", + "fs4", "tokio", ] @@ -6058,6 +6227,12 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3515d1bd55d87bfb392f6889313dcfbcaaec4229bb4a4abb5640ab8dc5eda70c" +[[package]] +name = "near-schema-checker-core" +version = "0.34.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f5700f8f5b38507eb01769c3f761a481aa0ff5ab18fd98d8c3c9d14f231e04b" + [[package]] name = "near-schema-checker-core" version = "2.10.3" @@ -6083,6 +6258,16 @@ dependencies = [ "near-schema-checker-macro 0.31.1", ] +[[package]] +name = "near-schema-checker-lib" +version = "0.34.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd90923ed5ef5e6ed2c18e2effeaa4bf53398f6dfd25493fc1494d6e44df6b57" +dependencies = [ + "near-schema-checker-core 0.34.3", + "near-schema-checker-macro 0.34.3", +] + [[package]] name = "near-schema-checker-lib" version = "2.10.3" @@ -6104,6 +6289,12 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dc45bb3760350de7f957c11827e1e20c5a4aff8d95d19fd2c0c492d795bfb02" +[[package]] +name = "near-schema-checker-macro" +version = "0.34.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff9a4b5c2a27926b14465dd7cc06a9f801f8892de9ee8576b421c7d00f6320" + [[package]] name = "near-schema-checker-macro" version = "2.10.3" @@ -6111,24 +6302,24 @@ source = "git+https://github.com/near/nearcore?tag=2.10.3#3caaf44631859fb8a962b7 [[package]] name = "near-sdk" -version = "5.18.1" +version = "5.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab0fa9255055e9715ff7c4bffc819772ed757af13a2583dbdbd982db897b4769" +checksum = "b5188eba9ee0383c2a28afee994e65c21e98823d18a32b8b3a7c8d6cdedfb119" dependencies = [ "base64 0.22.1", "borsh", "bs58 0.5.1", "near-abi", - "near-account-id 1.1.4", - "near-crypto 0.31.1", + "near-account-id 2.5.0", + "near-crypto 0.34.3", "near-gas", - "near-parameters 0.31.1", - "near-primitives 0.31.1", - "near-primitives-core 0.31.1", + "near-parameters 0.34.3", + "near-primitives 0.34.3", + "near-primitives-core 0.34.3", "near-sdk-macros", "near-sys", "near-token", - "near-vm-runner 0.31.1", + "near-vm-runner 0.34.3", "once_cell", "schemars 0.8.22", "serde", @@ -6139,9 +6330,9 @@ dependencies = [ [[package]] name = "near-sdk-macros" -version = "5.18.1" +version = "5.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c349917f79b2df2a94eff6409fc74722918e471835cb62edd0eb084f4ea7feb" +checksum = "e4339b75a514ca2e6b67379be62a441f7e99a2c3813278f1b23d233b300f9f4f" dependencies = [ "Inflector", "darling 0.20.11", @@ -6151,7 +6342,7 @@ dependencies = [ "serde_json", "strum 0.26.3", "strum_macros 0.26.4", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -6166,6 +6357,12 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e3c38fc0843ef7c5bca717cc4daaf2af05441c3cb9cf259824e226387b18740" +[[package]] +name = "near-stdx" +version = "0.34.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b28b47d44e10c45054bcc023dfda154f13f5b8e980ad25ee94cd32207d463b78" + [[package]] name = "near-stdx" version = "2.10.3" @@ -6182,7 +6379,7 @@ dependencies = [ "crossbeam", "dashmap", "derive-where", - "derive_more 2.0.1", + "derive_more 2.1.1", "enum-map", "hex", "itertools 0.14.0", @@ -6221,9 +6418,9 @@ dependencies = [ [[package]] name = "near-sys" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64e114297f37c94aa20df6a6f92822a1b41da76b4961298caf08ba80b7779b2" +checksum = "b99e9ce0020190ea152f70d1849e54fc8fc123738e7447800ad818c78f5167cc" [[package]] name = "near-telemetry" @@ -6235,7 +6432,7 @@ dependencies = [ "near-o11y", "near-performance-metrics", "near-performance-metrics-macros", - "reqwest 0.12.24", + "reqwest 0.12.28", "serde", "serde_json", "tracing", @@ -6262,6 +6459,17 @@ dependencies = [ "time", ] +[[package]] +name = "near-time" +version = "0.34.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5974d008afcd280363411fc1bde76b2c3d36d6c707694bd93d68ceb2a25f2dfe" +dependencies = [ + "parking_lot 0.12.5", + "serde", + "time", +] + [[package]] name = "near-time" version = "2.10.3" @@ -6275,9 +6483,9 @@ dependencies = [ [[package]] name = "near-token" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "133a293baa70b78db8c4325753ca8012f84e67de6c84c013960722a937985615" +checksum = "34de6b54d82d0790b2a56b677e7b4ecb7f021a7e8559f8611065c890d56cfcda" dependencies = [ "borsh", "schemars 0.8.22", @@ -6333,16 +6541,16 @@ dependencies = [ "parking_lot 0.12.5", "rkyv", "rustc-demangle", - "rustix 1.1.2", + "rustix 1.1.3", "thiserror 2.0.17", "tracing", ] [[package]] name = "near-vm-runner" -version = "0.31.1" +version = "0.34.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ddefc8e4460b2c080b34f800b0bd06fd971b37d64ec7279552d792468228924" +checksum = "a806f05174cc99052ad974d054aa4416dc4c6b09be728ab0a02b07539643f8c9" dependencies = [ "blst", "borsh", @@ -6350,17 +6558,17 @@ dependencies = [ "ed25519-dalek", "enum-map", "lru 0.12.5", - "near-crypto 0.31.1", - "near-parameters 0.31.1", - "near-primitives-core 0.31.1", - "near-schema-checker-lib 0.31.1", - "near-stdx 0.31.1", + "near-crypto 0.34.3", + "near-parameters 0.34.3", + "near-primitives-core 0.34.3", + "near-schema-checker-lib 0.34.3", + "near-stdx 0.34.3", "num-rational", "parking_lot 0.12.5", "rand 0.8.5", "rayon", "ripemd", - "rustix 1.1.2", + "rustix 1.1.3", "serde", "sha2", "sha3", @@ -6404,7 +6612,7 @@ dependencies = [ "rand 0.8.5", "rayon", "ripemd", - "rustix 1.1.2", + "rustix 1.1.3", "serde", "sha2", "sha3", @@ -6424,7 +6632,7 @@ name = "near-vm-types" version = "2.10.3" source = "git+https://github.com/near/nearcore?tag=2.10.3#3caaf44631859fb8a962b70c883f699bcc10f318" dependencies = [ - "indexmap 2.12.0", + "indexmap 2.13.0", "num-traits", "rkyv", "thiserror 2.0.17", @@ -6484,7 +6692,7 @@ dependencies = [ "near-sandbox-utils", "near-token", "rand 0.8.5", - "reqwest 0.12.24", + "reqwest 0.12.28", "serde", "serde_json", "sha2", @@ -6565,7 +6773,7 @@ dependencies = [ "num-rational", "parking_lot 0.12.5", "rand 0.8.5", - "reqwest 0.12.24", + "reqwest 0.12.28", "serde", "serde_ignored", "serde_json", @@ -6741,9 +6949,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "nybbles" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c4b5ecbd0beec843101bffe848217f770e8b8da81d8355b7d6e226f2199b3dc" +checksum = "7b5676b5c379cf5b03da1df2b3061c4a4e2aa691086a56ac923e08c143f53f59" dependencies = [ "alloy-rlp", "cfg-if 1.0.4", @@ -6761,7 +6969,7 @@ checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "crc32fast", "hashbrown 0.15.5", - "indexmap 2.12.0", + "indexmap 2.13.0", "memchr", ] @@ -6777,16 +6985,16 @@ dependencies = [ "chrono", "form_urlencoded", "futures", - "http 1.3.1", + "http 1.4.0", "http-body-util", "humantime", - "hyper 1.7.0", + "hyper 1.8.1", "itertools 0.14.0", "parking_lot 0.12.5", "percent-encoding", "quick-xml", "rand 0.9.2", - "reqwest 0.12.24", + "reqwest 0.12.28", "ring", "rustls-pemfile 2.2.0", "serde", @@ -6840,9 +7048,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.74" +version = "0.10.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" dependencies = [ "bitflags 2.10.0", "cfg-if 1.0.4", @@ -6861,7 +7069,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -6870,6 +7078,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +[[package]] +name = "openssl-probe" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" + [[package]] name = "openssl-src" version = "300.5.4+3.5.4" @@ -6881,9 +7095,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.110" +version = "0.9.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" dependencies = [ "cc", "libc", @@ -6912,7 +7126,7 @@ version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbee664a43e07615731afc539ca60c6d9f1a9425e25ca09c57bc36c87c55852b" dependencies = [ - "http 1.3.1", + "http 1.4.0", "opentelemetry", "opentelemetry-proto", "opentelemetry_sdk", @@ -7014,7 +7228,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -7068,18 +7282,7 @@ dependencies = [ "libc", "redox_syscall 0.5.18", "smallvec", - "windows-link 0.2.1", -] - -[[package]] -name = "password-hash" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", + "windows-link", ] [[package]] @@ -7099,14 +7302,12 @@ dependencies = [ [[package]] name = "pbkdf2" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest 0.10.7", "hmac", - "password-hash", - "sha2", ] [[package]] @@ -7142,9 +7343,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.3" +version = "2.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4" +checksum = "2c9eb05c21a464ea704b53158d358a31e6425db2f63a1a7312268b05fe2b75f7" dependencies = [ "memchr", "ucd-trie", @@ -7152,9 +7353,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.8.3" +version = "2.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "187da9a3030dbafabbbfb20cb323b976dc7b7ce91fcd84f2f74d6e31d378e2de" +checksum = "68f9dbced329c441fa79d80472764b1a2c7e57123553b8519b36663a2fb234ed" dependencies = [ "pest", "pest_generator", @@ -7162,22 +7363,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.3" +version = "2.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b401d98f5757ebe97a26085998d6c0eecec4995cad6ab7fc30ffdf4b052843" +checksum = "3bb96d5051a78f44f43c8f712d8e810adb0ebf923fc9ed2655a7f66f63ba8ee5" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] name = "pest_meta" -version = "2.8.3" +version = "2.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f27a2cfee9f9039c4d86faa5af122a0ac3851441a34865b8a043b46be0065a" +checksum = "602113b5b5e8621770cfd490cfd90b9f84ab29bd2b0e49ad83eb6d186cef2365" dependencies = [ "pest", "sha2", @@ -7220,7 +7421,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -7265,9 +7466,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" [[package]] name = "postcard" @@ -7355,7 +7556,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -7431,14 +7632,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" dependencies = [ "unicode-ident", ] @@ -7506,7 +7707,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -7519,7 +7720,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -7573,7 +7774,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4aeaa1f2460f1d348eeaeed86aea999ce98c1bded6f089ff8514c9d9dbdc973" dependencies = [ "anyhow", - "indexmap 2.12.0", + "indexmap 2.13.0", "log", "protobuf", "protobuf-support", @@ -7608,7 +7809,7 @@ checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -7631,7 +7832,7 @@ checksum = "0b4b4aee26ad4085bcde356a00853e11fe1f06f4ae0d27a1cdfac9dd2529fa62" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -7642,9 +7843,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quick-xml" -version = "0.38.3" +version = "0.38.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a232e7487fc2ef313d96dde7948e7a3c05101870d8985e4fd8d26aedd27b89" +checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" dependencies = [ "memchr", "serde", @@ -7707,9 +7908,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.41" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" dependencies = [ "proc-macro2", ] @@ -7834,6 +8035,15 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rapidhash" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2988730ee014541157f48ce4dcc603940e00915edc3c7f9a8d78092256bb2493" +dependencies = [ + "rustversion", +] + [[package]] name = "rayon" version = "1.11.0" @@ -7885,6 +8095,15 @@ dependencies = [ "bitflags 2.10.0", ] +[[package]] +name = "redox_syscall" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" +dependencies = [ + "bitflags 2.10.0", +] + [[package]] name = "redox_users" version = "0.4.6" @@ -7928,7 +8147,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -8045,23 +8264,22 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.24" +version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ - "async-compression", "base64 0.22.1", "bytes", "encoding_rs", "futures-channel", "futures-core", "futures-util", - "h2 0.4.12", + "h2 0.4.13", "hickory-resolver", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.7.0", + "hyper 1.8.1", "hyper-rustls", "hyper-tls 0.6.0", "hyper-util", @@ -8093,14 +8311,14 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 1.0.3", + "webpki-roots 1.0.5", ] [[package]] name = "resolv-conf" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b3789b30bd25ba102de4beabd95d21ac45b69b1be7d14522bab988c526d6799" +checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7" [[package]] name = "rfc6979" @@ -8143,8 +8361,8 @@ checksum = "8b2e88acca7157d83d789836a3987dafc12bc3d88a050e54b8fe9ea4aaa29d20" dependencies = [ "bytecheck", "bytes", - "hashbrown 0.16.0", - "indexmap 2.12.0", + "hashbrown 0.16.1", + "indexmap 2.13.0", "munge", "ptr_meta", "rancor", @@ -8162,7 +8380,7 @@ checksum = "7f6dffea3c91fa91a3c0fc8a061b0e27fef25c6304728038a6d6bcb1c58ba9bd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -8186,22 +8404,19 @@ dependencies = [ [[package]] name = "rmp" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" +checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c" dependencies = [ - "byteorder", "num-traits", - "paste", ] [[package]] name = "rmp-serde" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" +checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155" dependencies = [ - "byteorder", "rmp", "serde", ] @@ -8242,15 +8457,15 @@ dependencies = [ "regex", "relative-path", "rustc_version 0.4.1", - "syn 2.0.108", + "syn 2.0.114", "unicode-ident", ] [[package]] name = "ruint" -version = "1.17.0" +version = "1.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a68df0380e5c9d20ce49534f292a36a7514ae21350726efe1865bdb1fa91d278" +checksum = "c141e807189ad38a07276942c6623032d3753c8859c146104ac2e4d68865945a" dependencies = [ "alloy-rlp", "ark-ff 0.3.0", @@ -8300,7 +8515,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.108", + "syn 2.0.114", "walkdir", ] @@ -8422,9 +8637,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ "bitflags 2.10.0", "errno", @@ -8435,9 +8650,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.34" +version = "0.23.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9586e9ee2b4f8fab52a0048ca7334d7024eef48e2cb9407e3497bb7cab7fa7" +checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" dependencies = [ "log", "once_cell", @@ -8450,11 +8665,11 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" dependencies = [ - "openssl-probe", + "openssl-probe 0.2.0", "rustls-pki-types", "schannel", "security-framework 3.5.1", @@ -8480,9 +8695,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a" +checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" dependencies = [ "web-time", "zeroize", @@ -8547,9 +8762,9 @@ checksum = "22a197350ece202f19a166d1ad6d9d6de145e1d2a8ef47db299abe164dbd7530" [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" [[package]] name = "same-file" @@ -8582,7 +8797,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -8629,9 +8844,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.0.4" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +checksum = "54e910108742c57a770f492731f99be216a52fadd361b06c8fb59d74ccc267d2" dependencies = [ "dyn-clone", "ref-cast", @@ -8648,7 +8863,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -8807,10 +9022,11 @@ dependencies = [ [[package]] name = "serde-human-bytes" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ef65cb41f3f9cef63c431193229067e8b98b53c4d4c4ed38a8ca87c4d07676" +checksum = "6a091af6294712930d01e375cce513e4ac416f823e033e8991ec4e5d6e6ef4c0" dependencies = [ + "base64 0.13.1", "hex", "serde", ] @@ -8854,7 +9070,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -8865,7 +9081,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -8880,16 +9096,16 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ - "indexmap 2.12.0", + "indexmap 2.13.0", "itoa", "memchr", - "ryu", "serde", "serde_core", + "zmij", ] [[package]] @@ -8911,7 +9127,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -8928,18 +9144,18 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.15.1" +version = "3.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa66c845eee442168b2c8134fec70ac50dc20e760769c8ba0ad1319ca1959b04" +checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.12.0", + "indexmap 2.13.0", "schemars 0.8.22", "schemars 0.9.0", - "schemars 1.0.4", + "schemars 1.2.0", "serde_core", "serde_json", "serde_with_macros", @@ -8948,14 +9164,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.15.1" +version = "3.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91a903660542fced4e99881aa481bdbaec1634568ee02e0b8bd57c64cb38955" +checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" dependencies = [ "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -8964,7 +9180,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.12.0", + "indexmap 2.13.0", "itoa", "ryu", "serde", @@ -8983,11 +9199,12 @@ dependencies = [ [[package]] name = "serial_test" -version = "3.2.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" +checksum = "0d0b343e184fc3b7bb44dff0705fffcf4b3756ba6aff420dddd8b24ca145e555" dependencies = [ - "futures", + "futures-executor", + "futures-util", "log", "once_cell", "parking_lot 0.12.5", @@ -8997,13 +9214,13 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "3.2.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" +checksum = "6f50427f258fb77356e4cd4aa0e87e2bd2c66dbcee41dc405282cae2bfc26c83" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -9065,10 +9282,11 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.6" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] @@ -9084,9 +9302,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" [[package]] name = "simdutf8" @@ -9162,7 +9380,7 @@ checksum = "0eb01866308440fc64d6c44d9e86c5cc17adfe33c4d6eed55da9145044d0ffc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -9271,7 +9489,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -9312,9 +9530,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.108" +version = "2.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" dependencies = [ "proc-macro2", "quote", @@ -9323,14 +9541,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff790eb176cc81bb8936aed0f7b9f14fc4670069a2d371b3e3b0ecce908b2cb3" +checksum = "5f92d01b5de07eaf324f7fca61cc6bd3d82bbc1de5b6c963e6fe79e86f36580d" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -9356,7 +9574,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -9447,9 +9665,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "target-lexicon" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" +checksum = "b1dd07eb858a2067e2f3c7155d54e929265c264e6f37efe3ee7a8d1b5a1dd0ba" [[package]] name = "tee-authority" @@ -9457,12 +9675,12 @@ version = "3.2.0" dependencies = [ "anyhow", "backon", - "derive_more 2.0.1", + "derive_more 2.1.1", "dstack-sdk", "hex", - "http 1.3.1", + "http 1.4.0", "mpc-attestation", - "reqwest 0.12.24", + "reqwest 0.12.28", "rstest", "serde", "serde_json", @@ -9473,14 +9691,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.23.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", "getrandom 0.3.4", "once_cell", - "rustix 1.1.2", + "rustix 1.1.3", "windows-sys 0.61.2", ] @@ -9562,7 +9780,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -9573,7 +9791,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -9617,7 +9835,7 @@ dependencies = [ "blstrs", "borsh", "byteorder", - "derive_more 2.0.1", + "derive_more 2.1.1", "digest 0.10.7", "ecdsa", "elliptic-curve", @@ -9731,9 +9949,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.48.0" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" dependencies = [ "bytes", "libc", @@ -9754,7 +9972,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -9790,9 +10008,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" dependencies = [ "futures-core", "pin-project-lite", @@ -9801,9 +10019,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.16" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", @@ -9815,20 +10033,20 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.3" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.23.7" +version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ - "indexmap 2.12.0", + "indexmap 2.13.0", "toml_datetime", "toml_parser", "winnow", @@ -9836,9 +10054,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ "winnow", ] @@ -9854,11 +10072,11 @@ dependencies = [ "axum 0.7.9", "base64 0.22.1", "bytes", - "h2 0.4.12", - "http 1.3.1", + "h2 0.4.13", + "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.7.0", + "hyper 1.8.1", "hyper-timeout", "hyper-util", "percent-encoding", @@ -9885,10 +10103,10 @@ dependencies = [ "async-trait", "base64 0.22.1", "bytes", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.7.0", + "hyper 1.8.1", "hyper-timeout", "hyper-util", "percent-encoding", @@ -9930,7 +10148,7 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", - "indexmap 2.12.0", + "indexmap 2.13.0", "pin-project-lite", "slab", "sync_wrapper 1.0.2", @@ -9943,18 +10161,22 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ + "async-compression", "bitflags 2.10.0", "bytes", + "futures-core", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", "iri-string", "pin-project-lite", + "tokio", + "tokio-util", "tower 0.5.2", "tower-layer", "tower-service", @@ -9987,9 +10209,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.41" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", @@ -9999,32 +10221,32 @@ dependencies = [ [[package]] name = "tracing-appender" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" dependencies = [ "crossbeam-channel", - "thiserror 1.0.69", + "thiserror 2.0.17", "time", "tracing-subscriber", ] [[package]] name = "tracing-attributes" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] name = "tracing-core" -version = "0.1.34" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -10071,9 +10293,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.20" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ "matchers", "nu-ansi-term", @@ -10108,7 +10330,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -10149,15 +10371,21 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicase" -version = "2.8.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" [[package]] name = "unicode-ident" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" @@ -10221,14 +10449,15 @@ dependencies = [ [[package]] name = "url" -version = "2.5.7" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", "serde", + "serde_derive", ] [[package]] @@ -10254,7 +10483,7 @@ name = "utilities" version = "3.2.0" dependencies = [ "near-account-id 1.1.4", - "near-account-id 2.0.0", + "near-account-id 2.5.0", ] [[package]] @@ -10263,7 +10492,7 @@ version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fcc29c80c21c31608227e0912b2d7fddba57ad76b606890627ba8ee7964e993" dependencies = [ - "indexmap 2.12.0", + "indexmap 2.13.0", "serde", "serde_json", "utoipa-gen", @@ -10277,7 +10506,7 @@ checksum = "6d79d08d92ab8af4c5e8a6da20c47ae3f61a0f1dabc1997cdf2d082b757ca08b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -10286,7 +10515,7 @@ version = "9.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d047458f1b5b65237c2f6dc6db136945667f40a7668627b3490b9513a3d43a55" dependencies = [ - "axum 0.8.6", + "axum 0.8.8", "base64 0.22.1", "mime_guess", "regex", @@ -10307,9 +10536,9 @@ checksum = "e2eebbbfe4093922c2b6734d7c679ebfebd704a0d7e56dfcb0d05818ce28977d" [[package]] name = "uuid" -version = "1.18.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ "getrandom 0.3.4", "js-sys", @@ -10342,7 +10571,7 @@ checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -10390,9 +10619,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if 1.0.4", "once_cell", @@ -10403,9 +10632,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.55" +version = "0.4.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0" +checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" dependencies = [ "cfg-if 1.0.4", "js-sys", @@ -10416,9 +10645,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -10426,22 +10655,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] @@ -10512,7 +10741,7 @@ checksum = "4abf1132c1fdf747d56bbc1bb52152400c70f336870f968b85e89ea422198ae3" dependencies = [ "bitflags 2.10.0", "hashbrown 0.15.5", - "indexmap 2.12.0", + "indexmap 2.13.0", "semver 1.0.27", "serde", ] @@ -10525,7 +10754,7 @@ checksum = "a9b1e81f3eb254cf7404a82cee6926a4a3ccc5aad80cc3d43608a070c67aa1d7" dependencies = [ "bitflags 2.10.0", "hashbrown 0.15.5", - "indexmap 2.12.0", + "indexmap 2.13.0", "semver 1.0.27", "serde", ] @@ -10564,7 +10793,7 @@ dependencies = [ "cc", "cfg-if 1.0.4", "hashbrown 0.15.5", - "indexmap 2.12.0", + "indexmap 2.13.0", "libc", "log", "mach2", @@ -10574,11 +10803,11 @@ dependencies = [ "postcard", "pulley-interpreter", "rayon", - "rustix 1.1.2", + "rustix 1.1.3", "serde", "serde_derive", "smallvec", - "target-lexicon 0.13.3", + "target-lexicon 0.13.4", "wasmparser 0.236.1", "wasmtime-environ", "wasmtime-internal-asm-macros", @@ -10603,14 +10832,14 @@ dependencies = [ "cranelift-bitset", "cranelift-entity", "gimli", - "indexmap 2.12.0", + "indexmap 2.13.0", "log", "object", "postcard", "serde", "serde_derive", "smallvec", - "target-lexicon 0.13.3", + "target-lexicon 0.13.4", "wasm-encoder 0.236.1", "wasmparser 0.236.1", "wasmprinter 0.236.1", @@ -10644,7 +10873,7 @@ dependencies = [ "object", "pulley-interpreter", "smallvec", - "target-lexicon 0.13.3", + "target-lexicon 0.13.4", "thiserror 2.0.17", "wasmparser 0.236.1", "wasmtime-environ", @@ -10662,7 +10891,7 @@ dependencies = [ "cc", "cfg-if 1.0.4", "libc", - "rustix 1.1.2", + "rustix 1.1.3", "wasmtime-internal-asm-macros", "wasmtime-internal-versioned-export-macros", "windows-sys 0.60.2", @@ -10726,14 +10955,14 @@ checksum = "0445c94839f5f76122f6be138ce7d7d53044a8b48a9305a9522460e836e51e0d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] name = "web-sys" -version = "0.3.82" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", @@ -10755,14 +10984,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.3", + "webpki-roots 1.0.5", ] [[package]] name = "webpki-roots" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" +checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c" dependencies = [ "rustls-pki-types", ] @@ -10820,9 +11049,9 @@ checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" [[package]] name = "wildmatch" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39b7d07a236abaef6607536ccfaf19b396dbe3f5110ddb73d39f4562902ed382" +checksum = "29333c3ea1ba8b17211763463ff24ee84e41c78224c16b001cd907e663a38c68" [[package]] name = "winapi" @@ -10883,9 +11112,9 @@ checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", - "windows-link 0.2.1", + "windows-link", "windows-result 0.4.1", - "windows-strings 0.5.1", + "windows-strings", ] [[package]] @@ -10896,7 +11125,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -10907,15 +11136,9 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - [[package]] name = "windows-link" version = "0.2.1" @@ -10924,13 +11147,13 @@ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-registry" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" dependencies = [ - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.4.2", + "windows-link", + "windows-result 0.4.1", + "windows-strings", ] [[package]] @@ -10942,31 +11165,13 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-result" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link 0.1.3", -] - [[package]] name = "windows-result" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link 0.2.1", -] - -[[package]] -name = "windows-strings" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" -dependencies = [ - "windows-link 0.1.3", + "windows-link", ] [[package]] @@ -10975,7 +11180,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -11020,7 +11225,7 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -11060,7 +11265,7 @@ version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link 0.2.1", + "windows-link", "windows_aarch64_gnullvm 0.53.1", "windows_aarch64_msvc 0.53.1", "windows_i686_gnu 0.53.1", @@ -11211,9 +11416,9 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] @@ -11284,7 +11489,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" dependencies = [ "libc", - "rustix 1.1.2", + "rustix 1.1.3", ] [[package]] @@ -11330,28 +11535,28 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.27" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.27" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -11371,7 +11576,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", "synstructure", ] @@ -11386,13 +11591,13 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] @@ -11438,27 +11643,37 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.114", ] [[package]] name = "zip" -version = "0.6.6" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" dependencies = [ "aes", - "byteorder", + "arbitrary", "bzip2", "constant_time_eq", "crc32fast", "crossbeam-utils", + "deflate64", + "displaydoc", "flate2", + "getrandom 0.3.4", "hmac", + "indexmap 2.13.0", + "lzma-rs", + "memchr", "pbkdf2", "sha1", + "thiserror 2.0.17", "time", - "zstd 0.11.2+zstd.1.5.2", + "xz2", + "zeroize", + "zopfli", + "zstd", ] [[package]] @@ -11470,16 +11685,22 @@ dependencies = [ "arbitrary", "crc32fast", "flate2", - "indexmap 2.12.0", + "indexmap 2.13.0", "memchr", "zopfli", ] [[package]] name = "zlib-rs" -version = "0.5.2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40990edd51aae2c2b6907af74ffb635029d5788228222c4bb811e9351c0caad3" + +[[package]] +name = "zmij" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f06ae92f42f5e5c42443fd094f245eb656abf56dd7cce9b8b263236565e00f2" +checksum = "2fc5a66a20078bf1251bde995aa2fdcc4b800c70b5d92dd2c62abc5c60f679f8" [[package]] name = "zopfli" @@ -11493,32 +11714,13 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "zstd" -version = "0.11.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" -dependencies = [ - "zstd-safe 5.0.2+zstd.1.5.2", -] - [[package]] name = "zstd" version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ - "zstd-safe 7.2.4", -] - -[[package]] -name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" -dependencies = [ - "libc", - "zstd-sys", + "zstd-safe", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index eec1158911..eac95eaaba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,7 +91,6 @@ hyper = { version = "0.14.32", features = ["server", "http1", "tcp", "stream"] } insta = { version = "1.43.1", features = ["json", "redactions"] } itertools = "0.12.1" k256 = "0.13.4" -lru = "0.12.5" mockall = "0.13.1" near-abi = "0.4.3" near-account-id = "2.0.0" diff --git a/crates/node/Cargo.toml b/crates/node/Cargo.toml index 933e5b7425..c2a3b83346 100644 --- a/crates/node/Cargo.toml +++ b/crates/node/Cargo.toml @@ -29,7 +29,6 @@ humantime = { workspace = true } hyper = { workspace = true } itertools = { workspace = true } k256 = { workspace = true } -lru = { workspace = true } mpc-attestation = { workspace = true } mpc-contract = { workspace = true } mpc-tls = { workspace = true } diff --git a/deny.toml b/deny.toml index 003d1ed43b..9a7fcf705e 100644 --- a/deny.toml +++ b/deny.toml @@ -30,12 +30,19 @@ ignore = [ # - `ruint::algorithms::div::reciprocal_mg10` has undefined behavior, no fix available as of now. # - `ruint` is a transitive dependency through `alloy`. # - The affected function is unused in alloy (ref: recmo/uint#550, alloy-rs/alloy#3416). - "RUSTSEC-2025-0137", + "RUSTSEC-2026-0002", # lru unsound advisory - transitive via nearcore@2.10.3 ] [bans] multiple-versions = "deny" -skip = [{ name = "prost-types" }] +skip = [ + { name = "prost-types" }, + # near-sdk v5.24.0 pulls in old near-primitives/near-fmt/near-time (0.34.3) + # while nearcore v2.10.3 pulls in newer versions (2.10.3) + { name = "near-fmt" }, + { name = "near-primitives" }, + { name = "near-time" }, +] skip-tree = [ { name = "reqwest" }, { name = "axum" }, From 88049e9f3ce4bdc625ddbbcaf2b9121fa58fc512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Wed, 7 Jan 2026 19:09:31 +0100 Subject: [PATCH 29/45] Revert "Remove lru dependency from Cargo.toml files and update deny.toml to address advisory RUSTSEC-2026-0002. Added skips for near-sdk related dependencies to resolve version conflicts." This reverts commit 57ac85644fc35fc33a8ba04dce93f8b60aca379b. --- Cargo.lock | 1458 +++++++++++++++++----------------------- Cargo.toml | 1 + crates/node/Cargo.toml | 1 + deny.toml | 11 +- 4 files changed, 632 insertions(+), 839 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d303ecaf41..65b14b08b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,9 +90,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy" -version = "1.3.0" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf23ee5a0d40c75ade22bf33f117058461fc30a95e84d48b01c845c28f4ea7c5" +checksum = "ae62e633fa48b4190af5e841eb05179841bb8b713945103291e2c0867037c0d1" dependencies = [ "alloy-core", "alloy-signer", @@ -101,9 +101,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "1.3.0" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41e46a465e50a339a817070ec23f06eb3fc9fbb8af71612868367b875a9d49e3" +checksum = "b9b151e38e42f1586a01369ec52a6934702731d07e8509a7307331b09f6c46dc" dependencies = [ "alloy-eips", "alloy-primitives", @@ -112,9 +112,8 @@ dependencies = [ "alloy-trie", "alloy-tx-macros", "auto_impl", - "borsh", "c-kzg", - "derive_more 2.1.1", + "derive_more 2.0.1", "either", "k256", "once_cell", @@ -128,9 +127,9 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "1.3.0" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07001b1693af794c7526aab400b42e38075f986ef8fef78841e5ebc745473e56" +checksum = "6e2d5e8668ef6215efdb7dcca6f22277b4e483a5650e05f5de22b2350971f4b8" dependencies = [ "alloy-consensus", "alloy-eips", @@ -142,9 +141,9 @@ dependencies = [ [[package]] name = "alloy-core" -version = "1.5.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d4087016b0896051dd3d03e0bedda2f4d4d1689af8addc8450288c63a9e5f68" +checksum = "5ca96214615ec8cf3fa2a54b32f486eb49100ca7fe7eb0b8c1137cd316e7250a" dependencies = [ "alloy-primitives", ] @@ -164,34 +163,32 @@ dependencies = [ [[package]] name = "alloy-eip2930" -version = "0.2.3" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9441120fa82df73e8959ae0e4ab8ade03de2aaae61be313fbf5746277847ce25" +checksum = "7b82752a889170df67bbb36d42ca63c531eb16274f0d7299ae2a680facba17bd" dependencies = [ "alloy-primitives", "alloy-rlp", - "borsh", "serde", ] [[package]] name = "alloy-eip7702" -version = "0.6.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2919c5a56a1007492da313e7a3b6d45ef5edc5d33416fdec63c0d7a2702a0d20" +checksum = "9d4769c6ffddca380b0070d71c8b7f30bed375543fe76bb2f74ec0acf4b7cd16" dependencies = [ "alloy-primitives", "alloy-rlp", - "borsh", "serde", "thiserror 2.0.17", ] [[package]] name = "alloy-eips" -version = "1.3.0" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707337efeb051ddbaece17a73eaec5150945a5a5541112f4146508248edc2e40" +checksum = "e5434834adaf64fa20a6fb90877bc1d33214c41b055cc49f82189c98614368cc" dependencies = [ "alloy-eip2124", "alloy-eip2930", @@ -200,9 +197,8 @@ dependencies = [ "alloy-rlp", "alloy-serde", "auto_impl", - "borsh", "c-kzg", - "derive_more 2.1.1", + "derive_more 2.0.1", "either", "serde", "serde_with", @@ -212,9 +208,9 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "1.5.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84e3cf01219c966f95a460c95f1d4c30e12f6c18150c21a30b768af2a2a29142" +checksum = "5513d5e6bd1cba6bdcf5373470f559f320c05c8c59493b6e98912fbe6733943f" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -224,13 +220,13 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "1.3.0" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48562f9b4c4e1514cab54af16feaffc18194a38216bbd0c23004ec4667ad696b" +checksum = "d7c69f6c9c68a1287c9d5ff903d0010726934de0dac10989be37b75a29190d55" dependencies = [ "alloy-primitives", "alloy-sol-types", - "http 1.4.0", + "http 1.3.1", "serde", "serde_json", "thiserror 2.0.17", @@ -239,9 +235,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "1.3.0" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "364a5eaa598437d7a57bcbcb4b7fcb0518e192cf809a19b09b2b5cf73b9ba1cd" +checksum = "8eaf2ae05219e73e0979cb2cf55612aafbab191d130f203079805eaf881cca58" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -256,7 +252,7 @@ dependencies = [ "alloy-sol-types", "async-trait", "auto_impl", - "derive_more 2.1.1", + "derive_more 2.0.1", "futures-utils-wasm", "serde", "serde_json", @@ -265,9 +261,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "1.3.0" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21af5255bd276e528ee625d97033884916e879a1c6edcd5b70a043bd440c0710" +checksum = "e58f4f345cef483eab7374f2b6056973c7419ffe8ad35e994b7a7f5d8e0c7ba4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -278,25 +274,24 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "1.5.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6a0fb18dd5fb43ec5f0f6a20be1ce0287c79825827de5744afaa6c957737c33" +checksum = "355bf68a433e0fd7f7d33d5a9fc2583fde70bf5c530f63b80845f8da5505cf28" dependencies = [ "alloy-rlp", "bytes", "cfg-if 1.0.4", "const-hex", - "derive_more 2.1.1", + "derive_more 2.0.1", "foldhash 0.2.0", - "hashbrown 0.16.1", - "indexmap 2.13.0", + "hashbrown 0.16.0", + "indexmap 2.12.0", "itoa", "k256", "keccak-asm", "paste", "proptest", "rand 0.9.2", - "rapidhash", "ruint", "rustc-hash 2.1.1", "serde", @@ -323,14 +318,14 @@ checksum = "64b728d511962dda67c1bc7ea7c03736ec275ed2cf4c35d9585298ac9ccf3b73" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] name = "alloy-rpc-types-any" -version = "1.3.0" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ebc96cf29095c10a183fb7106a097fe12ca8dd46733895582da255407f54b29" +checksum = "fbde0801a32d21c5f111f037bee7e22874836fba7add34ed4a6919932dd7cf23" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", @@ -339,9 +334,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "1.3.0" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cc3f354a5079480acca0a6533d1d3838177a03ea494ef0ae8d1679efea88274" +checksum = "361cd87ead4ba7659bda8127902eda92d17fa7ceb18aba1676f7be10f7222487" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -360,9 +355,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "1.3.0" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a438ce4cd49ec4bc213868c1fe94f2fe103d4c3f22f6a42073db974f9c0962da" +checksum = "64600fc6c312b7e0ba76f73a381059af044f4f21f43e07f51f1fa76c868fe302" dependencies = [ "alloy-primitives", "serde", @@ -371,9 +366,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "1.3.0" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389372d6ae4d62b88c8dca8238e4f7d0a7727b66029eb8a5516a908a03161450" +checksum = "5772858492b26f780468ae693405f895d6a27dea6e3eab2c36b6217de47c2647" dependencies = [ "alloy-primitives", "async-trait", @@ -386,9 +381,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "1.3.0" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69c260e78b9c104c444f8a202f283d5e8c6637e6fa52a83f649ad6aaa0b91fd0" +checksum = "f4195b803d0a992d8dbaab2ca1986fc86533d4bc80967c0cce7668b26ad99ef9" dependencies = [ "alloy-consensus", "alloy-network", @@ -402,41 +397,41 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "1.5.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09eb18ce0df92b4277291bbaa0ed70545d78b02948df756bbd3d6214bf39a218" +checksum = "f3ce480400051b5217f19d6e9a82d9010cdde20f1ae9c00d53591e4a1afbb312" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] name = "alloy-sol-macro-expander" -version = "1.5.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95d9fa2daf21f59aa546d549943f10b5cce1ae59986774019fbedae834ffe01b" +checksum = "6d792e205ed3b72f795a8044c52877d2e6b6e9b1d13f431478121d8d4eaa9028" dependencies = [ "alloy-sol-macro-input", "const-hex", "heck 0.5.0", - "indexmap 2.13.0", + "indexmap 2.12.0", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", "syn-solidity", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "1.5.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9396007fe69c26ee118a19f4dee1f5d1d6be186ea75b3881adf16d87f8444686" +checksum = "0bd1247a8f90b465ef3f1207627547ec16940c35597875cdc09c49d58b19693c" dependencies = [ "const-hex", "dunce", @@ -444,15 +439,15 @@ dependencies = [ "macro-string", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", "syn-solidity", ] [[package]] name = "alloy-sol-type-parser" -version = "1.5.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af67a0b0dcebe14244fc92002cd8d96ecbf65db4639d479f5fcd5805755a4c27" +checksum = "954d1b2533b9b2c7959652df3076954ecb1122a28cc740aa84e7b0a49f6ac0a9" dependencies = [ "serde", "winnow", @@ -460,9 +455,9 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "1.5.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09aeea64f09a7483bdcd4193634c7e5cf9fd7775ee767585270cd8ce2d69dc95" +checksum = "70319350969a3af119da6fb3e9bddb1bce66c9ea933600cb297c8b1850ad2a3c" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -472,14 +467,14 @@ dependencies = [ [[package]] name = "alloy-trie" -version = "0.9.3" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428aa0f0e0658ff091f8f667c406e034b431cb10abd39de4f507520968acc499" +checksum = "e3412d52bb97c6c6cc27ccc28d4e6e8cf605469101193b50b0bd5813b1f990b5" dependencies = [ "alloy-primitives", "alloy-rlp", "arrayvec", - "derive_more 2.1.1", + "derive_more 2.0.1", "nybbles", "serde", "smallvec", @@ -488,14 +483,15 @@ dependencies = [ [[package]] name = "alloy-tx-macros" -version = "1.3.0" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99dac443033e83b14f68fac56e8c27e76421f1253729574197ceccd06598f3ef" +checksum = "f8e52276fdb553d3c11563afad2898f4085165e4093604afe3d78b69afbf408f" dependencies = [ + "alloy-primitives", "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -539,22 +535,22 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.1.5" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.11" +version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -574,12 +570,9 @@ dependencies = [ [[package]] name = "arc-swap" -version = "1.8.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d03449bb8ca2cc2ef70869af31463d1ae5ccc8fa3e334b307203fbf815207e" -dependencies = [ - "rustversion", -] +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" [[package]] name = "ark-ff" @@ -666,7 +659,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -704,7 +697,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -803,7 +796,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", "synstructure", ] @@ -815,7 +808,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -832,9 +825,9 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "async-compression" -version = "0.4.36" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ec5f6c2f8bc326c994cb9e241cc257ddaba9afa8555a43cffbb5dd86efaa37" +checksum = "5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0" dependencies = [ "compression-codecs", "compression-core", @@ -862,7 +855,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -873,7 +866,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -897,7 +890,7 @@ version = "3.2.0" dependencies = [ "borsh", "dcap-qvl", - "derive_more 2.1.1", + "derive_more 2.0.1", "dstack-sdk-types", "hex", "serde", @@ -933,7 +926,7 @@ checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -983,10 +976,10 @@ dependencies = [ "axum-core 0.4.5", "bytes", "futures-util", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", - "hyper 1.8.1", + "hyper 1.7.0", "hyper-util", "itoa", "matchit 0.7.3", @@ -1009,19 +1002,19 @@ dependencies = [ [[package]] name = "axum" -version = "0.8.8" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" +checksum = "8a18ed336352031311f4e0b4dd2ff392d4fbb370777c9d18d7fc9d7359f73871" dependencies = [ - "axum-core 0.5.6", + "axum-core 0.5.5", "axum-macros", "bytes", "form_urlencoded", "futures-util", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", - "hyper 1.8.1", + "hyper 1.7.0", "hyper-util", "itoa", "matchit 0.8.4", @@ -1050,7 +1043,7 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", "mime", @@ -1064,13 +1057,13 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.5.6" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22" dependencies = [ "bytes", "futures-core", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", "mime", @@ -1089,7 +1082,7 @@ checksum = "604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -1115,7 +1108,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -1128,7 +1121,7 @@ dependencies = [ "ed25519-dalek", "mpc-contract", "mpc-node", - "near-account-id 2.5.0", + "near-account-id 2.0.0", "rand 0.8.5", "rand_core 0.6.4", "serde", @@ -1164,26 +1157,26 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.8.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d809780667f4410e7c41b07f52439b94d2bdf8528eeedc287fa38d3b7f95d82" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "binary-install" -version = "0.4.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5252e41a4ed7657f79827123f232443077984ec55c540adf48e8fe67b6ec0763" +checksum = "93bff426ff93f3610dd2b946f3eb8cb2d1285ca8682834d43be531a3f93db2ff" dependencies = [ "anyhow", "dirs-next", "flate2", - "fs4", + "fs2", "hex", "is_executable", "siphasher", "tar", "ureq", - "zip 2.4.2", + "zip 0.6.6", ] [[package]] @@ -1204,7 +1197,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -1222,7 +1215,7 @@ dependencies = [ "regex", "rustc-hash 2.1.1", "shlex", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -1242,15 +1235,15 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitcoin-io" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dee39a0ee5b4095224a0cfc6bf4cc1baf0f9624b96b367e53b66d974e51d953" +checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf" [[package]] name = "bitcoin_hashes" -version = "0.14.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26ec84b80c482df901772e931a9a681e26a1b9ee2302edeff23cb30328745c8b" +checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" dependencies = [ "bitcoin-io", "hex-conservative", @@ -1367,14 +1360,14 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] name = "borsh" -version = "1.6.0" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" +checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" dependencies = [ "borsh-derive", "cfg_aliases", @@ -1382,15 +1375,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.6.0" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" +checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -1420,9 +1413,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" dependencies = [ "allocator-api2", ] @@ -1453,7 +1446,7 @@ checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -1464,9 +1457,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" dependencies = [ "serde", ] @@ -1482,11 +1475,12 @@ dependencies = [ [[package]] name = "bzip2" -version = "0.5.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" dependencies = [ "bzip2-sys", + "libc", ] [[package]] @@ -1516,9 +1510,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.2.2" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" dependencies = [ "serde_core", ] @@ -1569,9 +1563,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.51" +version = "1.2.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" +checksum = "739eb0f94557554b3ca9a86d2d37bebd49c5e6d0c1d2bda35ba5bdac830befc2" dependencies = [ "find-msvc-tools", "jobserver", @@ -1617,7 +1611,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -1638,7 +1632,7 @@ dependencies = [ "blstrs", "clap", "contract-interface", - "derive_more 2.1.1", + "derive_more 2.0.1", "elliptic-curve", "hex", "hkdf", @@ -1662,9 +1656,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.54" +version = "4.5.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" +checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623" dependencies = [ "clap_builder", "clap_derive", @@ -1672,9 +1666,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.54" +version = "4.5.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" +checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0" dependencies = [ "anstream", "anstyle", @@ -1691,7 +1685,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -1727,9 +1721,9 @@ dependencies = [ [[package]] name = "compression-codecs" -version = "0.4.35" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0f7ac3e5b97fdce45e8922fb05cae2c37f7bbd63d30dd94821dacfd8f3f2bf2" +checksum = "ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23" dependencies = [ "compression-core", "flate2", @@ -1738,9 +1732,9 @@ dependencies = [ [[package]] name = "compression-core" -version = "0.4.31" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" +checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb" [[package]] name = "console" @@ -1801,9 +1795,9 @@ dependencies = [ [[package]] name = "constant_time_eq" -version = "0.3.1" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "contract-history" @@ -1811,7 +1805,7 @@ version = "3.2.0" dependencies = [ "bs58 0.5.1", "clap", - "reqwest 0.12.28", + "reqwest 0.12.24", "serde", "serde_json", "sha2", @@ -1824,7 +1818,7 @@ version = "3.2.0" dependencies = [ "borsh", "bs58 0.5.1", - "derive_more 2.1.1", + "derive_more 2.0.1", "near-sdk", "schemars 0.8.22", "serde", @@ -1844,15 +1838,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8" -[[package]] -name = "convert_case" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "core-foundation" version = "0.9.4" @@ -1948,7 +1933,7 @@ dependencies = [ "rustc-hash 2.1.1", "serde", "smallvec", - "target-lexicon 0.13.4", + "target-lexicon 0.13.3", "wasmtime-internal-math", ] @@ -2000,7 +1985,7 @@ dependencies = [ "cranelift-codegen", "log", "smallvec", - "target-lexicon 0.13.4", + "target-lexicon 0.13.3", ] [[package]] @@ -2017,7 +2002,7 @@ checksum = "be7b57410e388de0828fa9178e8693abe996bf2356a7f55be35719ee5b162755" dependencies = [ "cranelift-codegen", "libc", - "target-lexicon 0.13.4", + "target-lexicon 0.13.3", ] [[package]] @@ -2028,9 +2013,9 @@ checksum = "bd9641751da85481f0e04033228403eca2becd2a3d9aff56f6c8bed8b9147bfc" [[package]] name = "crc" -version = "3.4.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" dependencies = [ "crc-catalog", ] @@ -2132,9 +2117,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.7" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -2177,7 +2162,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -2210,7 +2195,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -2225,7 +2210,7 @@ dependencies = [ "quote", "serde", "strsim", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -2236,7 +2221,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -2247,7 +2232,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core 0.21.3", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -2318,12 +2303,6 @@ version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f400d0750c0c069e8493f2256cb4da6f604b6d2eeb69a0ca8863acde352f8400" -[[package]] -name = "deflate64" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26bf8fc351c5ed29b5c2f0cbbac1b209b74f60ecd62e675a998df72c49af5204" - [[package]] name = "der" version = "0.7.10" @@ -2359,7 +2338,7 @@ checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -2391,7 +2370,7 @@ checksum = "74ef43543e701c01ad77d3a5922755c6a1d71b22d942cb8042be4994b380caff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -2402,7 +2381,7 @@ checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -2413,7 +2392,7 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -2426,7 +2405,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -2440,11 +2419,11 @@ dependencies = [ [[package]] name = "derive_more" -version = "2.1.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" dependencies = [ - "derive_more-impl 2.1.1", + "derive_more-impl 2.0.1", ] [[package]] @@ -2455,20 +2434,18 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] name = "derive_more-impl" -version = "2.1.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ - "convert_case 0.10.0", "proc-macro2", "quote", - "rustc_version 0.4.1", - "syn 2.0.114", + "syn 2.0.108", "unicode-xid", ] @@ -2542,7 +2519,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -2583,9 +2560,9 @@ dependencies = [ "bon", "dstack-sdk-types", "hex", - "http 1.4.0", + "http 1.3.1", "http-client-unix-domain-socket", - "reqwest 0.12.28", + "reqwest 0.12.24", "serde", "serde_json", "sha2", @@ -2704,7 +2681,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -2772,7 +2749,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -2792,7 +2769,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -2812,7 +2789,7 @@ checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -2833,7 +2810,7 @@ dependencies = [ "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -2927,9 +2904,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.6" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" [[package]] name = "finite-wasm" @@ -3141,16 +3118,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "fs4" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eeb4ed9e12f43b7fa0baae3f9cdda28352770132ef2e09a23760c29cae8bd47" -dependencies = [ - "rustix 0.38.44", - "windows-sys 0.48.0", -] - [[package]] name = "funty" version = "2.0.0" @@ -3226,7 +3193,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -3281,12 +3248,12 @@ dependencies = [ "bytes", "chrono", "futures", - "hyper 1.8.1", + "hyper 1.7.0", "jsonwebtoken", "once_cell", "prost 0.13.5", "prost-types 0.13.5", - "reqwest 0.12.28", + "reqwest 0.12.24", "secret-vault-value", "serde", "serde_json", @@ -3301,9 +3268,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", @@ -3354,15 +3321,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" dependencies = [ "fallible-iterator", - "indexmap 2.13.0", + "indexmap 2.12.0", "stable_deref_trait", ] [[package]] name = "git2" -version = "0.20.3" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2b37e2f62729cdada11f0e6b3b6fe383c69c29fc619e391223e12856af308c" +checksum = "2deb07a133b1520dc1a5690e9bd08950108873d7ed5de38dcc74d3b5ebffa110" dependencies = [ "bitflags 2.10.0", "libc", @@ -3414,7 +3381,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.13.0", + "indexmap 2.12.0", "slab", "tokio", "tokio-util", @@ -3423,17 +3390,17 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.13" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" dependencies = [ "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "http 1.4.0", - "indexmap 2.13.0", + "http 1.3.1", + "indexmap 2.12.0", "slab", "tokio", "tokio-util", @@ -3478,13 +3445,12 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" dependencies = [ "foldhash 0.2.0", "serde", - "serde_core", ] [[package]] @@ -3530,9 +3496,9 @@ dependencies = [ [[package]] name = "hex-conservative" -version = "0.2.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda06d18ac606267c40c04e41b9947729bf8b9efe74bd4e82b61a5f26a510b9f" +checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" dependencies = [ "arrayvec", ] @@ -3603,11 +3569,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.12" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -3623,11 +3589,12 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", + "fnv", "itoa", ] @@ -3649,7 +3616,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.4.0", + "http 1.3.1", ] [[package]] @@ -3660,7 +3627,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "pin-project-lite", ] @@ -3671,10 +3638,10 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40dfebe8708af3772e3d5121077aaa18045dd9f43fc4b5046c31345cdffb7354" dependencies = [ - "axum 0.8.8", - "axum-core 0.5.6", + "axum 0.8.6", + "axum-core 0.5.5", "http-body-util", - "hyper 1.8.1", + "hyper 1.7.0", "hyper-util", "serde", "serde_json", @@ -3725,16 +3692,16 @@ dependencies = [ [[package]] name = "hyper" -version = "1.8.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" dependencies = [ "atomic-waker", "bytes", "futures-channel", "futures-core", - "h2 0.4.13", - "http 1.4.0", + "h2 0.4.12", + "http 1.3.1", "http-body 1.0.1", "httparse", "httpdate", @@ -3752,8 +3719,8 @@ version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "http 1.4.0", - "hyper 1.8.1", + "http 1.3.1", + "hyper 1.7.0", "hyper-util", "rustls", "rustls-native-certs", @@ -3761,7 +3728,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots 1.0.5", + "webpki-roots 1.0.3", ] [[package]] @@ -3770,7 +3737,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" dependencies = [ - "hyper 1.8.1", + "hyper 1.7.0", "hyper-util", "pin-project-lite", "tokio", @@ -3798,7 +3765,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.8.1", + "hyper 1.7.0", "hyper-util", "native-tls", "tokio", @@ -3808,18 +3775,18 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.19" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" dependencies = [ "base64 0.22.1", "bytes", "futures-channel", "futures-core", "futures-util", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", - "hyper 1.8.1", + "hyper 1.7.0", "ipnet", "libc", "percent-encoding", @@ -3904,9 +3871,9 @@ checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" dependencies = [ "icu_collections", "icu_locale_core", @@ -3918,9 +3885,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" [[package]] name = "icu_provider" @@ -3995,7 +3962,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -4008,7 +3975,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -4030,12 +3997,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.16.0", "serde", "serde_core", ] @@ -4065,9 +4032,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.46.0" +version = "1.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b66886d14d18d420ab5052cbff544fc5d34d0b2cdd35eb5976aaa10a4a472e5" +checksum = "46fdb647ebde000f43b5b53f773c30cf9b0cb4300453208713fa38b2c70935a0" dependencies = [ "console", "once_cell", @@ -4075,7 +4042,6 @@ dependencies = [ "pest_derive", "serde", "similar", - "tempfile", ] [[package]] @@ -4107,9 +4073,9 @@ checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "iri-string" -version = "0.7.10" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" dependencies = [ "memchr", "serde", @@ -4168,9 +4134,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jobserver" @@ -4184,9 +4150,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.83" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" dependencies = [ "once_cell", "wasm-bindgen", @@ -4299,15 +4265,15 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.179" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5a2d376baa530d1238d133232d15e239abad80d05838b4b59354e5268af431f" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libgit2-sys" -version = "0.18.3+1.9.2" +version = "0.18.2+1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9b3acc4b91781bb0b3386669d325163746af5f6e4f73e6d2d630e09a35f3487" +checksum = "1c42fe03df2bd3c53a3a9c7317ad91d80c81cd1fb0caec8d7cc4cd2bfa10c222" dependencies = [ "cc", "libc", @@ -4322,7 +4288,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if 1.0.4", - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -4333,13 +4299,13 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.12" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ "bitflags 2.10.0", "libc", - "redox_syscall 0.7.0", + "redox_syscall 0.5.18", ] [[package]] @@ -4361,18 +4327,18 @@ dependencies = [ [[package]] name = "libz-rs-sys" -version = "0.5.5" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c10501e7805cee23da17c7790e59df2870c0d4043ec6d03f67d31e2b53e77415" +checksum = "840db8cf39d9ec4dd794376f38acc40d0fc65eec2a8f484f7fd375b84602becd" dependencies = [ "zlib-rs", ] [[package]] name = "libz-sys" -version = "1.1.23" +version = "1.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15d118bbf3771060e7311cc7bb0545b01d08a8b4a7de949198dec1fa0ca1c0f7" +checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" dependencies = [ "cc", "libc", @@ -4416,9 +4382,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "lru" @@ -4454,16 +4420,6 @@ dependencies = [ "libc", ] -[[package]] -name = "lzma-rs" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" -dependencies = [ - "byteorder", - "crc", -] - [[package]] name = "lzma-sys" version = "0.1.20" @@ -4492,7 +4448,7 @@ checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -4524,7 +4480,7 @@ checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -4555,7 +4511,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad38eb12aea514a0466ea40a80fd8cc83637065948eb4a426e4aa46261175227" dependencies = [ - "rustix 1.1.3", + "rustix 1.1.2", ] [[package]] @@ -4646,9 +4602,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" dependencies = [ "libc", "wasi", @@ -4678,14 +4634,14 @@ dependencies = [ "cfg-if 1.0.4", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] name = "moka" -version = "0.12.12" +version = "0.12.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3dec6bd31b08944e08b58fd99373893a6c17054d6f3ea5006cc894f4f4eee2a" +checksum = "8261cd88c312e0004c1d51baad2980c66528dfdb2bee62003e643a4d8f86b077" dependencies = [ "crossbeam-channel", "crossbeam-epoch", @@ -4693,6 +4649,7 @@ dependencies = [ "equivalent", "parking_lot 0.12.5", "portable-atomic", + "rustc_version 0.4.1", "smallvec", "tagptr", "uuid", @@ -4711,7 +4668,7 @@ dependencies = [ "attestation", "borsh", "dcap-qvl", - "derive_more 2.1.1", + "derive_more 2.0.1", "hex", "include-measurements", "mpc-primitives", @@ -4734,7 +4691,7 @@ dependencies = [ "contract-history", "contract-interface", "curve25519-dalek", - "derive_more 2.1.1", + "derive_more 2.0.1", "digest 0.10.7", "ecdsa", "elliptic-curve", @@ -4747,7 +4704,7 @@ dependencies = [ "mpc-contract", "mpc-primitives", "near-abi", - "near-account-id 2.5.0", + "near-account-id 2.0.0", "near-sdk", "near-workspaces", "rand 0.8.5", @@ -4765,7 +4722,7 @@ dependencies = [ "threshold-signatures", "tokio", "utilities", - "zstd", + "zstd 0.13.3", ] [[package]] @@ -4782,7 +4739,7 @@ dependencies = [ "futures", "hex", "mpc-contract", - "near-account-id 2.5.0", + "near-account-id 2.0.0", "near-crypto 0.28.0", "near-jsonrpc-client 0.15.1", "near-jsonrpc-primitives 0.28.0", @@ -4790,7 +4747,7 @@ dependencies = [ "near-sdk", "node-types", "rand 0.9.2", - "reqwest 0.12.28", + "reqwest 0.12.24", "serde", "serde_json", "serde_yaml", @@ -4815,7 +4772,7 @@ dependencies = [ "built", "clap", "contract-interface", - "derive_more 2.1.1", + "derive_more 2.0.1", "ed25519-dalek", "flume", "futures", @@ -4825,11 +4782,12 @@ dependencies = [ "hyper 0.14.32", "itertools 0.12.1", "k256", + "lru 0.12.5", "mockall", "mpc-attestation", "mpc-contract", "mpc-tls", - "near-account-id 2.5.0", + "near-account-id 2.0.0", "near-async", "near-client", "near-config-utils 2.10.3", @@ -4872,7 +4830,7 @@ name = "mpc-primitives" version = "3.2.0" dependencies = [ "borsh", - "derive_more 2.1.1", + "derive_more 2.0.1", "hex", "rand 0.8.5", "schemars 0.8.22", @@ -4910,7 +4868,7 @@ checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -4944,7 +4902,7 @@ dependencies = [ "libc", "log", "openssl", - "openssl-probe 0.1.6", + "openssl-probe", "openssl-sys", "schannel", "security-framework 2.11.1", @@ -4954,9 +4912,9 @@ dependencies = [ [[package]] name = "near-abi" -version = "0.4.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fe0c8cdaf8369d8c78f2577d95673007c7f256c85752a66672be5244e2681a6" +checksum = "7c49593c9e94454a2368a4c0a511bf4bf1413aff4d23f16e1d8f4e64b5215351" dependencies = [ "borsh", "schemars 0.8.22", @@ -5011,14 +4969,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "975bb8e272af403d97656893f71e095e1b178ccee571b3ec4a193152be0248f5" dependencies = [ "borsh", + "schemars 0.8.22", "serde", ] [[package]] name = "near-account-id" -version = "2.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91f75ff8eee73815c247d0e17f3c0b705f0e993922a5548acd2ad377aeb67fca" +checksum = "0bf7d8c37ea9408d536af7e998bd0d4f9699de1f6b0d12280d28ae46977c4501" dependencies = [ "borsh", "schemars 0.8.22", @@ -5051,7 +5010,7 @@ source = "git+https://github.com/near/nearcore?tag=2.10.3#3caaf44631859fb8a962b7 dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -5145,7 +5104,7 @@ dependencies = [ "anyhow", "bytesize", "chrono", - "derive_more 2.1.1", + "derive_more 2.0.1", "near-config-utils 0.31.1", "near-crypto 0.31.1", "near-parameters 0.31.1", @@ -5169,7 +5128,7 @@ dependencies = [ "anyhow", "bytesize", "chrono", - "derive_more 2.1.1", + "derive_more 2.0.1", "near-config-utils 2.10.3", "near-crypto 2.10.3", "near-o11y", @@ -5274,7 +5233,7 @@ dependencies = [ "rayon", "reed-solomon-erasure", "regex", - "reqwest 0.12.28", + "reqwest 0.12.24", "rust-s3", "serde", "serde_json", @@ -5329,18 +5288,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "near-config-utils" -version = "0.34.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d501df6fa01064f325daaf19329183a4cd1ad54b7a1b5b8b0281b07f7e7c540" -dependencies = [ - "anyhow", - "json_comments", - "thiserror 2.0.17", - "tracing", -] - [[package]] name = "near-config-utils" version = "2.10.3" @@ -5388,7 +5335,7 @@ dependencies = [ "borsh", "bs58 0.4.0", "curve25519-dalek", - "derive_more 2.1.1", + "derive_more 2.0.1", "ed25519-dalek", "hex", "near-account-id 1.1.4", @@ -5404,31 +5351,6 @@ dependencies = [ "thiserror 2.0.17", ] -[[package]] -name = "near-crypto" -version = "0.34.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c8bfbd0f159e817402936e188bdd1d38167b0679c7693652f5199b5a36bc804" -dependencies = [ - "blake2", - "borsh", - "bs58 0.4.0", - "curve25519-dalek", - "derive_more 2.1.1", - "ed25519-dalek", - "hex", - "near-account-id 2.5.0", - "near-config-utils 0.34.3", - "near-schema-checker-lib 0.34.3", - "near-stdx 0.34.3", - "primitive-types 0.10.1", - "secp256k1 0.27.0", - "serde", - "serde_json", - "subtle", - "thiserror 2.0.17", -] - [[package]] name = "near-crypto" version = "2.10.3" @@ -5438,10 +5360,10 @@ dependencies = [ "borsh", "bs58 0.4.0", "curve25519-dalek", - "derive_more 2.1.1", + "derive_more 2.0.1", "ed25519-dalek", "hex", - "near-account-id 2.5.0", + "near-account-id 2.0.0", "near-config-utils 2.10.3", "near-schema-checker-lib 2.10.3", "near-stdx 2.10.3", @@ -5516,7 +5438,7 @@ dependencies = [ "near-chain-configs 2.10.3", "object_store", "percent-encoding", - "reqwest 0.12.28", + "reqwest 0.12.24", "rust-s3", "serde", "serde_json", @@ -5541,15 +5463,6 @@ dependencies = [ "near-primitives-core 0.31.1", ] -[[package]] -name = "near-fmt" -version = "0.34.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb22e3081a4d0de5795cf0f44b1152ec70bb31a95d6f463e723d9a81e9aac50" -dependencies = [ - "near-primitives-core 0.34.3", -] - [[package]] name = "near-fmt" version = "2.10.3" @@ -5560,9 +5473,9 @@ dependencies = [ [[package]] name = "near-gas" -version = "0.3.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cecd5d9463587f34f2b7ff4c7104297483a543be8a68a4a04a8ac96c419d1a1" +checksum = "41ca4044222f2f392ab61d27d0aefc5106b1ece4dcd22c5c987e3c75371d2a37" dependencies = [ "borsh", "schemars 0.8.22", @@ -5610,7 +5523,7 @@ name = "near-jsonrpc" version = "2.10.3" source = "git+https://github.com/near/nearcore?tag=2.10.3#3caaf44631859fb8a962b70c883f699bcc10f318" dependencies = [ - "axum 0.8.8", + "axum 0.8.6", "bs58 0.4.0", "easy-ext", "near-async", @@ -5642,7 +5555,7 @@ dependencies = [ "near-crypto 0.28.0", "near-jsonrpc-primitives 0.28.0", "near-primitives 0.28.0", - "reqwest 0.12.28", + "reqwest 0.12.24", "serde", "serde_json", "thiserror 2.0.17", @@ -5661,7 +5574,7 @@ dependencies = [ "near-crypto 0.31.1", "near-jsonrpc-primitives 0.31.1", "near-primitives 0.31.1", - "reqwest 0.12.28", + "reqwest 0.12.24", "serde", "serde_json", "thiserror 2.0.17", @@ -5675,7 +5588,7 @@ dependencies = [ "futures", "near-jsonrpc-primitives 2.10.3", "near-primitives 2.10.3", - "reqwest 0.12.28", + "reqwest 0.12.24", "serde", "serde_json", "url", @@ -5739,7 +5652,7 @@ name = "near-mainnet-res" version = "2.10.3" source = "git+https://github.com/near/nearcore?tag=2.10.3#3caaf44631859fb8a962b70c883f699bcc10f318" dependencies = [ - "near-account-id 2.5.0", + "near-account-id 2.0.0", "near-chain-configs 2.10.3", "near-primitives 2.10.3", "serde_json", @@ -5851,25 +5764,6 @@ dependencies = [ "thiserror 2.0.17", ] -[[package]] -name = "near-parameters" -version = "0.34.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10010e4e9badbb7608bf7feddf99027a954dcdfc64439f0f86a014c6277bfe53" -dependencies = [ - "borsh", - "enum-map", - "near-account-id 2.5.0", - "near-primitives-core 0.34.3", - "near-schema-checker-lib 0.34.3", - "num-rational", - "serde", - "serde_repr", - "serde_yaml", - "strum 0.24.1", - "thiserror 2.0.17", -] - [[package]] name = "near-parameters" version = "2.10.3" @@ -5877,7 +5771,7 @@ source = "git+https://github.com/near/nearcore?tag=2.10.3#3caaf44631859fb8a962b7 dependencies = [ "borsh", "enum-map", - "near-account-id 2.5.0", + "near-account-id 2.0.0", "near-primitives-core 2.10.3", "near-schema-checker-lib 2.10.3", "num-rational", @@ -5903,7 +5797,7 @@ version = "2.10.3" source = "git+https://github.com/near/nearcore?tag=2.10.3#3caaf44631859fb8a962b70c883f699bcc10f318" dependencies = [ "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -5957,7 +5851,7 @@ dependencies = [ "strum 0.24.1", "thiserror 2.0.17", "tracing", - "zstd", + "zstd 0.13.3", ] [[package]] @@ -5973,7 +5867,7 @@ dependencies = [ "bytes", "bytesize", "chrono", - "derive_more 2.1.1", + "derive_more 2.0.1", "easy-ext", "enum-map", "hex", @@ -5998,47 +5892,7 @@ dependencies = [ "strum 0.24.1", "thiserror 2.0.17", "tracing", - "zstd", -] - -[[package]] -name = "near-primitives" -version = "0.34.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ffba1d49adc30ec0808d1aef3cc2a3395ade82a99216ef3cf387355c7b46658" -dependencies = [ - "arbitrary", - "base64 0.21.7", - "bitvec", - "borsh", - "bytes", - "bytesize", - "chrono", - "derive_more 2.1.1", - "easy-ext", - "enum-map", - "hex", - "itertools 0.14.0", - "near-crypto 0.34.3", - "near-fmt 0.34.3", - "near-parameters 0.34.3", - "near-primitives-core 0.34.3", - "near-schema-checker-lib 0.34.3", - "near-stdx 0.34.3", - "near-time 0.34.3", - "num-rational", - "ordered-float", - "primitive-types 0.10.1", - "serde", - "serde_json", - "serde_with", - "sha3", - "smallvec", - "smart-default 0.7.1", - "strum 0.24.1", - "thiserror 2.0.17", - "tracing", - "zstd", + "zstd 0.13.3", ] [[package]] @@ -6053,7 +5907,7 @@ dependencies = [ "bytes", "bytesize", "chrono", - "derive_more 2.1.1", + "derive_more 2.0.1", "easy-ext", "enum-map", "hex", @@ -6080,7 +5934,7 @@ dependencies = [ "strum 0.24.1", "thiserror 2.0.17", "tracing", - "zstd", + "zstd 0.13.3", ] [[package]] @@ -6114,7 +5968,7 @@ dependencies = [ "base64 0.21.7", "borsh", "bs58 0.4.0", - "derive_more 2.1.1", + "derive_more 2.0.1", "enum-map", "near-account-id 1.1.4", "near-schema-checker-lib 0.31.1", @@ -6125,30 +5979,6 @@ dependencies = [ "thiserror 2.0.17", ] -[[package]] -name = "near-primitives-core" -version = "0.34.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "becb94101c8b7883231a027a0aec85e4f92b4366a17a665d9b68a852937d2bdd" -dependencies = [ - "arbitrary", - "base64 0.21.7", - "borsh", - "bs58 0.4.0", - "derive_more 2.1.1", - "enum-map", - "near-account-id 2.5.0", - "near-gas", - "near-schema-checker-lib 0.34.3", - "near-token", - "num-rational", - "serde", - "serde_repr", - "serde_with", - "sha2", - "thiserror 2.0.17", -] - [[package]] name = "near-primitives-core" version = "2.10.3" @@ -6158,9 +5988,9 @@ dependencies = [ "base64 0.21.7", "borsh", "bs58 0.4.0", - "derive_more 2.1.1", + "derive_more 2.0.1", "enum-map", - "near-account-id 2.5.0", + "near-account-id 2.0.0", "near-gas", "near-schema-checker-lib 2.10.3", "near-token", @@ -6177,12 +6007,12 @@ name = "near-rosetta-rpc" version = "2.10.3" source = "git+https://github.com/near/nearcore?tag=2.10.3#3caaf44631859fb8a962b70c883f699bcc10f318" dependencies = [ - "axum 0.8.8", - "derive_more 2.1.1", + "axum 0.8.6", + "derive_more 2.0.1", "futures", "hex", "insta", - "near-account-id 2.5.0", + "near-account-id 2.0.0", "near-async", "near-chain-configs 2.10.3", "near-client", @@ -6205,13 +6035,14 @@ dependencies = [ [[package]] name = "near-sandbox-utils" -version = "0.15.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0479c989de7c9c99c849fe452181a9a2d9826eaebd737a562e76627e2ba0ccdc" +checksum = "66ea2772bc3fb37be43b52c57c0a998b1add4675e609fd89113c600c7c016443" dependencies = [ "anyhow", "binary-install", - "fs4", + "fs2", + "home", "tokio", ] @@ -6227,12 +6058,6 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3515d1bd55d87bfb392f6889313dcfbcaaec4229bb4a4abb5640ab8dc5eda70c" -[[package]] -name = "near-schema-checker-core" -version = "0.34.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5700f8f5b38507eb01769c3f761a481aa0ff5ab18fd98d8c3c9d14f231e04b" - [[package]] name = "near-schema-checker-core" version = "2.10.3" @@ -6258,16 +6083,6 @@ dependencies = [ "near-schema-checker-macro 0.31.1", ] -[[package]] -name = "near-schema-checker-lib" -version = "0.34.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd90923ed5ef5e6ed2c18e2effeaa4bf53398f6dfd25493fc1494d6e44df6b57" -dependencies = [ - "near-schema-checker-core 0.34.3", - "near-schema-checker-macro 0.34.3", -] - [[package]] name = "near-schema-checker-lib" version = "2.10.3" @@ -6289,12 +6104,6 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dc45bb3760350de7f957c11827e1e20c5a4aff8d95d19fd2c0c492d795bfb02" -[[package]] -name = "near-schema-checker-macro" -version = "0.34.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff9a4b5c2a27926b14465dd7cc06a9f801f8892de9ee8576b421c7d00f6320" - [[package]] name = "near-schema-checker-macro" version = "2.10.3" @@ -6302,24 +6111,24 @@ source = "git+https://github.com/near/nearcore?tag=2.10.3#3caaf44631859fb8a962b7 [[package]] name = "near-sdk" -version = "5.24.0" +version = "5.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5188eba9ee0383c2a28afee994e65c21e98823d18a32b8b3a7c8d6cdedfb119" +checksum = "ab0fa9255055e9715ff7c4bffc819772ed757af13a2583dbdbd982db897b4769" dependencies = [ "base64 0.22.1", "borsh", "bs58 0.5.1", "near-abi", - "near-account-id 2.5.0", - "near-crypto 0.34.3", + "near-account-id 1.1.4", + "near-crypto 0.31.1", "near-gas", - "near-parameters 0.34.3", - "near-primitives 0.34.3", - "near-primitives-core 0.34.3", + "near-parameters 0.31.1", + "near-primitives 0.31.1", + "near-primitives-core 0.31.1", "near-sdk-macros", "near-sys", "near-token", - "near-vm-runner 0.34.3", + "near-vm-runner 0.31.1", "once_cell", "schemars 0.8.22", "serde", @@ -6330,9 +6139,9 @@ dependencies = [ [[package]] name = "near-sdk-macros" -version = "5.24.0" +version = "5.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4339b75a514ca2e6b67379be62a441f7e99a2c3813278f1b23d233b300f9f4f" +checksum = "4c349917f79b2df2a94eff6409fc74722918e471835cb62edd0eb084f4ea7feb" dependencies = [ "Inflector", "darling 0.20.11", @@ -6342,7 +6151,7 @@ dependencies = [ "serde_json", "strum 0.26.3", "strum_macros 0.26.4", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -6357,12 +6166,6 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e3c38fc0843ef7c5bca717cc4daaf2af05441c3cb9cf259824e226387b18740" -[[package]] -name = "near-stdx" -version = "0.34.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28b47d44e10c45054bcc023dfda154f13f5b8e980ad25ee94cd32207d463b78" - [[package]] name = "near-stdx" version = "2.10.3" @@ -6379,7 +6182,7 @@ dependencies = [ "crossbeam", "dashmap", "derive-where", - "derive_more 2.1.1", + "derive_more 2.0.1", "enum-map", "hex", "itertools 0.14.0", @@ -6418,9 +6221,9 @@ dependencies = [ [[package]] name = "near-sys" -version = "0.2.6" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b99e9ce0020190ea152f70d1849e54fc8fc123738e7447800ad818c78f5167cc" +checksum = "e64e114297f37c94aa20df6a6f92822a1b41da76b4961298caf08ba80b7779b2" [[package]] name = "near-telemetry" @@ -6432,7 +6235,7 @@ dependencies = [ "near-o11y", "near-performance-metrics", "near-performance-metrics-macros", - "reqwest 0.12.28", + "reqwest 0.12.24", "serde", "serde_json", "tracing", @@ -6459,17 +6262,6 @@ dependencies = [ "time", ] -[[package]] -name = "near-time" -version = "0.34.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5974d008afcd280363411fc1bde76b2c3d36d6c707694bd93d68ceb2a25f2dfe" -dependencies = [ - "parking_lot 0.12.5", - "serde", - "time", -] - [[package]] name = "near-time" version = "2.10.3" @@ -6483,9 +6275,9 @@ dependencies = [ [[package]] name = "near-token" -version = "0.3.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34de6b54d82d0790b2a56b677e7b4ecb7f021a7e8559f8611065c890d56cfcda" +checksum = "133a293baa70b78db8c4325753ca8012f84e67de6c84c013960722a937985615" dependencies = [ "borsh", "schemars 0.8.22", @@ -6541,16 +6333,16 @@ dependencies = [ "parking_lot 0.12.5", "rkyv", "rustc-demangle", - "rustix 1.1.3", + "rustix 1.1.2", "thiserror 2.0.17", "tracing", ] [[package]] name = "near-vm-runner" -version = "0.34.3" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a806f05174cc99052ad974d054aa4416dc4c6b09be728ab0a02b07539643f8c9" +checksum = "5ddefc8e4460b2c080b34f800b0bd06fd971b37d64ec7279552d792468228924" dependencies = [ "blst", "borsh", @@ -6558,17 +6350,17 @@ dependencies = [ "ed25519-dalek", "enum-map", "lru 0.12.5", - "near-crypto 0.34.3", - "near-parameters 0.34.3", - "near-primitives-core 0.34.3", - "near-schema-checker-lib 0.34.3", - "near-stdx 0.34.3", + "near-crypto 0.31.1", + "near-parameters 0.31.1", + "near-primitives-core 0.31.1", + "near-schema-checker-lib 0.31.1", + "near-stdx 0.31.1", "num-rational", "parking_lot 0.12.5", "rand 0.8.5", "rayon", "ripemd", - "rustix 1.1.3", + "rustix 1.1.2", "serde", "sha2", "sha3", @@ -6612,7 +6404,7 @@ dependencies = [ "rand 0.8.5", "rayon", "ripemd", - "rustix 1.1.3", + "rustix 1.1.2", "serde", "sha2", "sha3", @@ -6632,7 +6424,7 @@ name = "near-vm-types" version = "2.10.3" source = "git+https://github.com/near/nearcore?tag=2.10.3#3caaf44631859fb8a962b70c883f699bcc10f318" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.12.0", "num-traits", "rkyv", "thiserror 2.0.17", @@ -6692,7 +6484,7 @@ dependencies = [ "near-sandbox-utils", "near-token", "rand 0.8.5", - "reqwest 0.12.28", + "reqwest 0.12.24", "serde", "serde_json", "sha2", @@ -6773,7 +6565,7 @@ dependencies = [ "num-rational", "parking_lot 0.12.5", "rand 0.8.5", - "reqwest 0.12.28", + "reqwest 0.12.24", "serde", "serde_ignored", "serde_json", @@ -6949,9 +6741,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "nybbles" -version = "0.4.7" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5676b5c379cf5b03da1df2b3061c4a4e2aa691086a56ac923e08c143f53f59" +checksum = "2c4b5ecbd0beec843101bffe848217f770e8b8da81d8355b7d6e226f2199b3dc" dependencies = [ "alloy-rlp", "cfg-if 1.0.4", @@ -6969,7 +6761,7 @@ checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "crc32fast", "hashbrown 0.15.5", - "indexmap 2.13.0", + "indexmap 2.12.0", "memchr", ] @@ -6985,16 +6777,16 @@ dependencies = [ "chrono", "form_urlencoded", "futures", - "http 1.4.0", + "http 1.3.1", "http-body-util", "humantime", - "hyper 1.8.1", + "hyper 1.7.0", "itertools 0.14.0", "parking_lot 0.12.5", "percent-encoding", "quick-xml", "rand 0.9.2", - "reqwest 0.12.28", + "reqwest 0.12.24", "ring", "rustls-pemfile 2.2.0", "serde", @@ -7048,9 +6840,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.75" +version = "0.10.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654" dependencies = [ "bitflags 2.10.0", "cfg-if 1.0.4", @@ -7069,7 +6861,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -7078,12 +6870,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" -[[package]] -name = "openssl-probe" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" - [[package]] name = "openssl-src" version = "300.5.4+3.5.4" @@ -7095,9 +6881,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.111" +version = "0.9.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2" dependencies = [ "cc", "libc", @@ -7126,7 +6912,7 @@ version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbee664a43e07615731afc539ca60c6d9f1a9425e25ca09c57bc36c87c55852b" dependencies = [ - "http 1.4.0", + "http 1.3.1", "opentelemetry", "opentelemetry-proto", "opentelemetry_sdk", @@ -7228,7 +7014,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -7282,7 +7068,18 @@ dependencies = [ "libc", "redox_syscall 0.5.18", "smallvec", - "windows-link", + "windows-link 0.2.1", +] + +[[package]] +name = "password-hash" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", ] [[package]] @@ -7302,12 +7099,14 @@ dependencies = [ [[package]] name = "pbkdf2" -version = "0.12.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ "digest 0.10.7", "hmac", + "password-hash", + "sha2", ] [[package]] @@ -7343,9 +7142,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.5" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9eb05c21a464ea704b53158d358a31e6425db2f63a1a7312268b05fe2b75f7" +checksum = "989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4" dependencies = [ "memchr", "ucd-trie", @@ -7353,9 +7152,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.8.5" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f9dbced329c441fa79d80472764b1a2c7e57123553b8519b36663a2fb234ed" +checksum = "187da9a3030dbafabbbfb20cb323b976dc7b7ce91fcd84f2f74d6e31d378e2de" dependencies = [ "pest", "pest_generator", @@ -7363,22 +7162,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.5" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bb96d5051a78f44f43c8f712d8e810adb0ebf923fc9ed2655a7f66f63ba8ee5" +checksum = "49b401d98f5757ebe97a26085998d6c0eecec4995cad6ab7fc30ffdf4b052843" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] name = "pest_meta" -version = "2.8.5" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602113b5b5e8621770cfd490cfd90b9f84ab29bd2b0e49ad83eb6d186cef2365" +checksum = "72f27a2cfee9f9039c4d86faa5af122a0ac3851441a34865b8a043b46be0065a" dependencies = [ "pest", "sha2", @@ -7421,7 +7220,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -7466,9 +7265,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.13.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] name = "postcard" @@ -7556,7 +7355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -7632,14 +7431,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] name = "proc-macro2" -version = "1.0.105" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] @@ -7707,7 +7506,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -7720,7 +7519,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -7774,7 +7573,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4aeaa1f2460f1d348eeaeed86aea999ce98c1bded6f089ff8514c9d9dbdc973" dependencies = [ "anyhow", - "indexmap 2.13.0", + "indexmap 2.12.0", "log", "protobuf", "protobuf-support", @@ -7809,7 +7608,7 @@ checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -7832,7 +7631,7 @@ checksum = "0b4b4aee26ad4085bcde356a00853e11fe1f06f4ae0d27a1cdfac9dd2529fa62" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -7843,9 +7642,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quick-xml" -version = "0.38.4" +version = "0.38.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" +checksum = "42a232e7487fc2ef313d96dde7948e7a3c05101870d8985e4fd8d26aedd27b89" dependencies = [ "memchr", "serde", @@ -7908,9 +7707,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.43" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] @@ -8035,15 +7834,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "rapidhash" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2988730ee014541157f48ce4dcc603940e00915edc3c7f9a8d78092256bb2493" -dependencies = [ - "rustversion", -] - [[package]] name = "rayon" version = "1.11.0" @@ -8095,15 +7885,6 @@ dependencies = [ "bitflags 2.10.0", ] -[[package]] -name = "redox_syscall" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" -dependencies = [ - "bitflags 2.10.0", -] - [[package]] name = "redox_users" version = "0.4.6" @@ -8147,7 +7928,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -8264,22 +8045,23 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.28" +version = "0.12.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" dependencies = [ + "async-compression", "base64 0.22.1", "bytes", "encoding_rs", "futures-channel", "futures-core", "futures-util", - "h2 0.4.13", + "h2 0.4.12", "hickory-resolver", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", - "hyper 1.8.1", + "hyper 1.7.0", "hyper-rustls", "hyper-tls 0.6.0", "hyper-util", @@ -8311,14 +8093,14 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 1.0.5", + "webpki-roots 1.0.3", ] [[package]] name = "resolv-conf" -version = "0.7.6" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7" +checksum = "6b3789b30bd25ba102de4beabd95d21ac45b69b1be7d14522bab988c526d6799" [[package]] name = "rfc6979" @@ -8361,8 +8143,8 @@ checksum = "8b2e88acca7157d83d789836a3987dafc12bc3d88a050e54b8fe9ea4aaa29d20" dependencies = [ "bytecheck", "bytes", - "hashbrown 0.16.1", - "indexmap 2.13.0", + "hashbrown 0.16.0", + "indexmap 2.12.0", "munge", "ptr_meta", "rancor", @@ -8380,7 +8162,7 @@ checksum = "7f6dffea3c91fa91a3c0fc8a061b0e27fef25c6304728038a6d6bcb1c58ba9bd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -8404,19 +8186,22 @@ dependencies = [ [[package]] name = "rmp" -version = "0.8.15" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c" +checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" dependencies = [ + "byteorder", "num-traits", + "paste", ] [[package]] name = "rmp-serde" -version = "1.3.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155" +checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" dependencies = [ + "byteorder", "rmp", "serde", ] @@ -8457,15 +8242,15 @@ dependencies = [ "regex", "relative-path", "rustc_version 0.4.1", - "syn 2.0.114", + "syn 2.0.108", "unicode-ident", ] [[package]] name = "ruint" -version = "1.17.2" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c141e807189ad38a07276942c6623032d3753c8859c146104ac2e4d68865945a" +checksum = "a68df0380e5c9d20ce49534f292a36a7514ae21350726efe1865bdb1fa91d278" dependencies = [ "alloy-rlp", "ark-ff 0.3.0", @@ -8515,7 +8300,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.114", + "syn 2.0.108", "walkdir", ] @@ -8637,9 +8422,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.3" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ "bitflags 2.10.0", "errno", @@ -8650,9 +8435,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.36" +version = "0.23.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +checksum = "6a9586e9ee2b4f8fab52a0048ca7334d7024eef48e2cb9407e3497bb7cab7fa7" dependencies = [ "log", "once_cell", @@ -8665,11 +8450,11 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" dependencies = [ - "openssl-probe 0.2.0", + "openssl-probe", "rustls-pki-types", "schannel", "security-framework 3.5.1", @@ -8695,9 +8480,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.2" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" +checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a" dependencies = [ "web-time", "zeroize", @@ -8762,9 +8547,9 @@ checksum = "22a197350ece202f19a166d1ad6d9d6de145e1d2a8ef47db299abe164dbd7530" [[package]] name = "ryu" -version = "1.0.22" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "same-file" @@ -8797,7 +8582,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -8844,9 +8629,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.2.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e910108742c57a770f492731f99be216a52fadd361b06c8fb59d74ccc267d2" +checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" dependencies = [ "dyn-clone", "ref-cast", @@ -8863,7 +8648,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -9022,11 +8807,10 @@ dependencies = [ [[package]] name = "serde-human-bytes" -version = "0.1.2" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a091af6294712930d01e375cce513e4ac416f823e033e8991ec4e5d6e6ef4c0" +checksum = "78ef65cb41f3f9cef63c431193229067e8b98b53c4d4c4ed38a8ca87c4d07676" dependencies = [ - "base64 0.13.1", "hex", "serde", ] @@ -9070,7 +8854,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -9081,7 +8865,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -9096,16 +8880,16 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.12.0", "itoa", "memchr", + "ryu", "serde", "serde_core", - "zmij", ] [[package]] @@ -9127,7 +8911,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -9144,18 +8928,18 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.16.1" +version = "3.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" +checksum = "aa66c845eee442168b2c8134fec70ac50dc20e760769c8ba0ad1319ca1959b04" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.13.0", + "indexmap 2.12.0", "schemars 0.8.22", "schemars 0.9.0", - "schemars 1.2.0", + "schemars 1.0.4", "serde_core", "serde_json", "serde_with_macros", @@ -9164,14 +8948,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.16.1" +version = "3.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" +checksum = "b91a903660542fced4e99881aa481bdbaec1634568ee02e0b8bd57c64cb38955" dependencies = [ "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -9180,7 +8964,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.12.0", "itoa", "ryu", "serde", @@ -9199,12 +8983,11 @@ dependencies = [ [[package]] name = "serial_test" -version = "3.3.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d0b343e184fc3b7bb44dff0705fffcf4b3756ba6aff420dddd8b24ca145e555" +checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" dependencies = [ - "futures-executor", - "futures-util", + "futures", "log", "once_cell", "parking_lot 0.12.5", @@ -9214,13 +8997,13 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "3.3.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f50427f258fb77356e4cd4aa0e87e2bd2c66dbcee41dc405282cae2bfc26c83" +checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -9282,11 +9065,10 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.8" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" dependencies = [ - "errno", "libc", ] @@ -9302,9 +9084,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.8" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "simdutf8" @@ -9380,7 +9162,7 @@ checksum = "0eb01866308440fc64d6c44d9e86c5cc17adfe33c4d6eed55da9145044d0ffc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -9489,7 +9271,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -9530,9 +9312,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.114" +version = "2.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" dependencies = [ "proc-macro2", "quote", @@ -9541,14 +9323,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "1.5.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f92d01b5de07eaf324f7fca61cc6bd3d82bbc1de5b6c963e6fe79e86f36580d" +checksum = "ff790eb176cc81bb8936aed0f7b9f14fc4670069a2d371b3e3b0ecce908b2cb3" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -9574,7 +9356,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -9665,9 +9447,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "target-lexicon" -version = "0.13.4" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1dd07eb858a2067e2f3c7155d54e929265c264e6f37efe3ee7a8d1b5a1dd0ba" +checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" [[package]] name = "tee-authority" @@ -9675,12 +9457,12 @@ version = "3.2.0" dependencies = [ "anyhow", "backon", - "derive_more 2.1.1", + "derive_more 2.0.1", "dstack-sdk", "hex", - "http 1.4.0", + "http 1.3.1", "mpc-attestation", - "reqwest 0.12.28", + "reqwest 0.12.24", "rstest", "serde", "serde_json", @@ -9691,14 +9473,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.24.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", "getrandom 0.3.4", "once_cell", - "rustix 1.1.3", + "rustix 1.1.2", "windows-sys 0.61.2", ] @@ -9780,7 +9562,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -9791,7 +9573,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -9835,7 +9617,7 @@ dependencies = [ "blstrs", "borsh", "byteorder", - "derive_more 2.1.1", + "derive_more 2.0.1", "digest 0.10.7", "ecdsa", "elliptic-curve", @@ -9949,9 +9731,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.49.0" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ "bytes", "libc", @@ -9972,7 +9754,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -10008,9 +9790,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.18" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" dependencies = [ "futures-core", "pin-project-lite", @@ -10019,9 +9801,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.18" +version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" dependencies = [ "bytes", "futures-core", @@ -10033,20 +9815,20 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.5+spec-1.1.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.23.10+spec-1.0.0" +version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.12.0", "toml_datetime", "toml_parser", "winnow", @@ -10054,9 +9836,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.6+spec-1.1.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" dependencies = [ "winnow", ] @@ -10072,11 +9854,11 @@ dependencies = [ "axum 0.7.9", "base64 0.22.1", "bytes", - "h2 0.4.13", - "http 1.4.0", + "h2 0.4.12", + "http 1.3.1", "http-body 1.0.1", "http-body-util", - "hyper 1.8.1", + "hyper 1.7.0", "hyper-timeout", "hyper-util", "percent-encoding", @@ -10103,10 +9885,10 @@ dependencies = [ "async-trait", "base64 0.22.1", "bytes", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", - "hyper 1.8.1", + "hyper 1.7.0", "hyper-timeout", "hyper-util", "percent-encoding", @@ -10148,7 +9930,7 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", - "indexmap 2.13.0", + "indexmap 2.12.0", "pin-project-lite", "slab", "sync_wrapper 1.0.2", @@ -10161,22 +9943,18 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "async-compression", "bitflags 2.10.0", "bytes", - "futures-core", "futures-util", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", "iri-string", "pin-project-lite", - "tokio", - "tokio-util", "tower 0.5.2", "tower-layer", "tower-service", @@ -10209,9 +9987,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.44" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", @@ -10221,32 +9999,32 @@ dependencies = [ [[package]] name = "tracing-appender" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" dependencies = [ "crossbeam-channel", - "thiserror 2.0.17", + "thiserror 1.0.69", "time", "tracing-subscriber", ] [[package]] name = "tracing-attributes" -version = "0.1.31" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] name = "tracing-core" -version = "0.1.36" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", "valuable", @@ -10293,9 +10071,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "matchers", "nu-ansi-term", @@ -10330,7 +10108,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -10371,21 +10149,15 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicase" -version = "2.9.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" [[package]] name = "unicode-width" @@ -10449,15 +10221,14 @@ dependencies = [ [[package]] name = "url" -version = "2.5.8" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", "serde", - "serde_derive", ] [[package]] @@ -10483,7 +10254,7 @@ name = "utilities" version = "3.2.0" dependencies = [ "near-account-id 1.1.4", - "near-account-id 2.5.0", + "near-account-id 2.0.0", ] [[package]] @@ -10492,7 +10263,7 @@ version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fcc29c80c21c31608227e0912b2d7fddba57ad76b606890627ba8ee7964e993" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.12.0", "serde", "serde_json", "utoipa-gen", @@ -10506,7 +10277,7 @@ checksum = "6d79d08d92ab8af4c5e8a6da20c47ae3f61a0f1dabc1997cdf2d082b757ca08b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -10515,7 +10286,7 @@ version = "9.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d047458f1b5b65237c2f6dc6db136945667f40a7668627b3490b9513a3d43a55" dependencies = [ - "axum 0.8.8", + "axum 0.8.6", "base64 0.22.1", "mime_guess", "regex", @@ -10536,9 +10307,9 @@ checksum = "e2eebbbfe4093922c2b6734d7c679ebfebd704a0d7e56dfcb0d05818ce28977d" [[package]] name = "uuid" -version = "1.19.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ "getrandom 0.3.4", "js-sys", @@ -10571,7 +10342,7 @@ checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -10619,9 +10390,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.106" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" dependencies = [ "cfg-if 1.0.4", "once_cell", @@ -10632,9 +10403,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.56" +version = "0.4.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" +checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0" dependencies = [ "cfg-if 1.0.4", "js-sys", @@ -10645,9 +10416,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.106" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -10655,22 +10426,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.106" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.106" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" dependencies = [ "unicode-ident", ] @@ -10741,7 +10512,7 @@ checksum = "4abf1132c1fdf747d56bbc1bb52152400c70f336870f968b85e89ea422198ae3" dependencies = [ "bitflags 2.10.0", "hashbrown 0.15.5", - "indexmap 2.13.0", + "indexmap 2.12.0", "semver 1.0.27", "serde", ] @@ -10754,7 +10525,7 @@ checksum = "a9b1e81f3eb254cf7404a82cee6926a4a3ccc5aad80cc3d43608a070c67aa1d7" dependencies = [ "bitflags 2.10.0", "hashbrown 0.15.5", - "indexmap 2.13.0", + "indexmap 2.12.0", "semver 1.0.27", "serde", ] @@ -10793,7 +10564,7 @@ dependencies = [ "cc", "cfg-if 1.0.4", "hashbrown 0.15.5", - "indexmap 2.13.0", + "indexmap 2.12.0", "libc", "log", "mach2", @@ -10803,11 +10574,11 @@ dependencies = [ "postcard", "pulley-interpreter", "rayon", - "rustix 1.1.3", + "rustix 1.1.2", "serde", "serde_derive", "smallvec", - "target-lexicon 0.13.4", + "target-lexicon 0.13.3", "wasmparser 0.236.1", "wasmtime-environ", "wasmtime-internal-asm-macros", @@ -10832,14 +10603,14 @@ dependencies = [ "cranelift-bitset", "cranelift-entity", "gimli", - "indexmap 2.13.0", + "indexmap 2.12.0", "log", "object", "postcard", "serde", "serde_derive", "smallvec", - "target-lexicon 0.13.4", + "target-lexicon 0.13.3", "wasm-encoder 0.236.1", "wasmparser 0.236.1", "wasmprinter 0.236.1", @@ -10873,7 +10644,7 @@ dependencies = [ "object", "pulley-interpreter", "smallvec", - "target-lexicon 0.13.4", + "target-lexicon 0.13.3", "thiserror 2.0.17", "wasmparser 0.236.1", "wasmtime-environ", @@ -10891,7 +10662,7 @@ dependencies = [ "cc", "cfg-if 1.0.4", "libc", - "rustix 1.1.3", + "rustix 1.1.2", "wasmtime-internal-asm-macros", "wasmtime-internal-versioned-export-macros", "windows-sys 0.60.2", @@ -10955,14 +10726,14 @@ checksum = "0445c94839f5f76122f6be138ce7d7d53044a8b48a9305a9522460e836e51e0d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] name = "web-sys" -version = "0.3.83" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" dependencies = [ "js-sys", "wasm-bindgen", @@ -10984,14 +10755,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.5", + "webpki-roots 1.0.3", ] [[package]] name = "webpki-roots" -version = "1.0.5" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c" +checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" dependencies = [ "rustls-pki-types", ] @@ -11049,9 +10820,9 @@ checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" [[package]] name = "wildmatch" -version = "2.6.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29333c3ea1ba8b17211763463ff24ee84e41c78224c16b001cd907e663a38c68" +checksum = "39b7d07a236abaef6607536ccfaf19b396dbe3f5110ddb73d39f4562902ed382" [[package]] name = "winapi" @@ -11112,9 +10883,9 @@ checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", - "windows-link", + "windows-link 0.2.1", "windows-result 0.4.1", - "windows-strings", + "windows-strings 0.5.1", ] [[package]] @@ -11125,7 +10896,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -11136,9 +10907,15 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + [[package]] name = "windows-link" version = "0.2.1" @@ -11147,13 +10924,13 @@ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-registry" -version = "0.6.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ - "windows-link", - "windows-result 0.4.1", - "windows-strings", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", ] [[package]] @@ -11165,13 +10942,31 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.3", +] + [[package]] name = "windows-result" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link", + "windows-link 0.2.1", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link 0.1.3", ] [[package]] @@ -11180,7 +10975,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -11225,7 +11020,7 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -11265,7 +11060,7 @@ version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link", + "windows-link 0.2.1", "windows_aarch64_gnullvm 0.53.1", "windows_aarch64_msvc 0.53.1", "windows_i686_gnu 0.53.1", @@ -11416,9 +11211,9 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.14" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" dependencies = [ "memchr", ] @@ -11489,7 +11284,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" dependencies = [ "libc", - "rustix 1.1.3", + "rustix 1.1.2", ] [[package]] @@ -11535,28 +11330,28 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.33" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.33" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -11576,7 +11371,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", "synstructure", ] @@ -11591,13 +11386,13 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.4.3" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] @@ -11643,37 +11438,27 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.108", ] [[package]] name = "zip" -version = "2.4.2" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" dependencies = [ "aes", - "arbitrary", + "byteorder", "bzip2", "constant_time_eq", "crc32fast", "crossbeam-utils", - "deflate64", - "displaydoc", "flate2", - "getrandom 0.3.4", "hmac", - "indexmap 2.13.0", - "lzma-rs", - "memchr", "pbkdf2", "sha1", - "thiserror 2.0.17", "time", - "xz2", - "zeroize", - "zopfli", - "zstd", + "zstd 0.11.2+zstd.1.5.2", ] [[package]] @@ -11685,22 +11470,16 @@ dependencies = [ "arbitrary", "crc32fast", "flate2", - "indexmap 2.13.0", + "indexmap 2.12.0", "memchr", "zopfli", ] [[package]] name = "zlib-rs" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40990edd51aae2c2b6907af74ffb635029d5788228222c4bb811e9351c0caad3" - -[[package]] -name = "zmij" -version = "1.0.12" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fc5a66a20078bf1251bde995aa2fdcc4b800c70b5d92dd2c62abc5c60f679f8" +checksum = "2f06ae92f42f5e5c42443fd094f245eb656abf56dd7cce9b8b263236565e00f2" [[package]] name = "zopfli" @@ -11714,13 +11493,32 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe 5.0.2+zstd.1.5.2", +] + [[package]] name = "zstd" version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ - "zstd-safe", + "zstd-safe 7.2.4", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index eac95eaaba..eec1158911 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,6 +91,7 @@ hyper = { version = "0.14.32", features = ["server", "http1", "tcp", "stream"] } insta = { version = "1.43.1", features = ["json", "redactions"] } itertools = "0.12.1" k256 = "0.13.4" +lru = "0.12.5" mockall = "0.13.1" near-abi = "0.4.3" near-account-id = "2.0.0" diff --git a/crates/node/Cargo.toml b/crates/node/Cargo.toml index c2a3b83346..933e5b7425 100644 --- a/crates/node/Cargo.toml +++ b/crates/node/Cargo.toml @@ -29,6 +29,7 @@ humantime = { workspace = true } hyper = { workspace = true } itertools = { workspace = true } k256 = { workspace = true } +lru = { workspace = true } mpc-attestation = { workspace = true } mpc-contract = { workspace = true } mpc-tls = { workspace = true } diff --git a/deny.toml b/deny.toml index 9a7fcf705e..003d1ed43b 100644 --- a/deny.toml +++ b/deny.toml @@ -30,19 +30,12 @@ ignore = [ # - `ruint::algorithms::div::reciprocal_mg10` has undefined behavior, no fix available as of now. # - `ruint` is a transitive dependency through `alloy`. # - The affected function is unused in alloy (ref: recmo/uint#550, alloy-rs/alloy#3416). - "RUSTSEC-2026-0002", # lru unsound advisory - transitive via nearcore@2.10.3 + "RUSTSEC-2025-0137", ] [bans] multiple-versions = "deny" -skip = [ - { name = "prost-types" }, - # near-sdk v5.24.0 pulls in old near-primitives/near-fmt/near-time (0.34.3) - # while nearcore v2.10.3 pulls in newer versions (2.10.3) - { name = "near-fmt" }, - { name = "near-primitives" }, - { name = "near-time" }, -] +skip = [{ name = "prost-types" }] skip-tree = [ { name = "reqwest" }, { name = "axum" }, From 0ebbc18002c450709e9013bbba95435ccae5ca8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Wed, 7 Jan 2026 19:47:29 +0100 Subject: [PATCH 30/45] fix: update deny.toml to include additional advisories and adjust skip settings for dependencies --- deny.toml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/deny.toml b/deny.toml index 003d1ed43b..b35742b793 100644 --- a/deny.toml +++ b/deny.toml @@ -31,11 +31,20 @@ ignore = [ # - `ruint` is a transitive dependency through `alloy`. # - The affected function is unused in alloy (ref: recmo/uint#550, alloy-rs/alloy#3416). "RUSTSEC-2025-0137", + # Transitive via nearcore (lru 0.12.x); upgrade blocked without bumping nearcore + "RUSTSEC-2026-0002", ] [bans] multiple-versions = "deny" -skip = [{ name = "prost-types" }] +skip = [ + { name = "prost-types" }, + # Allow multiple versions pulled transitively by near-sdk/nearcore + { name = "lru" }, + { name = "near-fmt" }, + { name = "near-primitives" }, + { name = "near-time" }, +] skip-tree = [ { name = "reqwest" }, { name = "axum" }, From 8dcea80ec0b90445c2659cb97bb1a775c037b1c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Thu, 8 Jan 2026 18:30:45 +0100 Subject: [PATCH 31/45] feat: add P2P ping/pong metrics for monitoring connection health --- crates/node/src/metrics.rs | 40 ++++++++++++++++++++++++++++++++++++++ crates/node/src/p2p.rs | 13 +++++++++++++ 2 files changed, 53 insertions(+) diff --git a/crates/node/src/metrics.rs b/crates/node/src/metrics.rs index ec53b77d45..9176db33d8 100644 --- a/crates/node/src/metrics.rs +++ b/crates/node/src/metrics.rs @@ -315,3 +315,43 @@ pub static PARTICIPANT_TOTAL_TIMES_SEEN_IN_FAILED_SIGNATURE_COMPUTATION_FOLLOWER ) .unwrap() }); + +// P2P Ping/Pong metrics for monitoring connection health + +pub static MPC_P2P_PING_SEQUENCE_SENT: LazyLock = LazyLock::new(|| { + prometheus::register_int_gauge_vec!( + "mpc_p2p_ping_sequence_sent", + "Latest ping sequence number sent to each peer", + &["peer_id"], + ) + .unwrap() +}); + +pub static MPC_P2P_PONG_SEQUENCE_RECEIVED: LazyLock = + LazyLock::new(|| { + prometheus::register_int_gauge_vec!( + "mpc_p2p_pong_sequence_received", + "Latest pong sequence number received from each peer", + &["peer_id"], + ) + .unwrap() + }); + +pub static MPC_P2P_RTT_SECONDS: LazyLock = LazyLock::new(|| { + prometheus::register_gauge_vec!( + "mpc_p2p_rtt_seconds", + "Latest round-trip time in seconds to each peer", + &["peer_id"], + ) + .unwrap() +}); + +pub static MPC_P2P_STALE_PONGS_RECEIVED: LazyLock = + LazyLock::new(|| { + prometheus::register_int_counter_vec!( + "mpc_p2p_stale_pongs_received", + "Number of stale pong packets received from each peer (indicates reconnect issues)", + &["peer_id"], + ) + .unwrap() + }); diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 068c32507f..94449bdbf5 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -307,6 +307,7 @@ impl TlsConnection { let keepalive_task = tracking::spawn( &format!("Ping sender for {}", target_participant_id), async move { + let peer_id_str = target_participant_id.to_string(); let mut seq: u64 = 0; loop { seq += 1; @@ -316,6 +317,9 @@ impl TlsConnection { // dropped (i.e. connection is closed). return; } + crate::metrics::MPC_P2P_PING_SEQUENCE_SENT + .with_label_values(&[&peer_id_str]) + .set(seq as i64); // Wait for pong matching this ping, ignoring stale pongs let deadline = Instant::now() + Self::PONG_TIMEOUT; @@ -326,12 +330,21 @@ impl TlsConnection { let pong_info = *pong_rx.borrow_and_update(); if pong_info.seq == seq { let rtt = ping_sent_at.elapsed(); + crate::metrics::MPC_P2P_PONG_SEQUENCE_RECEIVED + .with_label_values(&[&peer_id_str]) + .set(seq as i64); + crate::metrics::MPC_P2P_RTT_SECONDS + .with_label_values(&[&peer_id_str]) + .set(rtt.as_secs_f64()); tracking::set_progress(&format!( "Received pong {} from {target_participant_id}, RTT: {rtt:?}", seq )); break; } + crate::metrics::MPC_P2P_STALE_PONGS_RECEIVED + .with_label_values(&[&peer_id_str]) + .inc(); tracing::debug!( peer = %target_participant_id, received_seq = pong_info.seq, From e74745154c4c7119135747a4b550baea3c7db003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Thu, 8 Jan 2026 18:40:45 +0100 Subject: [PATCH 32/45] refactor: remove extra loop --- crates/node/src/metrics.rs | 10 ----- crates/node/src/p2p.rs | 76 ++++++++++++++++---------------------- 2 files changed, 32 insertions(+), 54 deletions(-) diff --git a/crates/node/src/metrics.rs b/crates/node/src/metrics.rs index 9176db33d8..1fceac98cc 100644 --- a/crates/node/src/metrics.rs +++ b/crates/node/src/metrics.rs @@ -345,13 +345,3 @@ pub static MPC_P2P_RTT_SECONDS: LazyLock = LazyLock::new(| ) .unwrap() }); - -pub static MPC_P2P_STALE_PONGS_RECEIVED: LazyLock = - LazyLock::new(|| { - prometheus::register_int_counter_vec!( - "mpc_p2p_stale_pongs_received", - "Number of stale pong packets received from each peer (indicates reconnect issues)", - &["peer_id"], - ) - .unwrap() - }); diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 94449bdbf5..a161914f58 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -321,50 +321,38 @@ impl TlsConnection { .with_label_values(&[&peer_id_str]) .set(seq as i64); - // Wait for pong matching this ping, ignoring stale pongs - let deadline = Instant::now() + Self::PONG_TIMEOUT; - loop { - let remaining = deadline.saturating_duration_since(Instant::now()); - match tokio::time::timeout(remaining, pong_rx.changed()).await { - Ok(Ok(())) => { - let pong_info = *pong_rx.borrow_and_update(); - if pong_info.seq == seq { - let rtt = ping_sent_at.elapsed(); - crate::metrics::MPC_P2P_PONG_SEQUENCE_RECEIVED - .with_label_values(&[&peer_id_str]) - .set(seq as i64); - crate::metrics::MPC_P2P_RTT_SECONDS - .with_label_values(&[&peer_id_str]) - .set(rtt.as_secs_f64()); - tracking::set_progress(&format!( - "Received pong {} from {target_participant_id}, RTT: {rtt:?}", - seq - )); - break; - } - crate::metrics::MPC_P2P_STALE_PONGS_RECEIVED - .with_label_values(&[&peer_id_str]) - .inc(); - tracing::debug!( - peer = %target_participant_id, - received_seq = pong_info.seq, - expected_seq = seq, - "Received stale pong, waiting for expected sequence" - ); - } - Ok(Err(_)) => { - // Exit to trigger reconnection by PersistentConnection - return; - } - Err(_) => { - tracing::warn!( - peer = %target_participant_id, - timeout = ?Self::PONG_TIMEOUT, - "No pong received, closing connection" - ); - closed_for_keepalive.cancel(); - return; - } + // Wait for pong matching this ping (non-matching pongs are silently ignored) + match tokio::time::timeout( + Self::PONG_TIMEOUT, + pong_rx.wait_for(|info| info.seq == seq), + ) + .await + { + Ok(Ok(_)) => { + let rtt = ping_sent_at.elapsed(); + crate::metrics::MPC_P2P_PONG_SEQUENCE_RECEIVED + .with_label_values(&[&peer_id_str]) + .set(seq as i64); + crate::metrics::MPC_P2P_RTT_SECONDS + .with_label_values(&[&peer_id_str]) + .set(rtt.as_secs_f64()); + tracking::set_progress(&format!( + "Received pong {} from {target_participant_id}, RTT: {rtt:?}", + seq + )); + } + Ok(Err(_)) => { + // Channel closed, exit to trigger reconnection + return; + } + Err(_) => { + tracing::warn!( + peer = %target_participant_id, + timeout = ?Self::PONG_TIMEOUT, + "No pong received, closing connection" + ); + closed_for_keepalive.cancel(); + return; } } // Wait until PING_INTERVAL has elapsed since ping was sent From 4dd94d9e408dc634a5f3787880ba3ce8249a0c2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Thu, 8 Jan 2026 18:45:03 +0100 Subject: [PATCH 33/45] fix: optimize ping interval handling --- crates/node/src/p2p.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index a161914f58..d12add911b 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -356,10 +356,10 @@ impl TlsConnection { } } // Wait until PING_INTERVAL has elapsed since ping was sent - let elapsed = ping_sent_at.elapsed(); - if elapsed < Self::PING_INTERVAL { - tokio::time::sleep(Self::PING_INTERVAL - elapsed).await; - } + tokio::time::sleep_until(tokio::time::Instant::from_std( + ping_sent_at + Self::PING_INTERVAL, + )) + .await; } }, ); From a3eb46c0d835d8989ae4ac11e38be7e3e9e5d679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Thu, 8 Jan 2026 18:49:19 +0100 Subject: [PATCH 34/45] fix: improve ping interval handling with tick() --- crates/node/src/p2p.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index d12add911b..d136c46482 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -309,7 +309,11 @@ impl TlsConnection { async move { let peer_id_str = target_participant_id.to_string(); let mut seq: u64 = 0; + let mut interval = tokio::time::interval(Self::PING_INTERVAL); + interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay); + loop { + interval.tick().await; seq += 1; let ping_sent_at = Instant::now(); if sender_clone.send(Packet::Ping(seq)).is_err() { @@ -355,11 +359,6 @@ impl TlsConnection { return; } } - // Wait until PING_INTERVAL has elapsed since ping was sent - tokio::time::sleep_until(tokio::time::Instant::from_std( - ping_sent_at + Self::PING_INTERVAL, - )) - .await; } }, ); From c022c5ad35cdfe54504e5a649a6ebf599b27fed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Thu, 8 Jan 2026 18:52:45 +0100 Subject: [PATCH 35/45] fix: standardize log messages and error contexts to lowercase --- crates/node/src/p2p.rs | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index d136c46482..1908adb6e2 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -251,16 +251,16 @@ impl TlsConnection { .context("TLS connect")?; let peer_id = verify_peer_identity(tls_conn.get_ref().1, participant_identities) - .context("Verify server identity")?; + .context("verify server identity")?; if peer_id != target_participant_id { anyhow::bail!( - "Incorrect peer identity, expected {}, authenticated {}", + "incorrect peer identity, expected {}, authenticated {}", target_participant_id, peer_id ); } - info!(target_address, "Performing P2P handshake"); + info!(target_address, "performing P2P handshake"); p2p_handshake(&mut tls_conn, Self::HANDSHAKE_TIMEOUT) .await .context("p2p handshake")?; @@ -282,12 +282,12 @@ impl TlsConnection { break; }; let serialized = borsh::to_vec(&data)?; - let len: u32 = serialized.len().try_into().context("Message too long")?; + let len: u32 = serialized.len().try_into().context("message too long")?; tls_conn.write_u32(len).await?; tls_conn.write_all(&serialized).await?; sent_bytes += 4 + len as u64; - tracking::set_progress(&format!("Sent {sent_bytes} bytes")); + tracking::set_progress(&format!("sent {sent_bytes} bytes")); } _ = tls_conn.read_u8() => { // We do not expect any data from the other side. However, @@ -353,7 +353,7 @@ impl TlsConnection { tracing::warn!( peer = %target_participant_id, timeout = ?Self::PONG_TIMEOUT, - "No pong received, closing connection" + "no pong received, closing connection" ); closed_for_keepalive.cancel(); return; @@ -439,7 +439,7 @@ impl PersistentConnection { tracing::info!( from = %my_id, to = %target_participant_id, - "Outgoing connection established" + "outgoing connection established" ); connectivity.set_outgoing_connection(&new_conn); @@ -452,7 +452,7 @@ impl PersistentConnection { tracing::warn!( seq = pending_seq, peer = %target_participant_id, - "Failed to send pending pong, reconnecting" + "failed to send pending pong, reconnecting" ); continue; } @@ -464,7 +464,7 @@ impl PersistentConnection { peer = %target_participant_id, error = format!("{e:#}"), me = %my_id, - "Could not connect, retrying" + "could not connect, retrying" ); tokio::time::sleep(Self::CONNECTION_RETRY_DELAY).await; } @@ -499,7 +499,7 @@ pub async fn new_tls_mesh_network( .map(|participant| participant.port) .ok_or_else(|| anyhow!("My ID not found in participants"))?; - info!("Preparing participant data."); + info!("preparing participant data"); // Prepare participant data. let mut participant_identities = ParticipantIdentities::default(); let mut connections = HashMap::new(); @@ -552,7 +552,7 @@ pub async fn new_tls_mesh_network( let connectivities_clone = connectivities.clone(); let my_id = config.my_participant_id; let connections_for_incoming = connections.clone(); - info!("Spawning incoming connections handler."); + info!("spawning incoming connections handler"); let incoming_connections_task = tracking::spawn("Handle incoming connections", async move { let mut tasks = AutoAbortTaskCollection::new(); while let Ok((tcp_stream, _)) = tcp_listener.accept().await { @@ -568,11 +568,11 @@ pub async fn new_tls_mesh_network( let mut stream = tls_acceptor.accept(tcp_stream).await?; let peer_id = verify_peer_identity(stream.get_ref().1, &participant_identities)?; - tracking::set_progress(&format!("Authenticated as {peer_id}")); + tracking::set_progress(&format!("authenticated as {peer_id}")); p2p_handshake(&mut stream, TlsConnection::HANDSHAKE_TIMEOUT) .await .context("p2p handshake")?; - tracing::info!(to = %my_id, from = %peer_id, "Incoming connection established"); + tracing::info!(to = %my_id, from = %peer_id, "incoming connection established"); let incoming_conn = Arc::new(()); connectivities .get(peer_id)? @@ -585,7 +585,7 @@ pub async fn new_tls_mesh_network( ) .await??; if len >= MAX_MESSAGE_LEN { - anyhow::bail!("Message too long"); + anyhow::bail!("message too long"); } let mut buf = vec![0; len as usize]; tokio::time::timeout( @@ -596,7 +596,7 @@ pub async fn new_tls_mesh_network( received_bytes += 4 + len as u64; let packet = - Packet::try_from_slice(&buf).context("Failed to deserialize packet")?; + Packet::try_from_slice(&buf).context("failed to deserialize packet")?; match packet { Packet::Ping(seq) => { // Send Pong via our outgoing connection to the peer, maintaining @@ -604,7 +604,7 @@ pub async fn new_tls_mesh_network( // to be sent when the connection becomes ready. let Some(conn) = connections.get(&peer_id) else { // Peer authenticated but not in connections map - indicates a bug - tracing::warn!(peer = %peer_id, seq, "Received Ping from peer not in connections map"); + tracing::warn!(peer = %peer_id, seq, "received ping from peer not in connections map"); continue; }; if let Some(outgoing_conn) = @@ -614,7 +614,7 @@ pub async fn new_tls_mesh_network( // Close incoming so peer detects disconnect and both sides reconnect cleanly tracing::info!( peer = %peer_id, - "Outgoing connection is dead, closing incoming connection for clean reconnect" + "outgoing connection is dead, closing incoming connection for clean reconnect" ); break; } @@ -636,10 +636,10 @@ pub async fn new_tls_mesh_network( // meaning the connection is already closing. let _ = outgoing_conn.pong_tx.send(PongInfo { seq }); } else { - tracing::warn!(peer = %peer_id, seq, "No outgoing connection to forward Pong"); + tracing::warn!(peer = %peer_id, seq, "no outgoing connection to forward pong"); } } else { - tracing::warn!(peer = %peer_id, seq, "No connection found for peer to forward Pong"); + tracing::warn!(peer = %peer_id, seq, "no connection found for peer to forward pong"); } } Packet::MpcMessage(mpc_message) => { @@ -659,7 +659,7 @@ pub async fn new_tls_mesh_network( } tracking::set_progress(&format!( - "Received {received_bytes} bytes from {peer_id}" + "received {received_bytes} bytes from {peer_id}" )); } anyhow::Ok(()) @@ -696,7 +696,7 @@ fn verify_peer_identity( .key_to_participant_id .get(&public_key) else { - anyhow::bail!("Connection with unknown public key"); + anyhow::bail!("connection with unknown public key"); }; Ok(*peer_id) } From 720ef1e50842b387af297ab1f020e11e8d6b1b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Thu, 8 Jan 2026 19:02:17 +0100 Subject: [PATCH 36/45] fix: improve logging for connection closure and reconnection handling --- crates/node/src/p2p.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 1908adb6e2..a4dc5883f9 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -458,6 +458,10 @@ impl PersistentConnection { } new_conn.wait_for_close().await; + tracing::info!( + peer = %target_participant_id, + "connection closed, reconnecting" + ); } Err(e) => { tracing::warn!( @@ -611,10 +615,10 @@ pub async fn new_tls_mesh_network( conn.connectivity.any_outgoing_connection() { if outgoing_conn.sender.send(Packet::Pong(seq)).is_err() { - // Close incoming so peer detects disconnect and both sides reconnect cleanly + // Close incoming so peer detects disconnect and both sides reconnect tracing::info!( peer = %peer_id, - "outgoing connection is dead, closing incoming connection for clean reconnect" + "outgoing connection is dead" ); break; } From 74177b90be6a2e42d982ee678a16ab2bdd01350c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Thu, 15 Jan 2026 11:34:12 +0100 Subject: [PATCH 37/45] Revert deny.toml --- deny.toml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/deny.toml b/deny.toml index 2a7b04ee8d..016eedb550 100644 --- a/deny.toml +++ b/deny.toml @@ -32,14 +32,7 @@ ignore = [ [bans] multiple-versions = "deny" -skip = [ - { name = "prost-types" }, - # Allow multiple versions pulled transitively by near-sdk/nearcore - { name = "lru" }, - { name = "near-fmt" }, - { name = "near-primitives" }, - { name = "near-time" }, -] +skip = [{ name = "prost-types" }] skip-tree = [ { name = "axum" }, { name = "near-jsonrpc-client" }, From eed1da866a606b070a272a81337e357fd1cc076d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Thu, 15 Jan 2026 11:44:02 +0100 Subject: [PATCH 38/45] fix(p2p): handle overflow in TLS sequence number --- crates/node/src/p2p.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 6c9d6459b7..ccdb6fc632 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -318,7 +318,15 @@ impl TlsConnection { loop { interval.tick().await; - seq += 1; + seq = match seq.checked_add(1) { + Some(new_seq) => new_seq, + None => { + tracing::warn!( + "TLS sequence number exceeded u64::MAX - closing connection" + ); + return; + } + }; let ping_sent_at = Instant::now(); if sender_clone.send(Packet::Ping(seq)).is_err() { // The receiver side will be dropped when the sender task is From 0164312676c69491afdde90daa7a35d728d98e6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Thu, 15 Jan 2026 12:01:19 +0100 Subject: [PATCH 39/45] fix(p2p): handle overflow in TLS sequence number by converting to i64 --- crates/node/src/p2p.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index ccdb6fc632..8afcc53f15 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -333,9 +333,13 @@ impl TlsConnection { // dropped (i.e. connection is closed). return; } + let Ok(seq_i64) = i64::try_from(seq) else { + tracing::warn!(seq, "TLS sequence number exceeded i64::MAX - closing connection"); + return; + }; crate::metrics::MPC_P2P_PING_SEQUENCE_SENT .with_label_values(&[&peer_id_str]) - .set(seq as i64); + .set(seq_i64); // Wait for pong matching this ping (non-matching pongs are silently ignored) match tokio::time::timeout( From c71a0501e75c9e3feb6e550328b26bc47c8e0ded Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Thu, 15 Jan 2026 14:05:53 +0100 Subject: [PATCH 40/45] refactor + tests --- crates/node/Cargo.toml | 1 + crates/node/src/p2p.rs | 771 +++++++++++++++++++++++++++++------------ 2 files changed, 550 insertions(+), 222 deletions(-) diff --git a/crates/node/Cargo.toml b/crates/node/Cargo.toml index f96e8ef752..e1316d073a 100644 --- a/crates/node/Cargo.toml +++ b/crates/node/Cargo.toml @@ -88,4 +88,5 @@ near-sdk = { workspace = true } rstest = { workspace = true } serial_test = { workspace = true } threshold-signatures = { workspace = true, features = ["test-utils"] } +tokio = { workspace = true, features = ["test-util"] } tracing-test = { workspace = true } diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 8afcc53f15..8080ab692c 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -42,21 +42,25 @@ use crate::{ /// immediately, reducing latency for node messages at the cost of higher packet overhead. const TCP_NODELAY: bool = true; -/// This struct manages **outgoing connections only** - one persistent TLS connection to each -/// peer in the network. When the application wants to send a message to a peer, it queues the -/// message through the corresponding [`PersistentConnection`], which handles automatic -/// reconnection if the connection drops. Each connection runs two background tasks: one for -/// sending data, and one for sending 1-second interval ping heartbeats and monitoring pong responses. -/// -/// Implements the [`MeshNetworkTransportSender`] trait to provide a high-level API for sending -/// messages (`.send()`, `.send_indexer_height()`) and checking connectivity status -/// (`.connectivity()`, `.wait_for_ready()`), while handling low-level connection management. +/// TCP-level keepalive configuration constants. These configure the OS-level TCP keepalive +/// mechanism, which is separate from our application-level ping/pong keepalive (see +/// [`KeepaliveConfig`]). TCP keepalive detects dead connections at the transport layer. const TCP_CONNECTION_KEEPALIVE_DELAY: std::time::Duration = std::time::Duration::from_secs(3); const TCP_CONNECTION_RETRY_DELAY: std::time::Duration = std::time::Duration::from_secs(1); const TCP_CONNECTION_RETRIES: u32 = 3; -/// Implements MeshNetworkTransportSender for sending messages over a TLS-based -/// mesh network. +/// Manages **outgoing connections only** - one persistent TLS connection to each peer in the +/// network. +/// +/// When the application wants to send a message to a peer, it queues the message through the +/// corresponding [`PersistentConnection`], which handles automatic reconnection if the +/// connection drops. Each connection runs two background tasks: one for sending data, and one +/// for sending ping heartbeats (at [`KeepaliveConfig::ping_interval`]) and monitoring pong +/// responses. +/// +/// Implements the [`MeshNetworkTransportSender`] trait to provide a high-level API for sending +/// messages (`.send()`, `.send_indexer_height()`) and checking connectivity status +/// (`.connectivity()`, `.wait_for_ready()`), while handling low-level connection management. pub struct TlsMeshSender { /// The participant ID of this node. my_id: ParticipantId, @@ -71,7 +75,7 @@ pub struct TlsMeshSender { /// our outgoing connections, `connectivities` tracks whether both our outgoing connection /// to a peer AND their incoming connection to us are alive. Used by `.wait_for_ready()` /// and `.connectivity()` to check bidirectional connectivity status. - connectivities: Arc>, + connectivities: Arc>, } /// This struct manages **incoming connections only** - it accepts TLS connections from all @@ -121,30 +125,22 @@ struct ParticipantIdentities { /// Maintains a persistent outgoing TLS connection to a single peer with automatic reconnection. /// -/// This struct wraps a [`TlsConnection`] and ensures it stays alive throughout the lifetime of -/// the node. If the underlying TCP/TLS connection drops (due to network issues, peer restart, -/// etc.), the background task automatically attempts to reconnect after a 1-second delay. Each -/// [`TlsMeshSender`] owns one `PersistentConnection` per peer in the network (N-1 total). +/// This struct wraps an [`OutgoingConnection`] and provides the state needed for maintaining +/// a connection throughout the lifetime of the node. The reconnection logic runs in a separate +/// task spawned by the caller via [`run_persistent_connection()`]. +/// +/// Each [`TlsMeshSender`] owns one [`PersistentConnection`] per peer in the network (N-1 total). struct PersistentConnection { target_participant_id: ParticipantId, - connectivity: Arc>, + connectivity: Arc>, /// Stores the latest pong sequence number to send when outgoing connection becomes ready. /// Uses a watch channel so we only keep the most recent value. pending_pong: watch::Sender, /// Background reconnection task that maintains the connection lifecycle. /// - /// This task runs an infinite loop that: - /// 1. Attempts to establish a new [`TlsConnection`] to `target_participant_id` - /// 2. On success: Registers the connection with `connectivity`, sends any buffered - /// pending pong, and blocks waiting for it to close (via `wait_for_close()`) - /// 3. On failure: Logs the error and sleeps for - /// [`PersistentConnection::CONNECTION_RETRY_DELAY`] before retrying - /// 4. When a connection closes (step 2 completes): Loops back to step 1 - /// - /// The task owns the active [`TlsConnection`] (wrapped in Arc), so when the task is - /// aborted (via dropping this `PersistentConnection`), the connection is automatically - /// cleaned up. The [`AutoAbortTask`] wrapper ensures the task is aborted when this struct - /// is dropped, providing RAII-style cleanup on node shutdown. + /// This task is spawned by the caller and runs [`run_persistent_connection()`], which + /// handles the reconnection loop. The [`AutoAbortTask`] wrapper ensures the task is + /// aborted when this struct is dropped, providing RAII-style cleanup on node shutdown. _task: AutoAbortTask<()>, } @@ -156,46 +152,47 @@ struct PersistentConnection { /// channel, and the background `_sender_task` reads from the channel and writes to the TLS /// stream. Pong responses arrive via the separate incoming connection and are forwarded to /// the keepalive task via the `pong_tx` watch channel for health monitoring. -struct TlsConnection { +struct OutgoingConnection { /// Channel for queuing outbound packets ([`Packet::Ping`], [`Packet::MpcMessage`], /// [`Packet::IndexerHeight`]) to be sent. /// - /// The application sends messages by calling `.send_mpc_message()` or `.send_indexer_height()`, - /// which queue packets into this channel. The `_sender_task` continuously reads from the - /// receiver end of this channel and writes packets to the TLS stream. This decouples message - /// sending from I/O operations, allowing the application to queue messages without blocking - /// on network writes. + /// The application sends messages by calling [`send_mpc_message()`](Self::send_mpc_message) or + /// [`send_indexer_height()`](Self::send_indexer_height), which queue packets into this channel. + /// The [`_sender_task`](Self::_sender_task) continuously reads from the receiver end of this + /// channel and writes packets to the TLS stream. This decouples message sending from I/O + /// operations, allowing the application to queue messages without blocking on network writes. sender: UnboundedSender, /// Background task that owns the TLS stream and handles write-only I/O operations. /// - /// This task continuously reads packets from the `sender` channel and writes them to the - /// TLS stream. The stream is used unidirectionally - only for sending. Connection health - /// monitoring is handled by the keepalive task which cancels the `closed` token when - /// a pong timeout occurs. When this task is aborted (via [`AutoAbortTask`] drop), it closes - /// the underlying TLS/TCP stream, which triggers [`PersistentConnection`] to reconnect. + /// This task continuously reads packets from the [`sender`](Self::sender) channel and writes + /// them to the TLS stream. The stream is used unidirectionally - only for sending. Connection + /// health monitoring is handled by the keepalive task which cancels the [`closed`](Self::closed) + /// token when a pong timeout occurs. When this task is aborted (via [`AutoAbortTask`] drop), + /// it closes the underlying TLS/TCP stream, which triggers [`PersistentConnection`] to reconnect. _sender_task: AutoAbortTask<()>, /// Background task that sends Ping heartbeats and monitors Pong responses. /// - /// This task sends a Ping with an incrementing sequence number and then waits for either a - /// Pong response (via the `pong_rx` watch channel) or a timeout. When a Pong is received, - /// it validates the sequence number, calculates RTT, and waits until [`Self::PING_INTERVAL`] - /// (1 second) has elapsed since the ping was sent before sending the next one. If no Pong is - /// received within [`Self::PONG_TIMEOUT`] (20 seconds), it closes the connection by cancelling - /// the `closed` token. This ensures pings are sent at exactly 1-second intervals while only - /// sending when the previous ping received a response. + /// This task sends a [`Ping`](Packet::Ping) with an incrementing sequence number and then + /// waits for either a [`Pong`](Packet::Pong) response (via a watch channel) or a timeout. + /// When a Pong is received, it validates the sequence number, calculates RTT, and waits until + /// [`KeepaliveConfig::ping_interval`] (default 1 second) has elapsed since the ping was sent + /// before sending the next one. If no Pong is received within + /// [`KeepaliveConfig::pong_timeout`] (default 20 seconds), it closes the connection by + /// cancelling the [`closed`](Self::closed) token. This ensures pings are sent at regular + /// intervals while only sending when the previous ping received a response. _keepalive_task: AutoAbortTask<()>, /// Watch channel sender for delivering pong notifications to the keepalive task. /// - /// The incoming handler sends PongInfo when it receives a Pong packet. The keepalive task - /// monitors this channel to detect connection health and calculate RTT. This enables clean - /// async communication without mutexes. + /// The incoming handler sends [`PongInfo`] when it receives a [`Pong`](Packet::Pong) packet. + /// The keepalive task monitors this channel to detect connection health and calculate RTT. + /// This enables clean async communication without mutexes. pong_tx: tokio::sync::watch::Sender, /// Token that gets cancelled when the connection closes, allowing waiters to be notified. /// - /// Used by [`PersistentConnection`] via the `wait_for_close()` method to block until the - /// connection dies (either due to network failure, timeout, or intentional shutdown). When - /// `_sender_task` exits, the [`DropToCancel`] guard automatically cancels this token, - /// unblocking any tasks waiting on it. + /// Used by [`PersistentConnection`] via the [`wait_for_close()`](Self::wait_for_close) method + /// to block until the connection dies (either due to network failure, timeout, or intentional + /// shutdown). When [`_sender_task`](Self::_sender_task) exits, the [`DropToCancel`] guard + /// automatically cancels this token, unblocking any tasks waiting on it. closed: CancellationToken, } @@ -216,7 +213,126 @@ struct PongInfo { seq: u64, } -#[derive(BorshSerialize, BorshDeserialize)] +/// Configuration for the keepalive mechanism that monitors connection health. +/// +/// Allows configuring ping/pong timing for [`OutgoingConnection`]. Useful for testing +/// with shorter timeouts than the production defaults. +#[derive(Clone, Copy, Debug)] +pub struct KeepaliveConfig { + /// Interval between ping messages. Pings are sent at this interval from when + /// the previous ping was sent, waiting for pong response before sending the next. + pub ping_interval: std::time::Duration, + /// Maximum time to wait for a pong response before considering the connection dead. + pub pong_timeout: std::time::Duration, +} + +impl KeepaliveConfig { + /// Pings are sent at 1-second intervals from when the previous ping was sent, + /// waiting for pong response before sending the next. + pub const DEFAULT_PING_INTERVAL: std::time::Duration = std::time::Duration::from_secs(1); + + /// If we don't receive a pong response within this time, consider the connection dead. + pub const DEFAULT_PONG_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(20); +} + +impl Default for KeepaliveConfig { + fn default() -> Self { + Self { + ping_interval: Self::DEFAULT_PING_INTERVAL, + pong_timeout: Self::DEFAULT_PONG_TIMEOUT, + } + } +} + +/// Runs the keepalive loop that sends pings and monitors pong responses. +/// +/// This standalone function allows unit testing of timeout behavior without requiring +/// real TCP/TLS connections. Used by [`OutgoingConnection`] to monitor connection health. +/// +/// # Arguments +/// * `ping_sender` - Channel to send ping packets through +/// * `pong_rx` - Watch channel receiver to monitor for pong responses +/// * `config` - Keepalive timing configuration +/// * `closed` - Cancellation token to signal connection closure on timeout +/// * `peer_id` - Peer identifier for logging and metrics +/// +/// # Returns +/// Returns when the connection should be closed (timeout, channel closed, or overflow). +async fn run_keepalive( + ping_sender: UnboundedSender, + mut pong_rx: watch::Receiver, + config: KeepaliveConfig, + closed: CancellationToken, + peer_id: ParticipantId, +) { + let peer_id_str = peer_id.to_string(); + let mut seq: u64 = 0; + let mut interval = tokio::time::interval(config.ping_interval); + interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay); + + loop { + interval.tick().await; + seq = match seq.checked_add(1) { + Some(new_seq) => new_seq, + None => { + tracing::warn!("keepalive sequence number exceeded u64::MAX - closing connection"); + return; + } + }; + let ping_sent_at = Instant::now(); + if ping_sender.send(Packet::Ping(seq)).is_err() { + // The receiver side will be dropped when the sender task is + // dropped (i.e. connection is closed). + return; + } + let Ok(seq_i64) = i64::try_from(seq) else { + tracing::warn!( + seq, + "keepalive sequence number exceeded i64::MAX - closing connection" + ); + return; + }; + crate::metrics::MPC_P2P_PING_SEQUENCE_SENT + .with_label_values(&[&peer_id_str]) + .set(seq_i64); + + // Wait for pong matching this ping (non-matching pongs are silently ignored) + match tokio::time::timeout( + config.pong_timeout, + pong_rx.wait_for(|info| info.seq == seq), + ) + .await + { + Ok(Ok(_)) => { + let rtt = ping_sent_at.elapsed(); + crate::metrics::MPC_P2P_PONG_SEQUENCE_RECEIVED + .with_label_values(&[&peer_id_str]) + .set(seq_i64); + crate::metrics::MPC_P2P_RTT_SECONDS + .with_label_values(&[&peer_id_str]) + .set(rtt.as_secs_f64()); + tracking::set_progress(&format!( + "received pong {seq} from {peer_id}, RTT: {rtt:?}" + )); + } + Ok(Err(_)) => { + // Channel closed, exit to trigger reconnection + return; + } + Err(_) => { + tracing::warn!( + peer = %peer_id, + timeout = ?config.pong_timeout, + "no pong received, closing connection" + ); + closed.cancel(); + return; + } + } + } +} + +#[derive(BorshSerialize, BorshDeserialize, Debug)] enum Packet { Ping(u64), Pong(u64), @@ -224,18 +340,11 @@ enum Packet { IndexerHeight(IndexerHeightMessage), } -impl TlsConnection { +impl OutgoingConnection { /// Both sides of the connection must complete handshake within this time, or else /// the connection is considered not successful. const HANDSHAKE_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(2); - /// If we don't receive a pong response within this time, consider the connection dead. - const PONG_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(20); - - /// Pings are sent at 1-second intervals from when the previous ping was sent, - /// waiting for pong response before sending the next. - const PING_INTERVAL: std::time::Duration = std::time::Duration::from_secs(1); - /// Makes a TLS/TCP connection to the given address, authenticating the /// other side as the given participant. async fn new( @@ -243,7 +352,8 @@ impl TlsConnection { target_address: &str, target_participant_id: ParticipantId, participant_identities: &ParticipantIdentities, - ) -> anyhow::Result { + keepalive_config: KeepaliveConfig, + ) -> anyhow::Result { let tcp_stream = TcpStream::connect(target_address) .await .context("TCP connect")?; @@ -270,7 +380,7 @@ impl TlsConnection { .context("p2p handshake")?; let (sender, mut receiver) = mpsc::unbounded_channel::(); - let (pong_tx, mut pong_rx) = tokio::sync::watch::channel(PongInfo { seq: 0 }); + let (pong_tx, pong_rx) = tokio::sync::watch::channel(PongInfo { seq: 0 }); let closed = CancellationToken::new(); let closed_clone = closed.clone(); @@ -306,79 +416,21 @@ impl TlsConnection { anyhow::Ok(()) }, ); + let sender_clone = sender.clone(); let closed_for_keepalive = closed.clone(); let keepalive_task = tracking::spawn( &format!("ping keepalive task for {}", target_participant_id), - async move { - let peer_id_str = target_participant_id.to_string(); - let mut seq: u64 = 0; - let mut interval = tokio::time::interval(Self::PING_INTERVAL); - interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay); - - loop { - interval.tick().await; - seq = match seq.checked_add(1) { - Some(new_seq) => new_seq, - None => { - tracing::warn!( - "TLS sequence number exceeded u64::MAX - closing connection" - ); - return; - } - }; - let ping_sent_at = Instant::now(); - if sender_clone.send(Packet::Ping(seq)).is_err() { - // The receiver side will be dropped when the sender task is - // dropped (i.e. connection is closed). - return; - } - let Ok(seq_i64) = i64::try_from(seq) else { - tracing::warn!(seq, "TLS sequence number exceeded i64::MAX - closing connection"); - return; - }; - crate::metrics::MPC_P2P_PING_SEQUENCE_SENT - .with_label_values(&[&peer_id_str]) - .set(seq_i64); - - // Wait for pong matching this ping (non-matching pongs are silently ignored) - match tokio::time::timeout( - Self::PONG_TIMEOUT, - pong_rx.wait_for(|info| info.seq == seq), - ) - .await - { - Ok(Ok(_)) => { - let rtt = ping_sent_at.elapsed(); - crate::metrics::MPC_P2P_PONG_SEQUENCE_RECEIVED - .with_label_values(&[&peer_id_str]) - .set(seq as i64); - crate::metrics::MPC_P2P_RTT_SECONDS - .with_label_values(&[&peer_id_str]) - .set(rtt.as_secs_f64()); - tracking::set_progress(&format!( - "Received pong {} from {target_participant_id}, RTT: {rtt:?}", - seq - )); - } - Ok(Err(_)) => { - // Channel closed, exit to trigger reconnection - return; - } - Err(_) => { - tracing::warn!( - peer = %target_participant_id, - timeout = ?Self::PONG_TIMEOUT, - "no pong received, closing connection" - ); - closed_for_keepalive.cancel(); - return; - } - } - } - }, + run_keepalive( + sender_clone, + pong_rx, + keepalive_config, + closed_for_keepalive, + target_participant_id, + ), ); - Ok(TlsConnection { + + Ok(OutgoingConnection { sender, _sender_task: sender_task, _keepalive_task: keepalive_task, @@ -403,8 +455,6 @@ impl TlsConnection { } impl PersistentConnection { - const CONNECTION_RETRY_DELAY: std::time::Duration = std::time::Duration::from_secs(1); - /// Sends a message over the connection. If the connection was reset, fail. fn send_mpc_message( &self, @@ -428,76 +478,100 @@ impl PersistentConnection { } } - pub fn new( - client_config: Arc, - my_id: ParticipantId, - target_address: String, + fn new( target_participant_id: ParticipantId, - participant_identities: Arc, - connectivity: Arc>, - ) -> anyhow::Result { - let connectivity_clone = Arc::clone(&connectivity); - let (pending_pong_tx, mut pending_pong_rx) = watch::channel(0u64); - let task = tracking::spawn( - &format!("Persistent connection to {}", target_participant_id), - async move { - loop { - match TlsConnection::new( - Arc::clone(&client_config), - &target_address, - target_participant_id, - &participant_identities, - ) - .await - { - Ok(conn) => { - let new_conn = Arc::new(conn); - tracing::info!( - from = %my_id, - to = %target_participant_id, - "outgoing connection established" - ); - - connectivity.set_outgoing_connection(&new_conn); - - // Send the latest pending pong if there is one - let pending_seq = *pending_pong_rx.borrow_and_update(); - if pending_seq > 0 - && new_conn.sender.send(Packet::Pong(pending_seq)).is_err() - { - tracing::warn!( - seq = pending_seq, - peer = %target_participant_id, - "failed to send pending pong, reconnecting" - ); - continue; - } - - new_conn.wait_for_close().await; - tracing::info!( - peer = %target_participant_id, - "connection closed, reconnecting" - ); - } - Err(e) => { - tracing::warn!( - peer = %target_participant_id, - error = format!("{e:#}"), - me = %my_id, - "could not connect, retrying" - ); - tokio::time::sleep(Self::CONNECTION_RETRY_DELAY).await; - } - } - } - }, - ); - Ok(PersistentConnection { + connectivity: Arc>, + pending_pong: watch::Sender, + task: AutoAbortTask<()>, + ) -> PersistentConnection { + PersistentConnection { target_participant_id, - connectivity: connectivity_clone, - pending_pong: pending_pong_tx, + connectivity, + pending_pong, _task: task, - }) + } + } +} + +/// Delay between reconnection attempts after a connection failure. +const CONNECTION_RETRY_DELAY: std::time::Duration = std::time::Duration::from_secs(1); + +/// Runs the reconnection loop for a persistent connection to a single peer. +/// +/// This function maintains an outgoing TLS connection to the specified peer, automatically +/// reconnecting when the connection drops. It runs an infinite loop that: +/// 1. Attempts to establish a new [`OutgoingConnection`] to the target peer +/// 2. On success: Registers the connection with `connectivity`, sends any buffered +/// pending pong, and blocks waiting for it to close +/// 3. On failure: Logs the error and sleeps for [`CONNECTION_RETRY_DELAY`] before retrying +/// 4. When a connection closes: Loops back to step 1 +/// +/// # Arguments +/// * `client_config` - TLS client configuration +/// * `my_id` - This node's participant ID (for logging) +/// * `target_address` - Address to connect to (host:port) +/// * `target_participant_id` - Expected peer identity +/// * `participant_identities` - Map for authenticating peer certificates +/// * `connectivity` - Shared state for tracking connection status +/// * `pending_pong_rx` - Receiver for buffered pong messages to send on reconnect +/// * `keepalive_config` - Configuration for ping/pong keepalive mechanism +async fn run_persistent_connection( + client_config: Arc, + my_id: ParticipantId, + target_address: String, + target_participant_id: ParticipantId, + participant_identities: Arc, + connectivity: Arc>, + mut pending_pong_rx: watch::Receiver, + keepalive_config: KeepaliveConfig, +) { + loop { + match OutgoingConnection::new( + Arc::clone(&client_config), + &target_address, + target_participant_id, + &participant_identities, + keepalive_config, + ) + .await + { + Ok(conn) => { + let new_conn = Arc::new(conn); + tracing::info!( + from = %my_id, + to = %target_participant_id, + "outgoing connection established" + ); + + connectivity.set_outgoing_connection(&new_conn); + + // Send the latest pending pong if there is one + let pending_seq = *pending_pong_rx.borrow_and_update(); + if pending_seq > 0 && new_conn.sender.send(Packet::Pong(pending_seq)).is_err() { + tracing::warn!( + seq = pending_seq, + peer = %target_participant_id, + "failed to send pending pong, reconnecting" + ); + continue; + } + + new_conn.wait_for_close().await; + tracing::info!( + peer = %target_participant_id, + "connection closed, reconnecting" + ); + } + Err(e) => { + tracing::warn!( + peer = %target_participant_id, + error = format!("{e:#}"), + me = %my_id, + "could not connect, retrying" + ); + tokio::time::sleep(CONNECTION_RETRY_DELAY).await; + } + } } } @@ -546,17 +620,33 @@ pub async fn new_tls_mesh_network( if participant.id == config.my_participant_id { continue; } - connections.insert( - participant.id, - Arc::new(PersistentConnection::new( + let connectivity = connectivities.get(participant.id)?; + let target_address = format!("{}:{}", participant.address, participant.port); + let target_participant_id = participant.id; + + // Create watch channel for pending pongs - sender goes to PersistentConnection, + // receiver goes to the reconnection task + let (pending_pong_tx, pending_pong_rx) = watch::channel(0u64); + + // Spawn the reconnection loop - this is the actual work that maintains the connection + let task = tracking::spawn( + &format!("Persistent connection to {}", target_participant_id), + run_persistent_connection( client_config.clone(), config.my_participant_id, - format!("{}:{}", participant.address, participant.port), - participant.id, + target_address, + target_participant_id, participant_identities.clone(), - connectivities.get(participant.id)?, - )?), + Arc::clone(&connectivity), + pending_pong_rx, + KeepaliveConfig::default(), + ), ); + + let persistent_conn = + PersistentConnection::new(target_participant_id, connectivity, pending_pong_tx, task); + + connections.insert(participant.id, Arc::new(persistent_conn)); } let tls_acceptor = TlsAcceptor::from(Arc::new(server_config)); @@ -594,7 +684,7 @@ pub async fn new_tls_mesh_network( let peer_id = verify_peer_identity(stream.get_ref().1, &participant_identities)?; tracking::set_progress(&format!("authenticated as {peer_id}")); - p2p_handshake(&mut stream, TlsConnection::HANDSHAKE_TIMEOUT) + p2p_handshake(&mut stream, OutgoingConnection::HANDSHAKE_TIMEOUT) .await .context("p2p handshake")?; tracing::info!(to = %my_id, from = %peer_id, "incoming connection established"); @@ -944,21 +1034,31 @@ pub mod testing { #[cfg(test)] mod tests { - use crate::cli::LogFormat; - use crate::config::MpcConfig; - use crate::network::{MeshNetworkTransportReceiver, MeshNetworkTransportSender}; - use crate::p2p::testing::{generate_test_p2p_configs, PortSeed}; - use crate::primitives::{ - ChannelId, MpcMessage, MpcStartMessage, MpcTaskId, ParticipantId, PeerMessage, UniqueId, + use crate::{ + cli::LogFormat, + config::MpcConfig, + network::{MeshNetworkTransportReceiver, MeshNetworkTransportSender}, + p2p::testing::{generate_test_p2p_configs, PortSeed}, + primitives::{ + ChannelId, MpcMessage, MpcStartMessage, MpcTaskId, ParticipantId, PeerMessage, UniqueId, + }, + providers::EcdsaTaskId, + tracing::init_logging, + tracking::{self, testing::start_root_task_with_periodic_dump}, + }; + use mpc_contract::primitives::{ + domain::DomainId, + key_state::{AttemptId, EpochId, KeyEventId}, }; - use crate::providers::EcdsaTaskId; - use crate::tracing::init_logging; - use crate::tracking::testing::start_root_task_with_periodic_dump; - use mpc_contract::primitives::domain::DomainId; - use mpc_contract::primitives::key_state::{AttemptId, EpochId, KeyEventId}; use rand::Rng; use std::time::Duration; - use tokio::time::timeout; + use tokio::{ + sync::{mpsc, watch}, + time::timeout, + }; + use tokio_util::sync::CancellationToken; + + use super::{run_keepalive, KeepaliveConfig, Packet, PongInfo}; #[tokio::test] async fn test_basic_tls_mesh_network() { @@ -1191,4 +1291,231 @@ mod tests { ids.sort(); ids } + + #[tokio::test(start_paused = true)] + async fn test_pong_timeout_triggers_reconnection() { + // given + let config = KeepaliveConfig { + ping_interval: Duration::from_secs(1), + pong_timeout: Duration::from_secs(5), + }; + let (ping_tx, mut ping_rx) = mpsc::unbounded_channel(); + let (_pong_tx, pong_rx) = watch::channel(PongInfo { seq: 0 }); + let closed = CancellationToken::new(); + let peer_id = ParticipantId::from_raw(1); + + let closed_clone = closed.clone(); + let keepalive_handle = tokio::spawn(async move { + run_keepalive(ping_tx, pong_rx, config, closed_clone, peer_id).await; + }); + + // when + // Advance time past the first ping interval + tokio::time::advance(Duration::from_secs(1)).await; + tokio::task::yield_now().await; + + // Verify ping was sent + let ping = ping_rx.recv().await; + assert!(matches!(ping, Some(Packet::Ping(1)))); + + // Don't respond with pong - advance time past the timeout + tokio::time::advance(Duration::from_secs(6)).await; + tokio::task::yield_now().await; + + // then + let _ = keepalive_handle.await; + assert!( + closed.is_cancelled(), + "connection should be cancelled on pong timeout" + ); + } + + #[tokio::test(start_paused = true)] + async fn test_pong_received_keeps_connection_alive() { + start_root_task_with_periodic_dump(async move { + // given + let config = KeepaliveConfig { + ping_interval: Duration::from_secs(1), + pong_timeout: Duration::from_secs(5), + }; + let (ping_tx, mut ping_rx) = mpsc::unbounded_channel(); + let (pong_tx, pong_rx) = watch::channel(PongInfo { seq: 0 }); + let closed = CancellationToken::new(); + let peer_id = ParticipantId::from_raw(1); + + let closed_clone = closed.clone(); + let keepalive_handle = tracking::spawn("test keepalive", async move { + run_keepalive(ping_tx, pong_rx, config, closed_clone, peer_id).await; + }); + + // when + // Process multiple ping/pong cycles, responding to each ping + for expected_seq in 1..=3u64 { + tokio::time::advance(Duration::from_secs(1)).await; + tokio::task::yield_now().await; + + let ping = ping_rx.recv().await; + assert!( + matches!(ping, Some(Packet::Ping(seq)) if seq == expected_seq), + "expected Ping({expected_seq}), got {:?}", + ping + ); + + pong_tx.send(PongInfo { seq: expected_seq }).unwrap(); + tokio::task::yield_now().await; + } + + // then + assert!( + !closed.is_cancelled(), + "connection should still be alive after successful pong responses" + ); + + // cleanup + drop(pong_tx); + let _ = keepalive_handle.await; + }) + .await; + } + + #[tokio::test(start_paused = true)] + async fn test_mismatched_pong_sequence_ignored() { + // given + let config = KeepaliveConfig { + ping_interval: Duration::from_secs(1), + pong_timeout: Duration::from_secs(5), + }; + let (ping_tx, mut ping_rx) = mpsc::unbounded_channel(); + let (pong_tx, pong_rx) = watch::channel(PongInfo { seq: 0 }); + let closed = CancellationToken::new(); + let peer_id = ParticipantId::from_raw(1); + + let closed_clone = closed.clone(); + let keepalive_handle = tokio::spawn(async move { + run_keepalive(ping_tx, pong_rx, config, closed_clone, peer_id).await; + }); + + // when + // Wait for first ping + tokio::time::advance(Duration::from_secs(1)).await; + tokio::task::yield_now().await; + + let ping = ping_rx.recv().await; + assert!(matches!(ping, Some(Packet::Ping(1)))); + + // Send pong with wrong sequence (0 instead of 1) + pong_tx.send(PongInfo { seq: 0 }).unwrap(); + tokio::task::yield_now().await; + + // Connection should still be waiting for correct pong + assert!( + !closed.is_cancelled(), + "connection should not be cancelled yet" + ); + + // Advance past timeout + tokio::time::advance(Duration::from_secs(6)).await; + tokio::task::yield_now().await; + + // then + let _ = keepalive_handle.await; + assert!( + closed.is_cancelled(), + "connection should be cancelled after timeout (mismatched pong ignored)" + ); + } + + #[tokio::test(start_paused = true)] + async fn test_ping_channel_closed_exits_gracefully() { + // given + let config = KeepaliveConfig { + ping_interval: Duration::from_secs(1), + pong_timeout: Duration::from_secs(5), + }; + let (ping_tx, ping_rx) = mpsc::unbounded_channel(); + let (_pong_tx, pong_rx) = watch::channel(PongInfo { seq: 0 }); + let closed = CancellationToken::new(); + let peer_id = ParticipantId::from_raw(1); + + // when + // Drop the receiver before starting - simulates connection being closed externally + drop(ping_rx); + + let closed_clone = closed.clone(); + let keepalive_handle = tokio::spawn(async move { + run_keepalive(ping_tx, pong_rx, config, closed_clone, peer_id).await; + }); + + // Advance past the first ping interval + tokio::time::advance(Duration::from_secs(1)).await; + tokio::task::yield_now().await; + + // then + // Task should exit without cancelling (graceful exit on channel close) + let result = tokio::time::timeout(Duration::from_millis(100), keepalive_handle).await; + assert!( + result.is_ok(), + "keepalive should exit when ping channel is closed" + ); + assert!( + !closed.is_cancelled(), + "connection should not be cancelled on channel close (different from timeout)" + ); + } + + #[tokio::test(start_paused = true)] + async fn test_late_pong_within_timeout_succeeds() { + start_root_task_with_periodic_dump(async move { + // given + let config = KeepaliveConfig { + ping_interval: Duration::from_secs(1), + pong_timeout: Duration::from_secs(5), + }; + let (ping_tx, mut ping_rx) = mpsc::unbounded_channel(); + let (pong_tx, pong_rx) = watch::channel(PongInfo { seq: 0 }); + let closed = CancellationToken::new(); + let peer_id = ParticipantId::from_raw(1); + + let closed_clone = closed.clone(); + let _keepalive_handle = tracking::spawn("test keepalive", async move { + run_keepalive(ping_tx, pong_rx, config, closed_clone, peer_id).await; + }); + + // when + // Wait for first ping + tokio::time::advance(Duration::from_secs(1)).await; + tokio::task::yield_now().await; + + let ping = ping_rx.recv().await; + assert!(matches!(ping, Some(Packet::Ping(1)))); + + // Wait almost until timeout (4.9 seconds of 5 second timeout) + tokio::time::advance(Duration::from_millis(4900)).await; + tokio::task::yield_now().await; + + // Send pong just before timeout + pong_tx.send(PongInfo { seq: 1 }).unwrap(); + tokio::task::yield_now().await; + + // then + assert!( + !closed.is_cancelled(), + "connection should remain alive when pong arrives before timeout" + ); + + // Verify second ping is sent after interval from first ping + // Note: ping_interval is measured from when ping was sent, not when pong was received. + // First ping was at t=1s, so second ping should be at t=2s. + // We're now at t=5.9s, so we just need to yield for the interval tick. + tokio::time::advance(Duration::from_millis(100)).await; + tokio::task::yield_now().await; + + let ping = ping_rx.recv().await; + assert!( + matches!(ping, Some(Packet::Ping(2))), + "second ping should be sent after late pong received" + ); + }) + .await; + } } From 453de4ad7b202a8324a367c4c31cfaca8dcbf80a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Thu, 15 Jan 2026 14:55:16 +0100 Subject: [PATCH 41/45] feat(p2p): add OutgoingConnectionConfig for managing outgoing connection settings --- crates/node/src/p2p.rs | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 8080ab692c..592f7b95d6 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -244,6 +244,19 @@ impl Default for KeepaliveConfig { } } +/// Configuration for creating outgoing connections to peers. +/// +/// Groups the configuration that is identical across all peer connections, used by +/// [`run_persistent_connection()`] to establish new [`OutgoingConnection`]s. +struct OutgoingConnectionConfig { + /// TLS client configuration for establishing secure connections. + client_config: Arc, + /// Map for authenticating peer certificates by public key. + participant_identities: Arc, + /// Ping/pong timing configuration for connection health monitoring. + keepalive_config: KeepaliveConfig, +} + /// Runs the keepalive loop that sends pings and monitors pong responses. /// /// This standalone function allows unit testing of timeout behavior without requiring @@ -507,31 +520,27 @@ const CONNECTION_RETRY_DELAY: std::time::Duration = std::time::Duration::from_se /// 4. When a connection closes: Loops back to step 1 /// /// # Arguments -/// * `client_config` - TLS client configuration +/// * `outgoing_config` - Configuration for creating outgoing connections /// * `my_id` - This node's participant ID (for logging) /// * `target_address` - Address to connect to (host:port) /// * `target_participant_id` - Expected peer identity -/// * `participant_identities` - Map for authenticating peer certificates /// * `connectivity` - Shared state for tracking connection status /// * `pending_pong_rx` - Receiver for buffered pong messages to send on reconnect -/// * `keepalive_config` - Configuration for ping/pong keepalive mechanism async fn run_persistent_connection( - client_config: Arc, + outgoing_config: Arc, my_id: ParticipantId, target_address: String, target_participant_id: ParticipantId, - participant_identities: Arc, connectivity: Arc>, mut pending_pong_rx: watch::Receiver, - keepalive_config: KeepaliveConfig, ) { loop { match OutgoingConnection::new( - Arc::clone(&client_config), + Arc::clone(&outgoing_config.client_config), &target_address, target_participant_id, - &participant_identities, - keepalive_config, + &outgoing_config.participant_identities, + outgoing_config.keepalive_config, ) .await { @@ -616,6 +625,11 @@ pub async fn new_tls_mesh_network( } let participant_identities = Arc::new(participant_identities); let client_config = Arc::new(client_config); + let outgoing_config = Arc::new(OutgoingConnectionConfig { + client_config, + participant_identities: participant_identities.clone(), + keepalive_config: KeepaliveConfig::default(), + }); for participant in &config.participants.participants { if participant.id == config.my_participant_id { continue; @@ -632,14 +646,12 @@ pub async fn new_tls_mesh_network( let task = tracking::spawn( &format!("Persistent connection to {}", target_participant_id), run_persistent_connection( - client_config.clone(), + outgoing_config.clone(), config.my_participant_id, target_address, target_participant_id, - participant_identities.clone(), Arc::clone(&connectivity), pending_pong_rx, - KeepaliveConfig::default(), ), ); From 948f6148099650130e98264a39c36f7401b30179 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Thu, 15 Jan 2026 17:24:22 +0100 Subject: [PATCH 42/45] Cleanup --- crates/node/src/p2p.rs | 90 ++++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 592f7b95d6..832dc5a467 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -23,6 +23,7 @@ use tracing::info; use crate::{ config::MpcConfig, + metrics, network::{ conn::{ AllNodeConnectivities, ConnectionVersion, NodeConnectivity, NodeConnectivityInterface, @@ -156,43 +157,43 @@ struct OutgoingConnection { /// Channel for queuing outbound packets ([`Packet::Ping`], [`Packet::MpcMessage`], /// [`Packet::IndexerHeight`]) to be sent. /// - /// The application sends messages by calling [`send_mpc_message()`](Self::send_mpc_message) or - /// [`send_indexer_height()`](Self::send_indexer_height), which queue packets into this channel. - /// The [`_sender_task`](Self::_sender_task) continuously reads from the receiver end of this - /// channel and writes packets to the TLS stream. This decouples message sending from I/O - /// operations, allowing the application to queue messages without blocking on network writes. + /// The application sends messages by calling [Self::send_mpc_message] or + /// [Self::send_indexer_height], which queue packets into this channel. [Self::_sender_task] + /// continuously reads from the receiver end of this channel and writes packets to the TLS + /// stream. This decouples message sending from I/O operations, allowing the application to + /// queue messages without blocking on network writes. sender: UnboundedSender, /// Background task that owns the TLS stream and handles write-only I/O operations. /// - /// This task continuously reads packets from the [`sender`](Self::sender) channel and writes - /// them to the TLS stream. The stream is used unidirectionally - only for sending. Connection - /// health monitoring is handled by the keepalive task which cancels the [`closed`](Self::closed) - /// token when a pong timeout occurs. When this task is aborted (via [`AutoAbortTask`] drop), - /// it closes the underlying TLS/TCP stream, which triggers [`PersistentConnection`] to reconnect. + /// This task continuously reads packets from [Self::sender] channel and writes them to the + /// TLS stream. The stream is used unidirectionally - only for sending. Connection health + /// monitoring is handled by the keepalive task which cancels [Self::closed] token when a + /// pong timeout occurs. When this task is aborted (via [`AutoAbortTask`] drop), it closes + /// the underlying TLS/TCP stream, which triggers [`PersistentConnection`] to reconnect. _sender_task: AutoAbortTask<()>, /// Background task that sends Ping heartbeats and monitors Pong responses. /// - /// This task sends a [`Ping`](Packet::Ping) with an incrementing sequence number and then - /// waits for either a [`Pong`](Packet::Pong) response (via a watch channel) or a timeout. - /// When a Pong is received, it validates the sequence number, calculates RTT, and waits until + /// This task sends a [Packet::Ping] with an incrementing sequence number and then waits for + /// either a [Packet::Pong] response (via a watch channel) or a timeout. When a Pong is + /// received, it validates the sequence number, calculates RTT, and waits until /// [`KeepaliveConfig::ping_interval`] (default 1 second) has elapsed since the ping was sent /// before sending the next one. If no Pong is received within /// [`KeepaliveConfig::pong_timeout`] (default 20 seconds), it closes the connection by - /// cancelling the [`closed`](Self::closed) token. This ensures pings are sent at regular - /// intervals while only sending when the previous ping received a response. + /// cancelling [Self::closed] token. This ensures pings are sent at regular intervals while + /// only sending when the previous ping received a response. _keepalive_task: AutoAbortTask<()>, /// Watch channel sender for delivering pong notifications to the keepalive task. /// - /// The incoming handler sends [`PongInfo`] when it receives a [`Pong`](Packet::Pong) packet. - /// The keepalive task monitors this channel to detect connection health and calculate RTT. - /// This enables clean async communication without mutexes. + /// The incoming handler sends [`PongInfo`] when it receives a [Packet::Pong] packet. The + /// keepalive task monitors this channel to detect connection health and calculate RTT. This + /// enables clean async communication without mutexes. pong_tx: tokio::sync::watch::Sender, /// Token that gets cancelled when the connection closes, allowing waiters to be notified. /// - /// Used by [`PersistentConnection`] via the [`wait_for_close()`](Self::wait_for_close) method - /// to block until the connection dies (either due to network failure, timeout, or intentional - /// shutdown). When [`_sender_task`](Self::_sender_task) exits, the [`DropToCancel`] guard - /// automatically cancels this token, unblocking any tasks waiting on it. + /// Used by [`PersistentConnection`] via [Self::wait_for_close] to block until the connection + /// dies (either due to network failure, timeout, or intentional shutdown). When + /// [Self::_sender_task] exits, the [`DropToCancel`] guard automatically cancels this token, + /// unblocking any tasks waiting on it. closed: CancellationToken, } @@ -305,7 +306,7 @@ async fn run_keepalive( ); return; }; - crate::metrics::MPC_P2P_PING_SEQUENCE_SENT + metrics::MPC_P2P_PING_SEQUENCE_SENT .with_label_values(&[&peer_id_str]) .set(seq_i64); @@ -318,10 +319,10 @@ async fn run_keepalive( { Ok(Ok(_)) => { let rtt = ping_sent_at.elapsed(); - crate::metrics::MPC_P2P_PONG_SEQUENCE_RECEIVED + metrics::MPC_P2P_PONG_SEQUENCE_RECEIVED .with_label_values(&[&peer_id_str]) .set(seq_i64); - crate::metrics::MPC_P2P_RTT_SECONDS + metrics::MPC_P2P_RTT_SECONDS .with_label_values(&[&peer_id_str]) .set(rtt.as_secs_f64()); tracking::set_progress(&format!( @@ -329,10 +330,13 @@ async fn run_keepalive( )); } Ok(Err(_)) => { - // Channel closed, exit to trigger reconnection + // Channel closed - `OutgoingConnection` is being dropped, and its + // `_sender_task`'s `DropToCancel` guard will cancel the `closed` token return; } Err(_) => { + // Timeout - we're the first to detect the dead connection, + // so we must signal closure to notify other tasks tracing::warn!( peer = %peer_id, timeout = ?config.pong_timeout, @@ -1304,6 +1308,12 @@ mod tests { ids } + /// Initial sequence number for `PongInfo` in tests. + const INITIAL_SEQ: u64 = 0; + + /// Sequence number of the first `Ping` sent by `run_keepalive`. + const FIRST_PING_SEQ: u64 = INITIAL_SEQ + 1; + #[tokio::test(start_paused = true)] async fn test_pong_timeout_triggers_reconnection() { // given @@ -1312,7 +1322,7 @@ mod tests { pong_timeout: Duration::from_secs(5), }; let (ping_tx, mut ping_rx) = mpsc::unbounded_channel(); - let (_pong_tx, pong_rx) = watch::channel(PongInfo { seq: 0 }); + let (_pong_tx, pong_rx) = watch::channel(PongInfo { seq: INITIAL_SEQ }); let closed = CancellationToken::new(); let peer_id = ParticipantId::from_raw(1); @@ -1328,7 +1338,7 @@ mod tests { // Verify ping was sent let ping = ping_rx.recv().await; - assert!(matches!(ping, Some(Packet::Ping(1)))); + assert!(matches!(ping, Some(Packet::Ping(FIRST_PING_SEQ)))); // Don't respond with pong - advance time past the timeout tokio::time::advance(Duration::from_secs(6)).await; @@ -1351,7 +1361,7 @@ mod tests { pong_timeout: Duration::from_secs(5), }; let (ping_tx, mut ping_rx) = mpsc::unbounded_channel(); - let (pong_tx, pong_rx) = watch::channel(PongInfo { seq: 0 }); + let (pong_tx, pong_rx) = watch::channel(PongInfo { seq: INITIAL_SEQ }); let closed = CancellationToken::new(); let peer_id = ParticipantId::from_raw(1); @@ -1398,7 +1408,7 @@ mod tests { pong_timeout: Duration::from_secs(5), }; let (ping_tx, mut ping_rx) = mpsc::unbounded_channel(); - let (pong_tx, pong_rx) = watch::channel(PongInfo { seq: 0 }); + let (pong_tx, pong_rx) = watch::channel(PongInfo { seq: INITIAL_SEQ }); let closed = CancellationToken::new(); let peer_id = ParticipantId::from_raw(1); @@ -1413,10 +1423,10 @@ mod tests { tokio::task::yield_now().await; let ping = ping_rx.recv().await; - assert!(matches!(ping, Some(Packet::Ping(1)))); + assert!(matches!(ping, Some(Packet::Ping(FIRST_PING_SEQ)))); - // Send pong with wrong sequence (0 instead of 1) - pong_tx.send(PongInfo { seq: 0 }).unwrap(); + // Send pong with wrong sequence (INITIAL_SEQ instead of FIRST_PING_SEQ) + pong_tx.send(PongInfo { seq: INITIAL_SEQ }).unwrap(); tokio::task::yield_now().await; // Connection should still be waiting for correct pong @@ -1445,7 +1455,7 @@ mod tests { pong_timeout: Duration::from_secs(5), }; let (ping_tx, ping_rx) = mpsc::unbounded_channel(); - let (_pong_tx, pong_rx) = watch::channel(PongInfo { seq: 0 }); + let (_pong_tx, pong_rx) = watch::channel(PongInfo { seq: INITIAL_SEQ }); let closed = CancellationToken::new(); let peer_id = ParticipantId::from_raw(1); @@ -1484,7 +1494,7 @@ mod tests { pong_timeout: Duration::from_secs(5), }; let (ping_tx, mut ping_rx) = mpsc::unbounded_channel(); - let (pong_tx, pong_rx) = watch::channel(PongInfo { seq: 0 }); + let (pong_tx, pong_rx) = watch::channel(PongInfo { seq: INITIAL_SEQ }); let closed = CancellationToken::new(); let peer_id = ParticipantId::from_raw(1); @@ -1499,14 +1509,18 @@ mod tests { tokio::task::yield_now().await; let ping = ping_rx.recv().await; - assert!(matches!(ping, Some(Packet::Ping(1)))); + assert!(matches!(ping, Some(Packet::Ping(FIRST_PING_SEQ)))); // Wait almost until timeout (4.9 seconds of 5 second timeout) tokio::time::advance(Duration::from_millis(4900)).await; tokio::task::yield_now().await; // Send pong just before timeout - pong_tx.send(PongInfo { seq: 1 }).unwrap(); + pong_tx + .send(PongInfo { + seq: FIRST_PING_SEQ, + }) + .unwrap(); tokio::task::yield_now().await; // then @@ -1524,7 +1538,7 @@ mod tests { let ping = ping_rx.recv().await; assert!( - matches!(ping, Some(Packet::Ping(2))), + matches!(ping, Some(Packet::Ping(seq)) if seq == FIRST_PING_SEQ + 1), "second ping should be sent after late pong received" ); }) From 75a0b8cf955f5ebe371b7aeeaff13aecd9078be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Thu, 15 Jan 2026 18:17:07 +0100 Subject: [PATCH 43/45] Tests cleanup --- crates/node/src/p2p.rs | 339 ++++++++++++++++++++++------------------- 1 file changed, 178 insertions(+), 161 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 832dc5a467..31b04413ec 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -1308,46 +1308,115 @@ mod tests { ids } - /// Initial sequence number for `PongInfo` in tests. - const INITIAL_SEQ: u64 = 0; + /// Test environment for `run_keepalive` tests, encapsulating common setup and helpers. + struct KeepaliveTestEnv { + /// Keepalive timing configuration used for the test. + config: KeepaliveConfig, + /// Test receives pings here to verify them. + ping_receiver: Option>, + /// Test sends pong responses here. + pong_sender: watch::Sender, + /// Token cancelled when the keepalive task detects a timeout. + closed: CancellationToken, + /// Channel ends consumed when spawning: (ping_tx, pong_rx). + task_channels: Option<(mpsc::UnboundedSender, watch::Receiver)>, + } + + impl KeepaliveTestEnv { + /// Initial sequence number for `PongInfo` in tests. + const INITIAL_SEQ: u64 = 0; + + /// Sequence number of the first `Ping` sent by `run_keepalive`. + const FIRST_PING_SEQ: u64 = Self::INITIAL_SEQ + 1; + + fn new() -> Self { + let config = KeepaliveConfig::default(); + let (ping_tx, ping_rx) = mpsc::unbounded_channel(); + let (pong_tx, pong_rx) = watch::channel(PongInfo { + seq: Self::INITIAL_SEQ, + }); + let closed = CancellationToken::new(); + + Self { + config, + ping_receiver: Some(ping_rx), + pong_sender: pong_tx, + closed, + task_channels: Some((ping_tx, pong_rx)), + } + } + + /// Drops the ping receiver to simulate a closed channel. + fn drop_ping_receiver(&mut self) { + self.ping_receiver.take(); + } - /// Sequence number of the first `Ping` sent by `run_keepalive`. - const FIRST_PING_SEQ: u64 = INITIAL_SEQ + 1; + /// Spawns the keepalive task. + fn spawn_keepalive(&mut self) -> tokio::task::JoinHandle<()> { + let (ping_tx, pong_rx) = self.task_channels.take().expect("already spawned"); + let closed = self.closed.clone(); + let config = self.config; + let peer_id = ParticipantId::from_raw(1); + tokio::spawn(async move { + run_keepalive(ping_tx, pong_rx, config, closed, peer_id).await; + }) + } + + /// Spawns the keepalive task with tracking support (for tests inside + /// `start_root_task_with_periodic_dump`). + fn spawn_keepalive_tracked(&mut self) -> tracking::AutoAbortTask<()> { + let (ping_tx, pong_rx) = self.task_channels.take().expect("already spawned"); + let closed = self.closed.clone(); + let config = self.config; + let peer_id = ParticipantId::from_raw(1); + tracking::spawn("test keepalive", async move { + run_keepalive(ping_tx, pong_rx, config, closed, peer_id).await; + }) + } + + /// Advances time and yields to let tasks run. + async fn advance(&self, duration: Duration) { + tokio::time::advance(duration).await; + tokio::task::yield_now().await; + } + + /// Waits for and asserts the next ping has the expected sequence number. + async fn expect_ping(&mut self, expected_seq: u64) { + let pings = self.ping_receiver.as_mut().expect("pings was dropped"); + let Packet::Ping(seq) = pings.recv().await.unwrap() else { + panic!("expected Ping") + }; + assert_eq!(seq, expected_seq); + } + + /// Sends a pong with the given sequence number. + fn send_pong(&self, seq: u64) { + self.pong_sender.send(PongInfo { seq }).unwrap(); + } + + /// Returns true if the keepalive task detected a pong timeout. + fn timed_out(&self) -> bool { + self.closed.is_cancelled() + } + } #[tokio::test(start_paused = true)] async fn test_pong_timeout_triggers_reconnection() { // given - let config = KeepaliveConfig { - ping_interval: Duration::from_secs(1), - pong_timeout: Duration::from_secs(5), - }; - let (ping_tx, mut ping_rx) = mpsc::unbounded_channel(); - let (_pong_tx, pong_rx) = watch::channel(PongInfo { seq: INITIAL_SEQ }); - let closed = CancellationToken::new(); - let peer_id = ParticipantId::from_raw(1); - - let closed_clone = closed.clone(); - let keepalive_handle = tokio::spawn(async move { - run_keepalive(ping_tx, pong_rx, config, closed_clone, peer_id).await; - }); - - // when - // Advance time past the first ping interval - tokio::time::advance(Duration::from_secs(1)).await; - tokio::task::yield_now().await; + let mut env = KeepaliveTestEnv::new(); + let handle = env.spawn_keepalive(); - // Verify ping was sent - let ping = ping_rx.recv().await; - assert!(matches!(ping, Some(Packet::Ping(FIRST_PING_SEQ)))); + env.advance(Duration::from_secs(1)).await; + env.expect_ping(KeepaliveTestEnv::FIRST_PING_SEQ).await; - // Don't respond with pong - advance time past the timeout - tokio::time::advance(Duration::from_secs(6)).await; - tokio::task::yield_now().await; + // when: don't respond with pong - advance past timeout + env.advance(env.config.pong_timeout + Duration::from_secs(1)) + .await; + let _ = handle.await; // then - let _ = keepalive_handle.await; assert!( - closed.is_cancelled(), + env.timed_out(), "connection should be cancelled on pong timeout" ); } @@ -1356,46 +1425,22 @@ mod tests { async fn test_pong_received_keeps_connection_alive() { start_root_task_with_periodic_dump(async move { // given - let config = KeepaliveConfig { - ping_interval: Duration::from_secs(1), - pong_timeout: Duration::from_secs(5), - }; - let (ping_tx, mut ping_rx) = mpsc::unbounded_channel(); - let (pong_tx, pong_rx) = watch::channel(PongInfo { seq: INITIAL_SEQ }); - let closed = CancellationToken::new(); - let peer_id = ParticipantId::from_raw(1); + let mut env = KeepaliveTestEnv::new(); + let _handle = env.spawn_keepalive_tracked(); - let closed_clone = closed.clone(); - let keepalive_handle = tracking::spawn("test keepalive", async move { - run_keepalive(ping_tx, pong_rx, config, closed_clone, peer_id).await; - }); - - // when - // Process multiple ping/pong cycles, responding to each ping + // when: process multiple ping/pong cycles for expected_seq in 1..=3u64 { - tokio::time::advance(Duration::from_secs(1)).await; - tokio::task::yield_now().await; - - let ping = ping_rx.recv().await; - assert!( - matches!(ping, Some(Packet::Ping(seq)) if seq == expected_seq), - "expected Ping({expected_seq}), got {:?}", - ping - ); - - pong_tx.send(PongInfo { seq: expected_seq }).unwrap(); + env.advance(Duration::from_secs(1)).await; + env.expect_ping(expected_seq).await; + env.send_pong(expected_seq); tokio::task::yield_now().await; } // then assert!( - !closed.is_cancelled(), - "connection should still be alive after successful pong responses" + !env.timed_out(), + "connection should still be alive after successful pongs" ); - - // cleanup - drop(pong_tx); - let _ = keepalive_handle.await; }) .await; } @@ -1403,85 +1448,59 @@ mod tests { #[tokio::test(start_paused = true)] async fn test_mismatched_pong_sequence_ignored() { // given - let config = KeepaliveConfig { - ping_interval: Duration::from_secs(1), - pong_timeout: Duration::from_secs(5), - }; - let (ping_tx, mut ping_rx) = mpsc::unbounded_channel(); - let (pong_tx, pong_rx) = watch::channel(PongInfo { seq: INITIAL_SEQ }); - let closed = CancellationToken::new(); - let peer_id = ParticipantId::from_raw(1); - - let closed_clone = closed.clone(); - let keepalive_handle = tokio::spawn(async move { - run_keepalive(ping_tx, pong_rx, config, closed_clone, peer_id).await; - }); + let mut env = KeepaliveTestEnv::new(); + let handle = env.spawn_keepalive(); - // when - // Wait for first ping - tokio::time::advance(Duration::from_secs(1)).await; - tokio::task::yield_now().await; - - let ping = ping_rx.recv().await; - assert!(matches!(ping, Some(Packet::Ping(FIRST_PING_SEQ)))); + env.advance(Duration::from_secs(1)).await; + env.expect_ping(KeepaliveTestEnv::FIRST_PING_SEQ).await; - // Send pong with wrong sequence (INITIAL_SEQ instead of FIRST_PING_SEQ) - pong_tx.send(PongInfo { seq: INITIAL_SEQ }).unwrap(); + // when: send pong with wrong sequence + env.send_pong(KeepaliveTestEnv::INITIAL_SEQ); tokio::task::yield_now().await; - // Connection should still be waiting for correct pong - assert!( - !closed.is_cancelled(), - "connection should not be cancelled yet" - ); + // then: connection should not be cancelled yet + assert!(!env.timed_out(), "connection should not be cancelled yet"); - // Advance past timeout - tokio::time::advance(Duration::from_secs(6)).await; - tokio::task::yield_now().await; + // when: advance past timeout + env.advance(env.config.pong_timeout + Duration::from_secs(1)) + .await; + let _ = handle.await; // then - let _ = keepalive_handle.await; assert!( - closed.is_cancelled(), - "connection should be cancelled after timeout (mismatched pong ignored)" + env.timed_out(), + "connection should be cancelled after timeout" ); } + /// Verifies that when the ping channel is closed externally (e.g., connection teardown), + /// the keepalive task exits gracefully without triggering a timeout cancellation. + /// + /// This distinguishes between two exit scenarios: + /// - **Channel closed**: Another component initiated shutdown (e.g., sender task dropped). + /// The keepalive should simply exit - cancelling `closed` would be redundant since + /// the connection is already being torn down elsewhere. + /// - **Pong timeout**: The keepalive detected a dead connection first. It must cancel + /// `closed` to notify other tasks (like `wait_for_close`) that the connection died. #[tokio::test(start_paused = true)] async fn test_ping_channel_closed_exits_gracefully() { // given - let config = KeepaliveConfig { - ping_interval: Duration::from_secs(1), - pong_timeout: Duration::from_secs(5), - }; - let (ping_tx, ping_rx) = mpsc::unbounded_channel(); - let (_pong_tx, pong_rx) = watch::channel(PongInfo { seq: INITIAL_SEQ }); - let closed = CancellationToken::new(); - let peer_id = ParticipantId::from_raw(1); + let mut env = KeepaliveTestEnv::new(); + env.drop_ping_receiver(); // when - // Drop the receiver before starting - simulates connection being closed externally - drop(ping_rx); - - let closed_clone = closed.clone(); - let keepalive_handle = tokio::spawn(async move { - run_keepalive(ping_tx, pong_rx, config, closed_clone, peer_id).await; - }); - - // Advance past the first ping interval - tokio::time::advance(Duration::from_secs(1)).await; - tokio::task::yield_now().await; + let handle = env.spawn_keepalive(); + env.advance(Duration::from_secs(1)).await; + let result = tokio::time::timeout(Duration::from_millis(100), handle).await; // then - // Task should exit without cancelling (graceful exit on channel close) - let result = tokio::time::timeout(Duration::from_millis(100), keepalive_handle).await; assert!( result.is_ok(), "keepalive should exit when ping channel is closed" ); assert!( - !closed.is_cancelled(), - "connection should not be cancelled on channel close (different from timeout)" + !env.timed_out(), + "connection should not be cancelled on channel close" ); } @@ -1489,59 +1508,57 @@ mod tests { async fn test_late_pong_within_timeout_succeeds() { start_root_task_with_periodic_dump(async move { // given - let config = KeepaliveConfig { - ping_interval: Duration::from_secs(1), - pong_timeout: Duration::from_secs(5), - }; - let (ping_tx, mut ping_rx) = mpsc::unbounded_channel(); - let (pong_tx, pong_rx) = watch::channel(PongInfo { seq: INITIAL_SEQ }); - let closed = CancellationToken::new(); - let peer_id = ParticipantId::from_raw(1); + let mut env = KeepaliveTestEnv::new(); + let _handle = env.spawn_keepalive_tracked(); - let closed_clone = closed.clone(); - let _keepalive_handle = tracking::spawn("test keepalive", async move { - run_keepalive(ping_tx, pong_rx, config, closed_clone, peer_id).await; - }); - - // when - // Wait for first ping - tokio::time::advance(Duration::from_secs(1)).await; - tokio::task::yield_now().await; - - let ping = ping_rx.recv().await; - assert!(matches!(ping, Some(Packet::Ping(FIRST_PING_SEQ)))); - - // Wait almost until timeout (4.9 seconds of 5 second timeout) - tokio::time::advance(Duration::from_millis(4900)).await; - tokio::task::yield_now().await; + env.advance(Duration::from_secs(1)).await; + env.expect_ping(KeepaliveTestEnv::FIRST_PING_SEQ).await; + env.advance(env.config.pong_timeout - Duration::from_nanos(1)) + .await; - // Send pong just before timeout - pong_tx - .send(PongInfo { - seq: FIRST_PING_SEQ, - }) - .unwrap(); + // when: send pong just before timeout + env.send_pong(KeepaliveTestEnv::FIRST_PING_SEQ); tokio::task::yield_now().await; // then assert!( - !closed.is_cancelled(), + !env.timed_out(), "connection should remain alive when pong arrives before timeout" ); - // Verify second ping is sent after interval from first ping - // Note: ping_interval is measured from when ping was sent, not when pong was received. - // First ping was at t=1s, so second ping should be at t=2s. - // We're now at t=5.9s, so we just need to yield for the interval tick. - tokio::time::advance(Duration::from_millis(100)).await; - tokio::task::yield_now().await; - - let ping = ping_rx.recv().await; - assert!( - matches!(ping, Some(Packet::Ping(seq)) if seq == FIRST_PING_SEQ + 1), - "second ping should be sent after late pong received" - ); + // then: second ping is sent + env.advance(Duration::from_millis(100)).await; + env.expect_ping(KeepaliveTestEnv::FIRST_PING_SEQ + 1).await; }) .await; } + + /// Verifies that a pong arriving after timeout is ignored and doesn't resurrect the connection. + #[tokio::test(start_paused = true)] + async fn test_pong_after_timeout_ignored() { + // given + let mut env = KeepaliveTestEnv::new(); + let handle = env.spawn_keepalive(); + + env.advance(Duration::from_secs(1)).await; + env.expect_ping(KeepaliveTestEnv::FIRST_PING_SEQ).await; + + // when: timeout expires first + env.advance(env.config.pong_timeout + Duration::from_secs(1)) + .await; + let _ = handle.await; + assert!(env.timed_out(), "should have timed out"); + + // when: late pong arrives after timeout (send fails because receiver is dropped) + let send_result = env.pong_sender.send(PongInfo { + seq: KeepaliveTestEnv::FIRST_PING_SEQ, + }); + assert!( + send_result.is_err(), + "pong send should fail after task exits" + ); + + // then: connection stays closed + assert!(env.timed_out(), "connection should remain closed"); + } } From 1202ebc863bee0442658f4294a1239b2001126ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Fri, 16 Jan 2026 12:03:34 +0100 Subject: [PATCH 44/45] refine test_pong_timeout_triggers_reconnection --- crates/node/src/p2p.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 02ee7a82c8..197b18ad7e 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -1514,9 +1514,16 @@ mod tests { env.advance(Duration::from_secs(1)).await; env.expect_ping(KeepaliveTestEnv::FIRST_PING_SEQ).await; - // when: don't respond with pong - advance past timeout - env.advance(env.config.pong_timeout + Duration::from_secs(1)) + // when: advance to just before timeout - should NOT trigger + env.advance(env.config.pong_timeout - Duration::from_nanos(1)) .await; + assert!( + !env.timed_out(), + "connection should not be cancelled before timeout" + ); + + // when: advance past timeout - should trigger + env.advance(Duration::from_nanos(2)).await; let _ = handle.await; // then From 7003987d796e660beea01636a15d2113bd9008cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20B=C4=99za?= Date: Fri, 16 Jan 2026 13:04:39 +0100 Subject: [PATCH 45/45] More comprehensive tests --- crates/node/src/p2p.rs | 128 ++++++++++++++++++++++++++--------------- 1 file changed, 83 insertions(+), 45 deletions(-) diff --git a/crates/node/src/p2p.rs b/crates/node/src/p2p.rs index 197b18ad7e..0286eacbde 100644 --- a/crates/node/src/p2p.rs +++ b/crates/node/src/p2p.rs @@ -1494,12 +1494,30 @@ mod tests { assert_eq!(seq, expected_seq); } + /// Asserts that no ping has been sent yet. + fn expect_no_ping(&mut self) { + let pings = self.ping_receiver.as_mut().expect("pings was dropped"); + match pings.try_recv() { + Err(mpsc::error::TryRecvError::Empty) => { + // Expected: no ping in the channel + } + Err(mpsc::error::TryRecvError::Disconnected) => { + panic!("ping channel was unexpectedly closed"); + } + Ok(packet) => { + panic!("expected no ping, but received: {:?}", packet); + } + } + } + /// Sends a pong with the given sequence number. fn send_pong(&self, seq: u64) { self.pong_sender.send(PongInfo { seq }).unwrap(); } - /// Returns true if the keepalive task detected a pong timeout. + /// Returns true if the keepalive task detected a pong timeout. In production, this + /// cancellation triggers reconnection via `run_persistent_connection`, which waits + /// on `wait_for_close()` and loops to establish a new connection. fn timed_out(&self) -> bool { self.closed.is_cancelled() } @@ -1511,47 +1529,68 @@ mod tests { let mut env = KeepaliveTestEnv::new(); let handle = env.spawn_keepalive(); - env.advance(Duration::from_secs(1)).await; env.expect_ping(KeepaliveTestEnv::FIRST_PING_SEQ).await; - // when: advance to just before timeout - should NOT trigger + // when: advance to just before timeout env.advance(env.config.pong_timeout - Duration::from_nanos(1)) .await; assert!( !env.timed_out(), "connection should not be cancelled before timeout" ); + // no second ping should be sent while waiting for pong + env.expect_no_ping(); - // when: advance past timeout - should trigger + // when: advance past timeout env.advance(Duration::from_nanos(2)).await; - let _ = handle.await; - - // then assert!( env.timed_out(), "connection should be cancelled on pong timeout" ); + + let result = handle.await; + assert!(result.is_ok()); } #[tokio::test(start_paused = true)] async fn test_pong_received_keeps_connection_alive() { start_root_task_with_periodic_dump(async move { - // given + // given: a keepalive task monitoring connection health let mut env = KeepaliveTestEnv::new(); let _handle = env.spawn_keepalive_tracked(); - // when: process multiple ping/pong cycles + // when: we respond to each ping with a matching pong for expected_seq in 1..=3u64 { - env.advance(Duration::from_secs(1)).await; env.expect_ping(expected_seq).await; + assert!( + !env.timed_out(), + "connection should be alive while waiting for pong" + ); env.send_pong(expected_seq); - tokio::task::yield_now().await; + assert!( + !env.timed_out(), + "connection should remain alive after pong {expected_seq}" + ); } - // then + // then: connection survives even near timeout boundary + env.expect_ping(4).await; + env.advance(env.config.pong_timeout - Duration::from_nanos(1)) + .await; + assert!(!env.timed_out(), "should survive until just before timeout"); + env.send_pong(4); assert!( !env.timed_out(), - "connection should still be alive after successful pongs" + "pong at last moment should keep connection alive" + ); + + // then: connection times out when pongs stop + env.expect_ping(5).await; + env.advance(env.config.pong_timeout + Duration::from_nanos(1)) + .await; + assert!( + env.timed_out(), + "connection should timeout when pongs stop arriving" ); }) .await; @@ -1563,56 +1602,57 @@ mod tests { let mut env = KeepaliveTestEnv::new(); let handle = env.spawn_keepalive(); - env.advance(Duration::from_secs(1)).await; env.expect_ping(KeepaliveTestEnv::FIRST_PING_SEQ).await; // when: send pong with wrong sequence env.send_pong(KeepaliveTestEnv::INITIAL_SEQ); - tokio::task::yield_now().await; - // then: connection should not be cancelled yet + // then: connection should not be cancelled yet, and no new ping sent assert!(!env.timed_out(), "connection should not be cancelled yet"); + env.expect_no_ping(); - // when: advance past timeout - env.advance(env.config.pong_timeout + Duration::from_secs(1)) + // when: advance to just before timeout + env.advance(env.config.pong_timeout - Duration::from_nanos(1)) .await; - let _ = handle.await; - // then + // then: connection should not be cancelled yet + assert!(!env.timed_out(), "connection should not be cancelled yet"); + env.expect_no_ping(); + + // when: advance to the timeout + env.advance(env.config.pong_timeout).await; + + // then: connection should be cancelled assert!( env.timed_out(), "connection should be cancelled after timeout" ); + + let result = handle.await; + assert!(result.is_ok()); } - /// Verifies that when the ping channel is closed externally (e.g., connection teardown), - /// the keepalive task exits gracefully without triggering a timeout cancellation. + /// Verifies that when `ping_sender.send()` fails (receiver dropped), the keepalive task + /// exits gracefully without cancelling the `closed` token. /// - /// This distinguishes between two exit scenarios: - /// - **Channel closed**: Another component initiated shutdown (e.g., sender task dropped). - /// The keepalive should simply exit - cancelling `closed` would be redundant since - /// the connection is already being torn down elsewhere. - /// - **Pong timeout**: The keepalive detected a dead connection first. It must cancel - /// `closed` to notify other tasks (like `wait_for_close`) that the connection died. + /// This tests the error path in `run_keepalive` where sending a ping fails because the + /// sender task has already dropped its end of the channel (e.g., due to TLS stream error). + /// In this case, the keepalive should simply return - the `closed` token will be cancelled + /// by the sender task's `DropToCancel` guard, so cancelling it here would be redundant. #[tokio::test(start_paused = true)] async fn test_ping_channel_closed_exits_gracefully() { - // given + // given: ping receiver is dropped before spawning keepalive let mut env = KeepaliveTestEnv::new(); env.drop_ping_receiver(); - // when + // when: keepalive task tries to send ping, it fails immediately let handle = env.spawn_keepalive(); - env.advance(Duration::from_secs(1)).await; - let result = tokio::time::timeout(Duration::from_millis(100), handle).await; + handle.await.expect("task should exit cleanly"); - // then - assert!( - result.is_ok(), - "keepalive should exit when ping channel is closed" - ); + // then: closed token should NOT be cancelled assert!( !env.timed_out(), - "connection should not be cancelled on channel close" + "closed token should not be cancelled when ping channel is closed" ); } @@ -1623,14 +1663,12 @@ mod tests { let mut env = KeepaliveTestEnv::new(); let _handle = env.spawn_keepalive_tracked(); - env.advance(Duration::from_secs(1)).await; env.expect_ping(KeepaliveTestEnv::FIRST_PING_SEQ).await; env.advance(env.config.pong_timeout - Duration::from_nanos(1)) .await; // when: send pong just before timeout env.send_pong(KeepaliveTestEnv::FIRST_PING_SEQ); - tokio::task::yield_now().await; // then assert!( @@ -1638,8 +1676,10 @@ mod tests { "connection should remain alive when pong arrives before timeout" ); - // then: second ping is sent - env.advance(Duration::from_millis(100)).await; + env.expect_no_ping(); + + // second ping is sent + env.advance(Duration::from_nanos(1)).await; env.expect_ping(KeepaliveTestEnv::FIRST_PING_SEQ + 1).await; }) .await; @@ -1652,12 +1692,10 @@ mod tests { let mut env = KeepaliveTestEnv::new(); let handle = env.spawn_keepalive(); - env.advance(Duration::from_secs(1)).await; env.expect_ping(KeepaliveTestEnv::FIRST_PING_SEQ).await; // when: timeout expires first - env.advance(env.config.pong_timeout + Duration::from_secs(1)) - .await; + env.advance(env.config.pong_timeout).await; let _ = handle.await; assert!(env.timed_out(), "should have timed out");