diff --git a/mpc/src/ffi/c_bindings/network/mod.rs b/mpc/src/ffi/c_bindings/network/mod.rs index 1a17aea..28a3a7b 100644 --- a/mpc/src/ffi/c_bindings/network/mod.rs +++ b/mpc/src/ffi/c_bindings/network/mod.rs @@ -1,5 +1,6 @@ pub mod fake_network; pub mod quic; +use std::ffi::c_void; use std::slice; use std::sync::Arc; @@ -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` from a `NetworkOpaque` +/// pointer and returns it as a boxed Arc suitable for passing to libraries like StoffelVM +/// that expect a raw `Arc` pointer. +/// +/// # Arguments +/// * `network` - A pointer to NetworkOpaque (must wrap GenericNetwork::QuicNetworkManager) +/// +/// # Returns +/// * A pointer to a boxed `Arc`, 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); + } + } +} diff --git a/mpc/src/ffi/c_bindings/network/quic.rs b/mpc/src/ffi/c_bindings/network/quic.rs index a716dcf..3080837 100644 --- a/mpc/src/ffi/c_bindings/network/quic.rs +++ b/mpc/src/ffi/c_bindings/network/quic.rs @@ -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. diff --git a/mpc/src/ffi/honey_badger_bindings.h b/mpc/src/ffi/honey_badger_bindings.h index f6fd45e..ac9d6c9 100644 --- a/mpc/src/ffi/honey_badger_bindings.h +++ b/mpc/src/ffi/honey_badger_bindings.h @@ -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 *