Merge 8abc430b01d03d90ca8ac20cdb6e761da9e51a1e into 95040402feae4ebc3038d66e1168390669bd6942

This commit is contained in:
Darshan 2026-02-27 19:21:52 +00:00 committed by GitHub
commit cb712f0950
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 254 additions and 3372 deletions

2
.gitmodules vendored
View File

@ -1,3 +1,3 @@
[submodule "waku-sys/vendor"]
path = waku-sys/vendor
url = https://github.com/logos-messaging/logos-messaging-nim
url = https://github.com/logos-messaging/logos-delivery

1726
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
# Waku Rust bindings
# logos-delivery Rust Bindings
[![Crates.io][crates-badge]][crates-url]
[![Documentation][docs-badge]][docs-url]
@ -9,18 +9,98 @@
[crates-url]: https://crates.io/crates/waku-bindings
[docs-badge]: https://docs.rs/waku-bindings/badge.svg
[docs-url]: https://docs.rs/waku-bindings
[actions-badge]: https://github.com/logos-messaging/logos-messaging-rust-bindings/workflows/CI/badge.svg
[actions-url]: https://github.com/logos-messaging/logos-messaging-rust-bindings/actions/workflows/main.yml?query=workflow%3ACI+branch%3Amaster
[codecov-badge]: https://codecov.io/github/logos-messaging/logos-messaging-rust-bindings/branch/main/graph/badge.svg?token=H4CQWRUCUS
[codecov-url]: https://codecov.io/github/logos-messaging/logos-messaging-rust-bindings
[actions-badge]: https://github.com/logos-messaging/logos-delivery-rust-bindings/workflows/CI/badge.svg
[actions-url]: https://github.com/logos-messaging/logos-delivery-rust-bindings/actions/workflows/main.yml?query=workflow%3ACI+branch%3Amaster
[codecov-badge]: https://codecov.io/github/logos-messaging/logos-delivery-rust-bindings/branch/main/graph/badge.svg?token=H4CQWRUCUS
[codecov-url]: https://codecov.io/github/logos-messaging/logos-delivery-rust-bindings
Rust layer on top of [`logos-messaging-nim`](https://github.com/logos-messaging/logos-messaging-nim) [C FFI bindings](https://github.com/logos-messaging/logos-messaging-nim/blob/master/library/libwaku.h).
Rust bindings for [logos-delivery](https://github.com/logos-messaging/logos-delivery) (Waku) v0.38.0-beta,
built on top of the [C FFI](https://github.com/logos-messaging/logos-delivery/blob/master/library/libwaku.h).
## Prerequisites
- **Rust** (stable) — [rustup.rs](https://rustup.rs)
- **Nim 2.x** — required to compile the native `libwaku` library
- **Make**
- **GCC or Clang**
## Setup
Clone the repository:
```bash
git clone https://github.com/logos-messaging/logos-delivery-rust-bindings.git
cd logos-delivery-rust-bindings
```
The first `cargo build` / `cargo run` automatically:
1. Initializes and updates git submodules
2. Compiles the native `libwaku` static library via `make libwaku STATIC=1`
3. Generates Rust FFI bindings via `bindgen`
## Running the Examples
### basic
Two Waku nodes in the same process. Node 1 publishes a message; node 2 receives it via relay subscription.
```bash
cd examples/basic
cargo run
```
### toy-chat
Multi-participant chat room over Waku relay. Pass your nickname as argument.
```bash
cd examples/toy-chat
cargo run "Alice"
```
Start another instance in a separate terminal (or on another machine) to chat:
```bash
cargo run "Bob"
```
### tic-tac-toe-gui
Multiplayer tic-tac-toe with a native GUI (eframe). Start two instances — locally or on separate machines.
```bash
cd examples/tic-tac-toe-gui
cargo run
```
## Running the Tests
Tests start real Waku nodes and bind to local TCP ports, so they **must run serially**:
```bash
# from repo root
cargo test -p waku-bindings -- --test-threads=1
# or from waku-bindings/
cd waku-bindings
cargo test
```
To see log output:
```bash
cargo test -- --nocapture
```
## Crates
| Crate | Description |
|-------|-------------|
| [`waku-bindings`](waku-bindings/) | High-level Rust API |
| [`waku-sys`](waku-sys/) | Low-level bindgen FFI bindings |
## About Waku
[Waku](https://waku.org/) is a family of robust and censorship-resistant communication protocols enabling privacy-focused messaging for Web3 applications.
Private. Secure. Runs anywhere.
[Waku](https://waku.org/) is a family of robust, censorship-resistant communication protocols for Web3. Private. Secure. Runs anywhere.
Read the [Waku docs](https://docs.waku.org/)

1603
examples/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -46,6 +46,9 @@ async fn main() -> Result<(), Error> {
WakuEvent::ConnectionChange(_evt) => {
// dbg!("Conn change evt", evt);
}
WakuEvent::NodeHealthChange(_evt) => {
// dbg!("Node health change evt", evt);
}
WakuEvent::Unrecognized(err) => panic!("Unrecognized waku event: {:?}", err),
_ => panic!("event case not expected"),
};
@ -75,6 +78,9 @@ async fn main() -> Result<(), Error> {
WakuEvent::ConnectionChange(_evt) => {
// dbg!("Conn change evt", evt);
}
WakuEvent::NodeHealthChange(_evt) => {
// dbg!("Node health change evt", evt);
}
WakuEvent::Unrecognized(err) => panic!("Unrecognized waku event: {:?}", err),
_ => panic!("event case not expected"),
};

View File

@ -55,6 +55,7 @@ impl App<Initialized> {
tcp_port: Some(60010),
cluster_id: Some(16),
shards: vec![1, 32, 64, 128, 256],
num_shards_in_network: Some(0), // static sharding for explicit RS shard indices
// node_key: Some(SecretKey::from_str("2fc0515879e52b7b73297cfd6ab3abf7c344ef84b7a90ff6f4cc19e05a198027").unwrap()),
max_message_size: Some("1024KiB".to_string()),
relay_topics: vec![String::from(&pubsub_topic)],
@ -117,6 +118,9 @@ impl App<Initialized> {
WakuEvent::ConnectionChange(_evt) => {
// dbg!("Conn change evt", evt);
},
WakuEvent::NodeHealthChange(_evt) => {
// dbg!("Node health change evt", evt);
},
WakuEvent::Unrecognized(err) => eprintln!("Unrecognized waku event: {:?}", err),
_ => eprintln!("event case not expected"),
};

View File

@ -9,7 +9,7 @@ authors = [
]
description = "Waku networking library"
license = "MIT OR Apache-2.0"
repository = "https://github.com/logos-messaging/logos-messaging-rust-bindings"
repository = "https://github.com/logos-messaging/logos-delivery-rust-bindings"
keywords = ["waku", "peer-to-peer", "libp2p", "networking"]
categories = ["network-programming"]
@ -31,7 +31,6 @@ url = "2.3"
waku-sys = { version = "1.0.0", path = "../waku-sys" }
libc = "0.2"
serde-aux = "4.3.1"
rln = "0.3.4"
tokio = { version = "1", features = ["full"] }
regex = "1"
chrono = "0.4"

View File

@ -1,11 +1,12 @@
# Waku Rust bindings
[<img alt="github" src="https://img.shields.io/badge/github-Github-red?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/logos-messaging/logos-messaging-rust-bindings)
[<img alt="github" src="https://img.shields.io/badge/github-Github-red?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/logos-messaging/logos-delivery-rust-bindings)
[<img alt="crates.io" src="https://img.shields.io/crates/v/waku-bindings.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/waku-bindings)
[<img alt="docs.rs" src="https://img.shields.io/badge/doc/waku-bindings-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/waku-bindings)
[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/logos-messaging/logos-messaging-rust-bindings/main.yml?branch=master" height="20">](https://github.com/logos-messaging/logos-messaging-rust-bindings/actions/workflows/main.yml?query=branch%3Amaster)
[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/logos-messaging/logos-delivery-rust-bindings/main.yml?branch=master" height="20">](https://github.com/logos-messaging/logos-delivery-rust-bindings/actions/workflows/main.yml?query=branch%3Amaster)
Rust api on top of [`waku-sys`](https://crates.io/crates/waku-sys) bindgen bindings to [c ffi bindings](https://github.com/status-im/go-waku/blob/v0.2.2/library/README.md).
High-level Rust API on top of [`waku-sys`](https://crates.io/crates/waku-sys) bindgen bindings to the
[logos-delivery C FFI](https://github.com/logos-messaging/logos-delivery/blob/master/library/libwaku.h).
## Usage
@ -14,28 +15,86 @@ Add this to your `Cargo.toml`:
```toml
[dependencies]
waku-bindings = "0.1.0"
waku-bindings = "1.0.0"
```
## Testing
### Prerequisites
- **Rust** (stable) — [rustup.rs](https://rustup.rs)
- **Nim 2.x** — required to compile the native `libwaku` library
- **Make**
- **GCC or Clang**
### Setup
Clone the repository:
```bash
git clone https://github.com/logos-messaging/logos-delivery-rust-bindings.git
cd logos-delivery-rust-bindings
```
The first `cargo build` / `cargo test` automatically:
1. Initializes and updates git submodules
2. Builds the native `libwaku` static library via `make libwaku STATIC=1`
3. Generates Rust FFI bindings via `bindgen`
### Running the tests
From the repo root or the `waku-bindings/` directory:
```bash
cargo test
```
> Tests must run **serially** — they spin up real Waku nodes that bind to local TCP ports. Running them in
> parallel causes port conflicts. The `serial_test` crate enforces this automatically.
To run a specific test:
```bash
cargo test <test_name>
```
For example:
```bash
cargo test default_echo
cargo test node_restart
```
To see log output:
```bash
cargo test -- --nocapture
```
### What the tests cover
| Test | Description |
|------|-------------|
| `default_echo` | Creates two nodes, subscribes both to a relay topic, publishes a message from node 1, and verifies node 2 receives it |
| `node_restart` | Creates a node, starts and stops it three times in a row to verify lifecycle correctness |
## About [Waku](https://waku.org/)
Waku is the communication layer for Web3. Decentralized communication that scales.
Private. Secure. Runs anywhere.
### What is Waku?
Waku is a suite of privacy-preserving, peer-to-peer messaging protocols.
Waku removes centralized third parties from messaging, enabling private, secure, censorship-free communication with no single point of failure.
Waku provides privacy-preserving capabilities, such as sender anonymity,metadata protection and unlinkability to personally identifiable information.
Waku provides privacy-preserving capabilities, such as sender anonymity, metadata protection and unlinkability to personally identifiable information.
Waku is designed for generalized messaging, enabling human-to-human, machine-to-machine or hybrid communication.
Waku runs everywhere: desktop, server, including resource-restricted devices, such as mobile devices and browsers.
How does it work?
The first version of Waku had its origins in the Whisper protocol, with optimizations for scalability and usability. Waku v2 is a complete rewrite. Its relay protocol implements pub/sub over libp2p, and also introduces additional capabilities:
@ -45,6 +104,4 @@ The first version of Waku had its origins in the Whisper protocol, with optimiza
This makes it ideal for running a p2p protocol on mobile, or in other similarly resource-restricted environments.
Read the [Waku docs](https://docs.wakuconnect.dev/)
Read the [Waku docs](https://docs.waku.org/)

View File

@ -8,12 +8,6 @@ pub mod node;
// Re-export the LibwakuResponse type to make it accessible outside this module
pub use general::libwaku_response::LibwakuResponse;
// Required so functions inside libwaku can call RLN functions even if we
// use it within the bindings functions
#[allow(clippy::single_component_path_imports)]
#[allow(unused)]
use rln;
pub use node::{
waku_create_content_topic, waku_new, Initialized, Key, Multiaddr, PublicKey, RLNConfig,
Running, SecretKey, WakuEvent, WakuMessageEvent, WakuNodeConfig, WakuNodeHandle,

View File

@ -1,7 +1,7 @@
use crate::general::libwaku_response::LibwakuResponse;
use std::{slice, str};
use waku_sys::WakuCallBack;
use waku_sys::FFICallBack;
unsafe extern "C" fn trampoline<F>(
ret_code: ::std::os::raw::c_int,
@ -26,7 +26,7 @@ unsafe extern "C" fn trampoline<F>(
closure(result);
}
pub fn get_trampoline<F>(_closure: &F) -> WakuCallBack
pub fn get_trampoline<F>(_closure: &F) -> FFICallBack
where
F: FnMut(LibwakuResponse),
{
@ -57,10 +57,10 @@ macro_rules! handle_ffi_call {
let code = unsafe {
let cb = get_trampoline(&closure);
$waku_fn(
$ctx, // Pass the context
$($($arg),*,)? // Expand the variadic arguments if provided
cb, // Pass the callback trampoline
&mut closure as *mut _ as *mut c_void
$ctx, // Pass the context
cb, // Pass the callback trampoline
&mut closure as *mut _ as *mut c_void // Pass the user data
$(, $($arg),*)? // Expand the variadic arguments if provided
)
};

View File

@ -28,8 +28,14 @@ pub struct WakuNodeConfig {
#[default(Some(true))]
pub relay: Option<bool>,
pub relay_topics: Vec<String>,
#[default(vec![1])]
#[default(vec![0])]
pub shards: Vec<usize>,
/// Number of shards in the cluster for auto-sharding. Set to `0` to use
/// static sharding (required when subscribing to explicit RS shard indices
/// such as those used by the Status.im production network).
/// Defaults to `None` (Nim will use its own default of 1).
#[serde(skip_serializing_if = "Option::is_none")]
pub num_shards_in_network: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_message_size: Option<String>,

View File

@ -49,7 +49,7 @@ impl WakuNodeContext {
*boxed_closure = Box::new(closure);
unsafe {
let cb = get_trampoline(&(*boxed_closure));
waku_sys::waku_set_event_callback(
waku_sys::set_event_callback(
self.obj_ptr,
cb,
&mut (*boxed_closure) as *mut _ as *mut c_void,

View File

@ -27,6 +27,9 @@ pub enum WakuEvent {
#[serde(rename = "connection_change")]
ConnectionChange(ConnectionChangeEvent),
#[serde(rename = "node_health_change")]
NodeHealthChange(NodeHealthChangeEvent),
Unrecognized(serde_json::Value),
}
@ -62,6 +65,14 @@ pub struct ConnectionChangeEvent {
pub peer_event: String,
}
/// Type of `event` field for a `node health change` event
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct NodeHealthChangeEvent {
/// The node connection status: Disconnected, PartiallyConnected, or Connected
pub status: String,
}
#[cfg(test)]
mod tests {
use crate::WakuEvent;

View File

@ -58,6 +58,9 @@ async fn test_echo_messages(
WakuEvent::ConnectionChange(_evt) => {
// dbg!("Conn change evt", evt);
}
WakuEvent::NodeHealthChange(_evt) => {
// dbg!("Node health change evt", evt);
}
WakuEvent::Unrecognized(err) => panic!("Unrecognized waku event: {:?}", err),
_ => panic!("event case not expected"),
};

View File

@ -9,7 +9,7 @@ authors = [
]
description = "Waku networking library generated bindings"
license = "MIT OR Apache-2.0"
repository = "https://github.com/logos-messaging/logos-messaging-rust-bindings"
repository = "https://github.com/logos-messaging/logos-delivery-rust-bindings"
keywords = ["waku", "peer-to-peer", "libp2p", "networking"]
categories = ["network-programming"]

View File

@ -1,21 +1,22 @@
# Waku rust bindgen bindings
[<img alt="github" src="https://img.shields.io/badge/github-Github-red?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/logos-messaging/logos-messaging-rust-bindings)
[<img alt="github" src="https://img.shields.io/badge/github-Github-red?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/logos-messaging/logos-delivery-rust-bindings)
[<img alt="crates.io" src="https://img.shields.io/crates/v/waku-bindings.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/waku-sys)
[<img alt="docs.rs" src="https://img.shields.io/badge/doc/waku-bindings-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/waku-sys)
[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/logos-messaging/logos-messaging-rust-bindings/main.yml?branch=master" height="20">](https://github.com/logos-messaging/logos-messaging-rust-bindings/actions/workflows/main.yml?query=branch%3Amaster)
[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/logos-messaging/logos-delivery-rust-bindings/main.yml?branch=master" height="20">](https://github.com/logos-messaging/logos-delivery-rust-bindings/actions/workflows/main.yml?query=branch%3Amaster)
Rust layer on top of [`go-waku`](https://github.com/status-im/go-waku) [c ffi bindings](https://github.com/status-im/go-waku/blob/v0.2.2/library/README.md).
Auto-generated Rust FFI bindings (via `bindgen`) on top of the
[logos-delivery C FFI](https://github.com/logos-messaging/logos-delivery/blob/master/library/libwaku.h).
## Usage
These are autogenerated, if you are looking for a proper Rust API version check on [`waku-bindings`](https://crates.io/crates/waku-bindings)
These are low-level auto-generated bindings. For a proper Rust API check [`waku-bindings`](https://crates.io/crates/waku-bindings).
Add this to your `Cargo.toml`:
```toml
[dependencies]
waku-sys = "0.1.0"
waku-sys = "1.0.0"
```
@ -25,27 +26,4 @@ Waku is the communication layer for Web3. Decentralized communication that scale
Private. Secure. Runs anywhere.
### What is Waku?
Waku is a suite of privacy-preserving, peer-to-peer messaging protocols.
Waku removes centralized third parties from messaging, enabling private, secure, censorship-free communication with no single point of failure.
Waku provides privacy-preserving capabilities, such as sender anonymity,metadata protection and unlinkability to personally identifiable information.
Waku is designed for generalized messaging, enabling human-to-human, machine-to-machine or hybrid communication.
Waku runs everywhere: desktop, server, including resource-restricted devices, such as mobile devices and browsers.
How does it work?
The first version of Waku had its origins in the Whisper protocol, with optimizations for scalability and usability. Waku v2 is a complete rewrite. Its relay protocol implements pub/sub over libp2p, and also introduces additional capabilities:
1. Retrieving historical messages for mostly-offline devices.
2. Adaptive nodes, allowing for heterogeneous nodes to contribute.
3. Bandwidth preservation for light nodes.
This makes it ideal for running a p2p protocol on mobile, or in other similarly resource-restricted environments.
Read the [Waku docs](https://docs.wakuconnect.dev/)
Read the [Waku docs](https://docs.waku.org/)

View File

@ -100,6 +100,13 @@ fn generate_bindgen_code(project_dir: &Path) {
println!("cargo:rustc-link-lib=dl");
println!("cargo:rustc-link-lib=m");
// libwaku.a bundles C++ objects (nim-lsquic / BoringSSL); link the C++ runtime.
if cfg!(target_os = "macos") {
println!("cargo:rustc-link-lib=c++");
} else {
println!("cargo:rustc-link-lib=stdc++");
}
println!(
"cargo:rustc-link-search=native={}",
nwaku_path
@ -113,6 +120,22 @@ fn generate_bindgen_code(project_dir: &Path) {
.compile("cmditems"); // Compile it as a library
println!("cargo:rustc-link-lib=static=cmditems");
// Link librln.a (built from vendored zerokit by the Nim Makefile).
// The Rust `rln` crate is not used as a dependency because its older
// versions (0.3.x) pulled in wasmer 2.x which references __rust_probestack,
// a symbol removed in Rust 1.86. Instead, we link the prebuilt librln_*.a
// directly, which is the same artifact that libwaku.a was compiled against.
if let Ok(entries) = std::fs::read_dir(&nwaku_path) {
for entry in entries.flatten() {
let name = entry.file_name();
let name = name.to_string_lossy();
if name.starts_with("librln_") && name.ends_with(".a") {
println!("cargo:rustc-link-arg={}", entry.path().display());
break;
}
}
}
// Generate waku bindings with bindgen
let bindings = bindgen::Builder::default()
// The input header we would like to generate

@ -1 +1 @@
Subproject commit 4117449b9af6c0304a6115dd4bc0d1d745159685
Subproject commit 104ce6e5ac16b9c5e818788e2fb2858c36f36bbf