171 lines
5.4 KiB
Rust
Raw Normal View History

feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
use base64::Engine;
use multiaddr::Multiaddr;
use regex::Regex;
use secp256k1::SecretKey;
use serial_test::serial;
use std::str::FromStr;
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
use std::str::from_utf8;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use tokio::time;
use tokio::time::sleep;
2022-11-29 10:28:32 +01:00
use waku_bindings::{
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
Encoding, LogosDeliveryCtx, WakuContentTopic, WakuMessage, WakuNodeConfig,
};
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
const ECHO_TIMEOUT: u64 = 1000;
const ECHO_MESSAGE: &str = "Hi from 🦀!";
2024-02-19 17:04:41 -04:00
const TEST_PUBSUBTOPIC: &str = "test";
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
const TIMEOUT: Duration = Duration::from_secs(30);
/// Cargo runs test binaries in parallel and serial_test only serialises within
/// one, so each binary needs its own persistency root. Every node in a binary
/// must share it: the singleton refuses to be re-targeted.
const STORAGE_PATH: &str = "./data-node-test";
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
fn new_node(config: WakuNodeConfig) -> Result<LogosDeliveryCtx, String> {
let config = WakuNodeConfig {
local_storage_path: Some(STORAGE_PATH.to_string()),
..config
};
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
let config_json = serde_json::to_string(&config).map_err(|e| e.to_string())?;
LogosDeliveryCtx::create(config_json, TIMEOUT)
2024-02-14 16:52:21 -04:00
}
async fn test_echo_messages(
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
node1: LogosDeliveryCtx,
node2: LogosDeliveryCtx,
content: &'static str,
content_topic: WakuContentTopic,
) -> Result<(), String> {
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
// The relay push arrives as a typed payload, so the test only has to decode
// the base64 body rather than match on an event enum.
let rx_payload: Arc<Mutex<Vec<u8>>> = Arc::new(Mutex::new(Vec::new()));
let rx_payload_cloned = rx_payload.clone();
node2.add_on_received_message_listener(move |event| {
let decoded = base64::engine::general_purpose::STANDARD
.decode(&event.waku_message.payload)
.expect("event payload should be base64");
if let Ok(mut payload) = rx_payload_cloned.lock() {
*payload = decoded;
}
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
});
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
node1.start_node_async().await?;
node2.start_node_async().await?;
node1
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
.waku_relay_subscribe_async(TEST_PUBSUBTOPIC.to_string())
.await?;
node2
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
.waku_relay_subscribe_async(TEST_PUBSUBTOPIC.to_string())
.await?;
sleep(Duration::from_secs(5)).await;
// Interconnect nodes
// Replace all matches with 127.0.0.1 to avoid issue with NAT or firewall.
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
let addresses1 = node1.waku_listen_addresses_async().await?;
let addresses1 = addresses1
.split(',')
.next()
.ok_or("node1 should report a listen address")?;
let re = Regex::new(r"\b(?:\d{1,3}\.){3}\d{1,3}\b").unwrap();
let addresses1 = re.replace_all(addresses1, "127.0.0.1").to_string();
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
// Parsed only to prove the address is well formed before handing it over.
let addresses1 = addresses1
.parse::<Multiaddr>()
.expect("parse multiaddress")
.to_string();
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
println!("Connecting node1 to node2: {addresses1}");
node2.waku_connect_async(addresses1, 10_000).await?;
// Wait for mesh to form
sleep(Duration::from_secs(3)).await;
dbg!("Before publish");
let message = WakuMessage::new(content, content_topic, 1, Vec::new(), false);
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
let message = serde_json::to_string(&message).map_err(|e| e.to_string())?;
node1
.waku_relay_publish_async(TEST_PUBSUBTOPIC.to_string(), message, 10_000)
.await
.expect("send relay messages");
// Wait for the msg to arrive
for _ in 0..50 {
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
let message_received = if let Ok(payload) = rx_payload.lock() {
!payload.is_empty()
&& from_utf8(&payload).expect("should be valid message") == ECHO_MESSAGE
} else {
2025-11-13 00:12:21 +05:30
false
};
if message_received {
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
node1.stop_node_async().await?;
node2.stop_node_async().await?;
2025-11-13 00:12:21 +05:30
return Ok(());
}
2025-11-13 00:12:21 +05:30
sleep(Duration::from_millis(100)).await;
}
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
node1.stop_node_async().await?;
node2.stop_node_async().await?;
2025-11-13 00:12:21 +05:30
Err("Unexpected test ending".to_string())
}
#[tokio::test]
#[serial]
async fn default_echo() -> Result<(), String> {
println!("Test default_echo");
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
let node1 = new_node(WakuNodeConfig {
tcp_port: Some(60010),
..Default::default()
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
})?;
let node2 = new_node(WakuNodeConfig {
tcp_port: Some(60020),
..Default::default()
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
})?;
let content_topic = WakuContentTopic::new("toychat", "2", "huilong", Encoding::Proto);
let sleep = time::sleep(Duration::from_secs(ECHO_TIMEOUT));
tokio::pin!(sleep);
// Send and receive messages. Waits until all messages received.
// The echo's Result decides the outcome: completing is not the same as
// having received the message.
let got_all = tokio::select! {
_ = sleep => Err("timed out waiting for the echo".to_string()),
result = test_echo_messages(node1, node2, ECHO_MESSAGE, content_topic) => result,
};
got_all?;
Ok(())
}
#[tokio::test]
#[serial]
async fn node_restart() {
let config = WakuNodeConfig {
node_key: Some(
SecretKey::from_str("05f381866cc21f6c1e2e80e07fa732008e36d942dce3206ad6dcd6793c98d609")
.unwrap(),
2024-02-19 17:04:41 -04:00
),
..Default::default()
};
for _ in 0..3 {
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
let node = new_node(config.clone()).expect("default config should be valid");
node.start_node_async()
.await
.expect("node should start with valid config");
feat!: expose the generated bindings, drop the hand-written FFI tier The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:08:23 +02:00
node.stop_node_async().await.expect("node should stop");
// Resources are freed by LogosDeliveryCtx's Drop impl.
}
}