chore: fix test and lint

This commit is contained in:
darshankabariya 2026-03-03 14:03:33 +05:30
parent 09f0ae07ad
commit d4800312e6
No known key found for this signature in database
GPG Key ID: 9A92CCD9899F0D22
4 changed files with 99 additions and 85 deletions

View File

@ -7,9 +7,8 @@ use tokio::task;
use tokio::sync::mpsc;
use waku::{
waku_new, Encoding, WakuEvent, LibwakuResponse, WakuContentTopic,
WakuMessage, WakuNodeConfig, WakuNodeHandle, Initialized, Running,
general::pubsubtopic::PubsubTopic,
general::pubsubtopic::PubsubTopic, waku_new, Encoding, Initialized, LibwakuResponse, Running,
WakuContentTopic, WakuEvent, WakuMessage, WakuNodeConfig, WakuNodeHandle,
};
#[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone)]
@ -29,7 +28,7 @@ struct TicTacToeApp<State> {
game_state: Arc<Mutex<GameState>>,
waku: WakuNodeHandle<State>,
game_topic: PubsubTopic,
tx: mpsc::Sender<String>, // Sender to send `msg` to main thread
tx: mpsc::Sender<String>, // Sender to send `msg` to main thread
player_role: Option<Player>, // Store the player's role (X or O)
}
@ -51,7 +50,8 @@ impl TicTacToeApp<Initialized> {
async fn start(self) -> TicTacToeApp<Running> {
let tx_clone = self.tx.clone();
let game_content_topic = WakuContentTopic::new("waku", "2", "tictactoegame", Encoding::Proto);
let game_content_topic =
WakuContentTopic::new("waku", "2", "tictactoegame", Encoding::Proto);
let my_closure = move |response| {
if let LibwakuResponse::Success(v) = response {
@ -78,13 +78,13 @@ impl TicTacToeApp<Initialized> {
// Handle the error as needed, or just log and skip
}
}
},
}
WakuEvent::RelayTopicHealthChange(_evt) => {
// dbg!("Relay topic change evt", evt);
},
}
WakuEvent::ConnectionChange(_evt) => {
// dbg!("Conn change evt", evt);
},
}
WakuEvent::Unrecognized(err) => panic!("Unrecognized waku event: {:?}", err),
_ => panic!("event case not expected"),
};
@ -92,13 +92,17 @@ impl TicTacToeApp<Initialized> {
};
// Establish a closure that handles the incoming messages
self.waku.set_event_callback(my_closure).expect("set event call back working");
self.waku
.set_event_callback(my_closure)
.expect("set event call back working");
// Start the waku node
let waku = self.waku.start().await.expect("waku should start");
// Subscribe to desired topic using the relay protocol
waku.relay_subscribe(&self.game_topic).await.expect("waku should subscribe");
waku.relay_subscribe(&self.game_topic)
.await
.expect("waku should subscribe");
// Example filter subscription. This is needed in edge nodes (resource-restricted devices)
// Nodes usually use either relay or lightpush/filter protocols
@ -138,15 +142,13 @@ impl TicTacToeApp<Running> {
let serialized_game_state = serde_json::to_string(game_state).unwrap();
let content_topic = WakuContentTopic::new("waku", "2", "tictactoegame", Encoding::Proto);
let message = WakuMessage::new(
&serialized_game_state,
content_topic,
0,
Vec::new(),
false,
);
let message = WakuMessage::new(&serialized_game_state, content_topic, 0, Vec::new(), false);
if let Ok(msg_hash) = self.waku.relay_publish_message(&message, &self.game_topic, None).await {
if let Ok(msg_hash) = self
.waku
.relay_publish_message(&message, &self.game_topic, None)
.await
{
dbg!(format!("message hash published: {}", msg_hash));
}
@ -163,7 +165,6 @@ impl TicTacToeApp<Running> {
fn make_move(&mut self, row: usize, col: usize) {
if let Ok(mut game_state) = self.game_state.try_lock() {
if let Some(my_role) = self.player_role {
if game_state.current_turn != my_role {
return; // skip click if not my turn
@ -201,27 +202,31 @@ impl TicTacToeApp<Running> {
fn check_winner(&self, game_state: &GameState) -> Option<Player> {
// Check rows, columns, and diagonals
for i in 0..3 {
if game_state.board[i][0] == game_state.board[i][1] &&
game_state.board[i][1] == game_state.board[i][2] {
if game_state.board[i][0] == game_state.board[i][1]
&& game_state.board[i][1] == game_state.board[i][2]
{
if let Some(player) = game_state.board[i][0] {
return Some(player);
}
}
if game_state.board[0][i] == game_state.board[1][i] &&
game_state.board[1][i] == game_state.board[2][i] {
if game_state.board[0][i] == game_state.board[1][i]
&& game_state.board[1][i] == game_state.board[2][i]
{
if let Some(player) = game_state.board[0][i] {
return Some(player);
}
}
}
if game_state.board[0][0] == game_state.board[1][1] &&
game_state.board[1][1] == game_state.board[2][2] {
if game_state.board[0][0] == game_state.board[1][1]
&& game_state.board[1][1] == game_state.board[2][2]
{
if let Some(player) = game_state.board[0][0] {
return Some(player);
}
}
if game_state.board[0][2] == game_state.board[1][1] &&
game_state.board[1][1] == game_state.board[2][0] {
if game_state.board[0][2] == game_state.board[1][1]
&& game_state.board[1][1] == game_state.board[2][0]
{
if let Some(player) = game_state.board[0][2] {
return Some(player);
}
@ -241,7 +246,6 @@ impl TicTacToeApp<Running> {
impl eframe::App for TicTacToeApp<Running> {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
// Request a repaint every second
ctx.request_repaint_after(Duration::from_secs(1));
@ -286,13 +290,16 @@ impl eframe::App for TicTacToeApp<Running> {
Some(Player::O) => "O",
None => "-",
};
}
else {
} else {
label = "#";
}
}
let button = ui.add(egui::Button::new(label).min_size(egui::vec2(cell_size, cell_size)).sense(egui::Sense::click()));
let button = ui.add(
egui::Button::new(label)
.min_size(egui::vec2(cell_size, cell_size))
.sense(egui::Sense::click()),
);
if button.clicked() {
self.make_move(row, col);
@ -384,13 +391,11 @@ async fn main() -> eframe::Result<()> {
while let Some(msg) = rx.recv().await {
// println!("MSG received: {}", msg);
// Handle the received message, e.g., update the UI or game state
if let Ok(parsed_value) = serde_json::from_str::<GameState>(&msg)
{
if let Ok(mut unclocked_game_state) = clone.lock(){
if let Ok(parsed_value) = serde_json::from_str::<GameState>(&msg) {
if let Ok(mut unclocked_game_state) = clone.lock() {
*unclocked_game_state = parsed_value;
}
}
else {
} else {
eprintln!("Failed to parse JSON");
}
}

View File

@ -1,19 +1,19 @@
mod protocol;
use crate::protocol::{Chat2Message, TOY_CHAT_CONTENT_TOPIC};
use tokio::task;
use chrono::Utc;
use crossterm::{
event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use prost::Message;
use chrono::Utc;
use std::io::Write;
use std::os::unix::io::IntoRawFd;
use std::sync::{Arc, RwLock};
use std::{error::Error, io};
use std::time::Duration;
use std::{error::Error, io};
use tokio::task;
use tui::{
backend::{Backend, CrosstermBackend},
layout::{Constraint, Direction, Layout},
@ -24,8 +24,8 @@ use tui::{
};
use unicode_width::UnicodeWidthStr;
use waku::{
general::pubsubtopic::PubsubTopic, general::Result, waku_new, Initialized, LibwakuResponse, Running, WakuEvent,
WakuMessage, WakuNodeConfig, WakuNodeHandle,
general::pubsubtopic::PubsubTopic, general::Result, waku_new, Initialized, LibwakuResponse,
Running, WakuEvent, WakuMessage, WakuNodeConfig, WakuNodeHandle,
};
enum InputMode {
@ -61,19 +61,16 @@ impl App<Initialized> {
max_message_size: Some("1024KiB".to_string()),
relay_topics: vec![String::from(&pubsub_topic)],
log_level: Some("FATAL"), // Supported: TRACE, DEBUG, INFO, NOTICE, WARN, ERROR or FATAL
keep_alive: Some(true),
// Discovery
dns_discovery: Some(true),
dns_discovery_url: Some("enrtree://AMOJVZX4V6EXP7NTJPMAYJYST2QP6AJXYW76IU6VGJS7UVSNDYZG4@boot.prod.status.nodes.status.im"),
// discv5_discovery: Some(true),
// discv5_udp_port: Some(9001),
// discv5_enr_auto_update: Some(false),
..Default::default()
})).await?;
Ok(App {
input: String::new(),
input_mode: InputMode::Normal,
@ -84,17 +81,15 @@ impl App<Initialized> {
}
async fn start_waku_node(self) -> Result<App<Running>> {
let shared_messages = Arc::clone(&self.messages);
self.waku.set_event_callback(move|response| {
self.waku.set_event_callback(move |response| {
if let LibwakuResponse::Success(v) = response {
let event: WakuEvent =
serde_json::from_str(v.unwrap().as_str()).expect("failed parsing event in set_event_callback");
let event: WakuEvent = serde_json::from_str(v.unwrap().as_str())
.expect("failed parsing event in set_event_callback");
match event {
WakuEvent::WakuMessage(evt) => {
if evt.waku_message.content_topic != TOY_CHAT_CONTENT_TOPIC {
return; // skip the messages that don't belong to the toy chat
}
@ -112,14 +107,14 @@ impl App<Initialized> {
write!(out, "{e:?}").unwrap();
}
}
},
}
WakuEvent::RelayTopicHealthChange(_evt) => {
// dbg!("Relay topic change evt", evt);
},
}
WakuEvent::ConnectionChange(_evt) => {
// dbg!("Conn change evt", evt);
},
WakuEvent::NodeHealthChange(_evt) => {},
}
WakuEvent::NodeHealthChange(_evt) => {}
WakuEvent::Unrecognized(err) => eprintln!("Unrecognized waku event: {:?}", err),
_ => eprintln!("event case not expected"),
};
@ -139,32 +134,37 @@ impl App<Initialized> {
}
impl App<Running> {
async fn retrieve_history(&mut self) {
let one_day_in_secs = 60 * 60 * 24;
let time_start = (Duration::from_secs(Utc::now().timestamp() as u64)
- Duration::from_secs(one_day_in_secs))
.as_nanos() as u64;
.as_nanos() as u64;
let include_data = true;
let messages = self.waku.store_query(None,
vec![TOY_CHAT_CONTENT_TOPIC.clone()],
STORE_NODE,
include_data,
Some(time_start),
None,
None).await.unwrap();
let messages = self
.waku
.store_query(
None,
vec![TOY_CHAT_CONTENT_TOPIC.clone()],
STORE_NODE,
include_data,
Some(time_start),
None,
None,
)
.await
.unwrap();
let messages: Vec<_> = messages
.into_iter()
// we expect messages because the query was passed with include_data == true
.filter(|item| item.message.is_some())
.map(|store_resp_msg| {
<Chat2Message as Message>::decode(store_resp_msg.message.unwrap().payload())
.expect("Toy chat messages should be decodeable")
})
.collect();
.into_iter()
// we expect messages because the query was passed with include_data == true
.filter(|item| item.message.is_some())
.map(|store_resp_msg| {
<Chat2Message as Message>::decode(store_resp_msg.message.unwrap().payload())
.expect("Toy chat messages should be decodeable")
})
.collect();
if !messages.is_empty() {
*self.messages.write().unwrap() = messages;
@ -214,14 +214,18 @@ impl App<Running> {
handle.block_on(async {
// Assuming `self` is available in the current context
let pubsub_topic = PubsubTopic::new(DEFAULT_PUBSUB_TOPIC);
if let Err(e) = self.waku.relay_publish_message(
&waku_message,
&pubsub_topic,
None,
).await {
let mut out = std::io::stderr();
write!(out, "{e:?}").unwrap();
}
if let Err(e) = self
.waku
.relay_publish_message(
&waku_message,
&pubsub_topic,
None,
)
.await
{
let mut out = std::io::stderr();
write!(out, "{e:?}").unwrap();
}
});
});
}
@ -243,7 +247,10 @@ impl App<Running> {
}
async fn stop_app(self) {
self.waku.stop().await.expect("the node should stop properly");
self.waku
.stop()
.await
.expect("the node should stop properly");
}
}
@ -256,7 +263,9 @@ async fn main() -> std::result::Result<(), Box<dyn Error>> {
// Redirect stderr to /dev/null so nwaku discovery/LSQUIC logs don't corrupt the TUI
let devnull = std::fs::OpenOptions::new().write(true).open("/dev/null")?;
unsafe { libc::dup2(devnull.into_raw_fd(), 2); }
unsafe {
libc::dup2(devnull.into_raw_fd(), 2);
}
// setup terminal
enable_raw_mode()?;

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

@ -105,10 +105,7 @@ fn generate_bindgen_code(project_dir: &Path) {
let name_str = name.to_string_lossy();
if name_str.starts_with("librln_") && name_str.ends_with(".a") {
let lib_name = name_str.trim_start_matches("lib").trim_end_matches(".a");
println!(
"cargo:rustc-link-search=native={}",
nwaku_path.display()
);
println!("cargo:rustc-link-search=native={}", nwaku_path.display());
println!("cargo:rustc-link-lib=static={}", lib_name);
break;
}