refactor: Remove unused imports and handle unused results
Build and Push Docker Image / build_docker_image (push) Successful in 16m28s

This commit performs general code cleanup to improve quality and address compiler warnings.

Unused import statements have been removed from several files, including `HashSet`, `anyhow`, `log::error`, `serde::Deserialize`, and `serde_json::Value`. This declutters the code and makes dependencies clearer.

Additionally, the `Result` returned by `RelayMessage::send_ok` and `RelayMessage::send_notice` is now explicitly ignored. This resolves `must_use` warnings for these fire-and-forget message sending functions, where error handling is not critical to the application's flow.
This commit is contained in:
2025-09-22 16:56:00 +08:00
parent 7ac67102ef
commit b64ec550e0
7 changed files with 128 additions and 51 deletions
-1
View File
@@ -4,7 +4,6 @@ use anyhow::Result;
use log::error;
use sqlx::sqlite::SqlitePool;
use sqlx::{Row, query};
use std::collections::HashSet;
pub async fn init_database(pool: &SqlitePool) -> Result<()> {
let create_events_table = r#"
+1 -2
View File
@@ -1,6 +1,5 @@
use anyhow::{Result, anyhow};
use anyhow::Result;
use httparse::{EMPTY_HEADER, Request};
use log::{error, info};
use sqlx::SqlitePool;
use std::collections::{HashMap, HashSet};
use std::sync::Arc;
+1 -1
View File
@@ -1,5 +1,5 @@
use crate::nostr::Filter;
use serde::{Deserialize, Serialize};
use serde::Serialize;
use std::collections::HashMap;
use tokio::sync::mpsc;
use uuid::Uuid;
+16 -11
View File
@@ -1,9 +1,9 @@
use anyhow::Result;
use log::{debug, error, info};
use log::{debug, info};
use secp256k1::{
Message as SecpMessage, Secp256k1, XOnlyPublicKey, schnorr::Signature as SchnorrSignature,
};
use serde_json::{Value, json};
use serde_json::json;
use sha2::{Digest, Sha256};
use sqlx::SqlitePool;
use std::{
@@ -31,7 +31,7 @@ pub trait NostrEventExt {
impl NostrEventExt for NostrEvent {
// 根据 Nostr 协议规则序列化事件,用于计算事件 ID
fn serialize_for_id(&self) -> String {
let serialized = json!([
json!([
0, // 用于 ID 计算的协议版本,Nostr 当前为 0
self.pubkey,
self.created_at,
@@ -39,8 +39,7 @@ impl NostrEventExt for NostrEvent {
self.tags,
self.content
])
.to_string();
serialized
.to_string()
}
// 验证事件的有效性(ID、时间戳、标签数量、签名)
@@ -259,7 +258,7 @@ impl NostrEventExt for NostrEvent {
) -> Result<(), anyhow::Error> {
// 1. 验证事件类型是否为 NIP-42 认证事件 (kind 22242)
if self.kind != 22242 {
RelayMessage::send_ok(
let _ = RelayMessage::send_ok(
&self.id,
false,
"AUTH event must be kind 22242".to_string(), // 根据协议,OK 消息应包含事件 ID
@@ -271,7 +270,10 @@ impl NostrEventExt for NostrEvent {
// 2. 验证事件签名是否有效
if !self.verify() {
RelayMessage::send_notice("Invalid AUTH event signature".to_string(), to_client_msg_tx)
let _ = RelayMessage::send_notice(
"Invalid AUTH event signature".to_string(),
to_client_msg_tx,
)
.await;
return Ok(());
}
@@ -293,7 +295,7 @@ impl NostrEventExt for NostrEvent {
let challenge = match challenge {
Some(c) => c,
None => {
RelayMessage::send_notice(
let _ = RelayMessage::send_notice(
"AUTH event missing challenge tag".to_string(),
to_client_msg_tx,
)
@@ -318,7 +320,10 @@ impl NostrEventExt for NostrEvent {
};
if !is_valid_challenge {
RelayMessage::send_notice("Invalid or expired challenge".to_string(), to_client_msg_tx)
let _ = RelayMessage::send_notice(
"Invalid or expired challenge".to_string(),
to_client_msg_tx,
)
.await;
return Ok(());
}
@@ -329,7 +334,7 @@ impl NostrEventExt for NostrEvent {
.unwrap_or(Duration::ZERO)
.as_secs();
if self.created_at < now.saturating_sub(60) || self.created_at > now + 60 {
RelayMessage::send_notice(
let _ = RelayMessage::send_notice(
"AUTH event timestamp out of acceptable range (must be within 60s of now)"
.to_string(),
to_client_msg_tx,
@@ -347,7 +352,7 @@ impl NostrEventExt for NostrEvent {
info!("Client authenticated with pubkey: {}", self.pubkey);
// 根据 NIP-42,认证成功也应该回复 OK 消息
RelayMessage::send_ok(
let _ = RelayMessage::send_ok(
&self.id,
true,
"Authentication successful.".to_string(),
-1
View File
@@ -2,7 +2,6 @@ use anyhow::Result;
use log::debug;
use sqlx::sqlite::SqlitePool;
use sqlx::{Execute, QueryBuilder, Row};
use std::collections::HashMap;
use crate::constants::{DEFAULT_LIMIT, MAX_LIMIT};
use crate::nostr::Filter;
+49 -10
View File
@@ -3,6 +3,7 @@ use log::error;
use serde_json;
use tokio::sync::mpsc;
pub struct RelayMessage;
use anyhow::{Result, anyhow};
impl RelayMessage {
// 发送 OK 消息 (NIP-20)
@@ -23,27 +24,46 @@ impl RelayMessage {
event: &NostrEvent,
sub_id: &str,
to_client_msg_tx: &mpsc::Sender<String>,
) {
) -> Result<()> {
// 尝试将 NostrEvent 序列化为 JSON 字符串
let event_json = match serde_json::to_string(event) {
Ok(json) => json,
Err(e) => {
error!("Failed to serialize event {} for sending: {}", event.id, e);
return; // 序列化失败则不发送
return Err(anyhow!(
"Failed to serialize event {} for sending: {}",
event.id,
e
));
}
};
let msg = format!("[\"EVENT\", \"{}\", {}]", sub_id, event_json);
if let Err(e) = to_client_msg_tx.send(msg).await {
// 此错误通常表示客户端的接收端已关闭(客户端已断开)
match to_client_msg_tx.send(msg).await {
Ok(_) => Ok(()),
Err(e) => {
error!("Failed to send EVENT message (sub_id: {}): {}", sub_id, e);
Err(anyhow!(
"Failed to send EVENT message (sub_id: {}): {}",
sub_id,
e
))
}
}
}
// 发送 EOSE 消息 (NIP-15)
pub async fn send_eose(sub_id: &str, to_client_msg_tx: &mpsc::Sender<String>) {
pub async fn send_eose(sub_id: &str, to_client_msg_tx: &mpsc::Sender<String>) -> Result<()> {
let msg = format!("[\"EOSE\", \"{}\"]", sub_id);
if let Err(e) = to_client_msg_tx.send(msg).await {
match to_client_msg_tx.send(msg).await {
Ok(_) => Ok(()),
Err(e) => {
error!("Failed to send EOSE message (sub_id: {}): {}", sub_id, e);
Err(anyhow!(
"Failed to send EOSE message (sub_id: {}): {}",
sub_id,
e
))
}
}
}
@@ -52,21 +72,40 @@ impl RelayMessage {
sub_id: &str,
message: String,
to_client_msg_tx: &mpsc::Sender<String>,
) {
) -> Result<()> {
let msg = format!("[\"CLOSED\", \"{}\", \"{}\"]", sub_id, message);
if let Err(e) = to_client_msg_tx.send(msg).await {
match to_client_msg_tx.send(msg).await {
Ok(_) => Ok(()),
Err(e) => {
error!("Failed to send CLOSED message (sub_id: {}): {}", sub_id, e);
Err(anyhow!(
"Failed to send CLOSED message (sub_id: {}): {}",
sub_id,
e
))
}
}
}
// 发送 NOTICE 消息 (NIP-01)
pub async fn send_notice(message: String, to_client_msg_tx: &mpsc::Sender<String>) {
pub async fn send_notice(
message: String,
to_client_msg_tx: &mpsc::Sender<String>,
) -> Result<()> {
let msg = format!("[\"NOTICE\", \"{}\"]", message);
if let Err(e) = to_client_msg_tx.send(msg).await {
match to_client_msg_tx.send(msg).await {
Ok(_) => Ok(()),
Err(e) => {
error!(
"Failed to send NOTICE message (message: {}): {}",
message, e
);
Err(anyhow!(
"Failed to send NOTICE message (message: {}): {}",
message,
e
))
}
}
}
}
+52 -16
View File
@@ -9,7 +9,7 @@ use std::{
};
use tokio::net::TcpStream;
use tokio::sync::{RwLock, broadcast, mpsc};
use tokio_tungstenite::{WebSocketStream, accept_async, tungstenite::protocol::Message};
use tokio_tungstenite::{accept_async, tungstenite::protocol::Message};
use uuid::Uuid;
use crate::constants::{CLIENT_CHANNEL_SIZE, MAX_FILTERS_PER_REQ, MAX_SUBSCRIPTIONS, SERVER_INFO};
@@ -18,7 +18,7 @@ use crate::nostr::event::NostrEventExt;
use crate::nostr::filter::FilterExt;
use crate::nostr::messages::RelayMessage;
use crate::nostr::utils::extract_p_tags_from_vec;
use crate::nostr::{ClientMessage, Filter, NostrEvent};
use crate::nostr::{Filter, NostrEvent};
pub async fn handle_ws_connection(
stream: TcpStream,
@@ -77,7 +77,13 @@ pub async fn handle_ws_connection(
let conn = client_conn_for_send.read().await;
for (sub_id, subscription) in &conn.subscriptions {
if subscription.filters.iter().any(|filter| filter.matches(&event)) {
RelayMessage::send_event(&event, sub_id, &conn.sender).await;
match RelayMessage::send_event(&event, sub_id, &conn.sender).await {
Ok(()) => debug!("Sent event to client {}", client_id),
Err(e) => {
error!("Failed to send event to client {}: {}", client_id, e);
break;
},
}
}
}
}
@@ -124,8 +130,21 @@ pub async fn handle_ws_connection(
.await
{
error!("Error handling message for client {}: {}", client_id, e);
RelayMessage::send_notice(format!("Invalid message: {}", e), &client_tx)
.await;
match RelayMessage::send_notice(
format!("Invalid message: {}", e),
&client_tx,
)
.await
{
Ok(()) => debug!("Sent error notice to client {}", client_id),
Err(e) => {
debug!(
"Failed to send error notice to client {}: {}",
client_id, e
);
return;
}
};
}
});
}
@@ -185,7 +204,7 @@ pub async fn handle_message(
.to_string(),
to_client_msg_tx,
)
.await;
.await?;
return Ok(());
}
let sub_id = arr
@@ -203,7 +222,7 @@ pub async fn handle_message(
format!("Maximum subscriptions ({}) exceeded", MAX_SUBSCRIPTIONS),
to_client_msg_tx,
)
.await;
.await?;
return Ok(());
}
}
@@ -215,7 +234,7 @@ pub async fn handle_message(
format!("Maximum filters ({}) exceeded", MAX_FILTERS_PER_REQ),
to_client_msg_tx,
)
.await;
.await?;
return Ok(());
}
let filter: Filter = serde_json::from_value(arr[i].clone())
@@ -239,12 +258,12 @@ pub async fn handle_message(
for filter in &filters {
let events = filter.select(pool).await?; // 使用 FilterExt
for event in events {
RelayMessage::send_event(&event, &sub_id, to_client_msg_tx).await;
RelayMessage::send_event(&event, &sub_id, to_client_msg_tx).await?;
}
}
// 发送 EOSE 消息,表示历史事件已发送完毕
RelayMessage::send_eose(&sub_id, to_client_msg_tx).await;
RelayMessage::send_eose(&sub_id, to_client_msg_tx).await?;
Ok(())
}
@@ -279,26 +298,43 @@ pub async fn handle_message(
if SERVER_INFO.auth_required {
let conn = client_conn_clone.read().await;
if !conn.authenticated {
RelayMessage::send_closed(
match RelayMessage::send_closed(
// NIP-42 Auth: Forbid unauthenticated EVENT
&conn.id.to_string(), // 使用 client_id 作为 sub_id 来匹配 AUTH 挑战
"auth-required: Authentication required to publish events".to_string(),
&to_client_msg_tx_clone,
)
.await;
.await
{
Ok(_) => debug!("Client {}: Authentication challenge sent.", conn.id),
Err(e) => {
debug!("Failed to send authentication challenge: {}", e);
return;
}
};
debug!("Client {}: Not authenticated, event rejected.", conn.id);
return;
}
let trust_accounts_guard = trust_accounts_clone.read().await;
if !trust_accounts_guard.contains(&event_clone.pubkey) {
RelayMessage::send_closed(
match RelayMessage::send_closed(
// NIP-42 Auth: Forbid unauthorized EVENT
&conn.id.to_string(),
"restricted: You are not in the trust list to publish events"
.to_string(),
&to_client_msg_tx_clone,
)
.await;
.await
{
Ok(_) => debug!(
"Client {}: Pubkey {} not in trust list, authentication challenge sent.",
conn.id, event_clone.pubkey
),
Err(e) => {
error!("Failed to send authentication challenge: {}", e);
return;
}
};
debug!(
"Client {}: Pubkey {} not in trust list, event rejected.",
conn.id, event_clone.pubkey
@@ -369,7 +405,7 @@ pub async fn handle_message(
"Subscription cancelled".to_string(),
to_client_msg_tx,
)
.await;
.await?;
Ok(())
}
@@ -379,7 +415,7 @@ pub async fn handle_message(
"AUTH message requires an event: [\"AUTH\", <auth_event>]".to_string(),
to_client_msg_tx,
)
.await;
.await?;
return Ok(());
}