Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions mpc/src/ffi/c_bindings/network/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod fake_network;
pub mod quic;
use std::ffi::c_void;
use std::slice;
use std::sync::Arc;

Expand Down Expand Up @@ -94,3 +95,54 @@ pub extern "C" fn network_send(
Err(e) => return e.into(),
}
}

/// Extract raw QuicNetworkManager pointer for use with external libraries.
///
/// This function extracts the inner `Arc<QuicNetworkManager>` from a `NetworkOpaque`
/// pointer and returns it as a boxed Arc suitable for passing to libraries like StoffelVM
/// that expect a raw `Arc<QuicNetworkManager>` pointer.
///
/// # Arguments
/// * `network` - A pointer to NetworkOpaque (must wrap GenericNetwork::QuicNetworkManager)
///
/// # Returns
/// * A pointer to a boxed `Arc<QuicNetworkManager>`, or null if:
/// - The input pointer is null
/// - The network is not a QuicNetworkManager variant
///
/// # Safety
/// * The caller must ensure `network` is a valid NetworkOpaque pointer
/// * The returned pointer must be freed with `free_raw_quic_network()` when no longer needed
/// * The original NetworkOpaque remains valid and must be freed separately
#[no_mangle]
pub extern "C" fn extract_quic_network(network: *mut NetworkOpaque) -> *mut c_void {
if network.is_null() {
return std::ptr::null_mut();
}
let net = unsafe { &*(network as *mut GenericNetwork) };
match net {
GenericNetwork::QuicNetworkManager(arc) => {
// Box the Arc for stable FFI pointer (matches StoffelVM expectation)
Box::into_raw(Box::new(Arc::clone(arc))) as *mut c_void
}
_ => std::ptr::null_mut(),
}
}

/// Free a raw QuicNetworkManager pointer obtained from `extract_quic_network()`.
///
/// # Arguments
/// * `ptr` - A pointer obtained from `extract_quic_network()`
///
/// # Safety
/// * The pointer must have been obtained from `extract_quic_network()`
/// * The pointer must not have been freed already
/// * The pointer must not be used after this call
#[no_mangle]
pub extern "C" fn free_raw_quic_network(ptr: *mut c_void) {
if !ptr.is_null() {
unsafe {
let _ = Box::from_raw(ptr as *mut Arc<QuicNetworkManager>);
}
}
}
27 changes: 27 additions & 0 deletions mpc/src/ffi/c_bindings/network/quic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,33 @@ pub extern "C" fn new_quic_network(
Box::into_raw(Box::new(quic_network)) as *mut QuicNetworkOpaque
}

/// Creates a new QUIC network instance with a specific party ID
///
/// This is essential for MPC operations where parties need consistent IDs.
/// The party_id will be used in handshakes and for connection lookups.
///
/// # Arguments
/// * `party_id` - The party ID for this network node (e.g., 0, 1, 2, etc.)
/// * `returned_connections` - Output parameter for peer connections map
#[no_mangle]
pub extern "C" fn new_quic_network_with_party_id(
party_id: usize,
returned_connections: *mut *mut QuicPeerConnectionsOpaque,
) -> *mut QuicNetworkOpaque {
let quic_network = QuicNetwork {
quic_manager: QuicNetworkManager::with_node_id(party_id),
};
let peer_connections = QuicPeerConnections {
connections: HashMap::new(),
};
unsafe {
*returned_connections =
Box::into_raw(Box::new(peer_connections)) as *mut QuicPeerConnectionsOpaque;
}

Box::into_raw(Box::new(quic_network)) as *mut QuicNetworkOpaque
}

/// Establishes a connection to a new peer
///
/// This method initiates an outgoing connection to a peer at the specified address.
Expand Down
13 changes: 13 additions & 0 deletions mpc/src/ffi/honey_badger_bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,19 @@ void init_tls(void);
*/
struct QuicNetworkOpaque *new_quic_network(struct QuicPeerConnectionsOpaque **returned_connections);

/**
* Creates a new QUIC network instance with a specific party ID
*
* This is essential for MPC operations where parties need consistent IDs.
* The party_id will be used in handshakes and for connection lookups.
*
* # Arguments
* * `party_id` - The party ID for this network node (e.g., 0, 1, 2, etc.)
* * `returned_connections` - Output parameter for peer connections map
*/
struct QuicNetworkOpaque *new_quic_network_with_party_id(uintptr_t party_id,
struct QuicPeerConnectionsOpaque **returned_connections);

/**
* Establishes a connection to a new peer
*
Expand Down