refactor: format

This commit is contained in:
Greg Heartsfield 2023-02-25 14:49:35 -06:00
parent 6df92f9580
commit c1c25a22f5
14 changed files with 153 additions and 126 deletions

View File

@ -2,9 +2,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::configure() tonic_build::configure()
.build_server(false) .build_server(false)
.protoc_arg("--experimental_allow_proto3_optional") .protoc_arg("--experimental_allow_proto3_optional")
.compile( .compile(&["proto/nauthz.proto"], &["proto"])?;
&["proto/nauthz.proto"],
&["proto"],
)?;
Ok(()) Ok(())
} }

View File

@ -161,12 +161,12 @@ impl ClientConn {
Challenge(_) => (), Challenge(_) => (),
AuthPubkey(_) => { AuthPubkey(_) => {
// already authenticated // already authenticated
return Ok(()) return Ok(());
}, }
NoAuth => { NoAuth => {
// unexpected AUTH request // unexpected AUTH request
return Err(Error::AuthFailure); return Err(Error::AuthFailure);
}, }
} }
match event.validate() { match event.validate() {
Ok(_) => { Ok(_) => {

View File

@ -2,12 +2,12 @@
use crate::config::Settings; use crate::config::Settings;
use crate::error::{Error, Result}; use crate::error::{Error, Result};
use crate::event::Event; use crate::event::Event;
use crate::nauthz;
use crate::notice::Notice; use crate::notice::Notice;
use crate::repo::postgres::{PostgresPool, PostgresRepo}; use crate::repo::postgres::{PostgresPool, PostgresRepo};
use crate::repo::sqlite::SqliteRepo; use crate::repo::sqlite::SqliteRepo;
use crate::repo::NostrRepo; use crate::repo::NostrRepo;
use crate::server::NostrMetrics; use crate::server::NostrMetrics;
use crate::nauthz;
use governor::clock::Clock; use governor::clock::Clock;
use governor::{Quota, RateLimiter}; use governor::{Quota, RateLimiter};
use r2d2; use r2d2;
@ -181,10 +181,7 @@ pub async fn db_writer(
&event.kind &event.kind
); );
notice_tx notice_tx
.try_send(Notice::blocked( .try_send(Notice::blocked(event.id, "event kind is blocked by relay"))
event.id,
"event kind is blocked by relay"
))
.ok(); .ok();
continue; continue;
} }
@ -216,7 +213,6 @@ pub async fn db_writer(
uv.name.to_string(), uv.name.to_string(),
event.get_author_prefix() event.get_author_prefix()
); );
} else { } else {
info!( info!(
"rejecting event, author ({:?} / {:?}) verification invalid (expired/wrong domain)", "rejecting event, author ({:?} / {:?}) verification invalid (expired/wrong domain)",
@ -253,27 +249,44 @@ pub async fn db_writer(
} }
// nip05 address // nip05 address
let nip05_address : Option<crate::nip05::Nip05Name> = validation.and_then(|x| x.ok().map(|y| y.name)); let nip05_address: Option<crate::nip05::Nip05Name> =
validation.and_then(|x| x.ok().map(|y| y.name));
// GRPC check // GRPC check
if let Some(ref mut c) = grpc_client { if let Some(ref mut c) = grpc_client {
trace!("checking if grpc permits"); trace!("checking if grpc permits");
let grpc_start = Instant::now(); let grpc_start = Instant::now();
let decision_res = c.admit_event(&event, &subm_event.source_ip, subm_event.origin, subm_event.user_agent, nip05_address, subm_event.auth_pubkey).await; let decision_res = c
.admit_event(
&event,
&subm_event.source_ip,
subm_event.origin,
subm_event.user_agent,
nip05_address,
subm_event.auth_pubkey,
)
.await;
match decision_res { match decision_res {
Ok(decision) => { Ok(decision) => {
if !decision.permitted() { if !decision.permitted() {
// GPRC returned a decision to reject this event // GPRC returned a decision to reject this event
info!("GRPC rejected event: {:?} (kind: {}) from: {:?} in: {:?} (IP: {:?})", info!(
"GRPC rejected event: {:?} (kind: {}) from: {:?} in: {:?} (IP: {:?})",
event.get_event_id_prefix(), event.get_event_id_prefix(),
event.kind, event.kind,
event.get_author_prefix(), event.get_author_prefix(),
grpc_start.elapsed(), grpc_start.elapsed(),
subm_event.source_ip); subm_event.source_ip
notice_tx.try_send(Notice::blocked(event.id, &decision.message().unwrap_or_else(|| "".to_string()))).ok(); );
notice_tx
.try_send(Notice::blocked(
event.id,
&decision.message().unwrap_or_else(|| "".to_string()),
))
.ok();
continue; continue;
} }
}, }
Err(e) => { Err(e) => {
warn!("GRPC server error: {:?}", e); warn!("GRPC server error: {:?}", e);
} }

View File

@ -5,6 +5,8 @@ use crate::error::Error::{
EventMalformedPubkey, EventMalformedPubkey,
}; };
use crate::error::Result; use crate::error::Result;
use crate::event::EventWrapper::WrappedAuth;
use crate::event::EventWrapper::WrappedEvent;
use crate::nip05; use crate::nip05;
use crate::utils::unix_time; use crate::utils::unix_time;
use bitcoin_hashes::{sha256, Hash}; use bitcoin_hashes::{sha256, Hash};
@ -17,8 +19,6 @@ use std::collections::HashMap;
use std::collections::HashSet; use std::collections::HashSet;
use std::str::FromStr; use std::str::FromStr;
use tracing::{debug, info}; use tracing::{debug, info};
use crate::event::EventWrapper::WrappedEvent;
use crate::event::EventWrapper::WrappedAuth;
lazy_static! { lazy_static! {
/// Secp256k1 verification instance. /// Secp256k1 verification instance.
@ -90,10 +90,9 @@ pub fn single_char_tagname(tagname: &str) -> Option<char> {
} }
} }
pub enum EventWrapper { pub enum EventWrapper {
WrappedEvent(Event), WrappedEvent(Event),
WrappedAuth(Event) WrappedAuth(Event),
} }
/// Convert network event to parsed/validated event. /// Convert network event to parsed/validated event.
@ -157,11 +156,13 @@ impl Event {
/// Determine the time at which this event should expire /// Determine the time at which this event should expire
pub fn expiration(&self) -> Option<u64> { pub fn expiration(&self) -> Option<u64> {
let default = "".to_string(); let default = "".to_string();
let dvals:Vec<&String> = self.tags let dvals: Vec<&String> = self
.tags
.iter() .iter()
.filter(|x| !x.is_empty()) .filter(|x| !x.is_empty())
.filter(|x| x.get(0).unwrap() == "expiration") .filter(|x| x.get(0).unwrap() == "expiration")
.map(|x| x.get(1).unwrap_or(&default)).take(1) .map(|x| x.get(1).unwrap_or(&default))
.take(1)
.collect(); .collect();
let val_first = dvals.get(0); let val_first = dvals.get(0);
val_first.and_then(|t| t.parse::<u64>().ok()) val_first.and_then(|t| t.parse::<u64>().ok())
@ -711,9 +712,7 @@ mod tests {
// regular events do not expire // regular events do not expire
let mut event = Event::simple_event(); let mut event = Event::simple_event();
event.kind = 7; event.kind = 7;
event.tags = vec![ event.tags = vec![vec!["test".to_string(), "foo".to_string()]];
vec!["test".to_string(), "foo".to_string()],
];
assert_eq!(event.expiration(), None); assert_eq!(event.expiration(), None);
} }
@ -722,9 +721,7 @@ mod tests {
// regular events do not expire // regular events do not expire
let mut event = Event::simple_event(); let mut event = Event::simple_event();
event.kind = 7; event.kind = 7;
event.tags = vec![ event.tags = vec![vec!["expiration".to_string()]];
vec!["expiration".to_string()],
];
assert_eq!(event.expiration(), None); assert_eq!(event.expiration(), None);
} }
@ -734,9 +731,7 @@ mod tests {
let exp: u64 = 1676264138; let exp: u64 = 1676264138;
let mut event = Event::simple_event(); let mut event = Event::simple_event();
event.kind = 1; event.kind = 1;
event.tags = vec![ event.tags = vec![vec!["expiration".to_string(), exp.to_string()]];
vec!["expiration".to_string(), exp.to_string()],
];
assert_eq!(event.expiration(), Some(exp)); assert_eq!(event.expiration(), Some(exp));
} }
@ -746,9 +741,7 @@ mod tests {
let exp: i64 = -90; let exp: i64 = -90;
let mut event = Event::simple_event(); let mut event = Event::simple_event();
event.kind = 1; event.kind = 1;
event.tags = vec![ event.tags = vec![vec!["expiration".to_string(), exp.to_string()]];
vec!["expiration".to_string(), exp.to_string()],
];
assert_eq!(event.expiration(), None); assert_eq!(event.expiration(), None);
} }
@ -758,9 +751,7 @@ mod tests {
let exp: i64 = 0; let exp: i64 = 0;
let mut event = Event::simple_event(); let mut event = Event::simple_event();
event.kind = 1; event.kind = 1;
event.tags = vec![ event.tags = vec![vec!["expiration".to_string(), exp.to_string()]];
vec!["expiration".to_string(), exp.to_string()],
];
assert_eq!(event.expiration(), Some(0)); assert_eq!(event.expiration(), Some(0));
} }
@ -770,9 +761,7 @@ mod tests {
let exp: f64 = 23.334; let exp: f64 = 23.334;
let mut event = Event::simple_event(); let mut event = Event::simple_event();
event.kind = 1; event.kind = 1;
event.tags = vec![ event.tags = vec![vec!["expiration".to_string(), exp.to_string()]];
vec!["expiration".to_string(), exp.to_string()],
];
assert_eq!(event.expiration(), None); assert_eq!(event.expiration(), None);
} }

View File

@ -8,8 +8,8 @@ pub mod error;
pub mod event; pub mod event;
pub mod hexrange; pub mod hexrange;
pub mod info; pub mod info;
pub mod nip05;
pub mod nauthz; pub mod nauthz;
pub mod nip05;
pub mod notice; pub mod notice;
pub mod repo; pub mod repo;
pub mod subscription; pub mod subscription;

View File

@ -76,7 +76,7 @@ impl EventAuthzService {
origin: Option<String>, origin: Option<String>,
user_agent: Option<String>, user_agent: Option<String>,
nip05: Option<Nip05Name>, nip05: Option<Nip05Name>,
auth_pubkey: Option<Vec<u8>> auth_pubkey: Option<Vec<u8>>,
) -> Result<Box<dyn AuthzDecision>> { ) -> Result<Box<dyn AuthzDecision>> {
self.ready_connection().await; self.ready_connection().await;
let id_blob = hex::decode(&event.id)?; let id_blob = hex::decode(&event.id)?;

View File

@ -265,10 +265,10 @@ impl Verifier {
Err(Error::ChannelClosed) => { Err(Error::ChannelClosed) => {
// channel was closed, we are shutting down // channel was closed, we are shutting down
return; return;
}, }
Err(e) => { Err(e) => {
info!("error in verifier: {:?}", e); info!("error in verifier: {:?}", e);
}, }
_ => {} _ => {}
} }
} }

View File

@ -16,7 +16,7 @@ pub struct EventResult {
pub enum Notice { pub enum Notice {
Message(String), Message(String),
EventResult(EventResult), EventResult(EventResult),
AuthChallenge(String) AuthChallenge(String),
} }
impl EventResultStatus { impl EventResultStatus {

View File

@ -16,11 +16,11 @@ use crate::error;
use crate::hexrange::{hex_range, HexSearch}; use crate::hexrange::{hex_range, HexSearch};
use crate::repo::postgres_migration::run_migrations; use crate::repo::postgres_migration::run_migrations;
use crate::server::NostrMetrics; use crate::server::NostrMetrics;
use crate::utils::{is_hex, is_lower_hex, self}; use crate::utils::{self, is_hex, is_lower_hex};
use tokio::sync::mpsc::Sender; use tokio::sync::mpsc::Sender;
use tokio::sync::oneshot::Receiver; use tokio::sync::oneshot::Receiver;
use tracing::log::trace; use tracing::log::trace;
use tracing::{debug, info, warn, error}; use tracing::{debug, error, info, warn};
pub type PostgresPool = sqlx::pool::Pool<Postgres>; pub type PostgresPool = sqlx::pool::Pool<Postgres>;
@ -36,10 +36,8 @@ impl PostgresRepo {
metrics: m, metrics: m,
} }
} }
} }
/// Cleanup expired events on a regular basis /// Cleanup expired events on a regular basis
async fn cleanup_expired(conn: PostgresPool, frequency: Duration) -> Result<()> { async fn cleanup_expired(conn: PostgresPool, frequency: Duration) -> Result<()> {
tokio::task::spawn(async move { tokio::task::spawn(async move {
@ -71,7 +69,8 @@ async fn delete_expired(conn:PostgresPool) -> Result<u64> {
let update_count = sqlx::query("DELETE FROM \"event\" WHERE expires_at <= $1;") let update_count = sqlx::query("DELETE FROM \"event\" WHERE expires_at <= $1;")
.bind(Utc.timestamp_opt(utils::unix_time() as i64, 0).unwrap()) .bind(Utc.timestamp_opt(utils::unix_time() as i64, 0).unwrap())
.execute(&mut tx) .execute(&mut tx)
.await?.rows_affected(); .await?
.rows_affected();
tx.commit().await?; tx.commit().await?;
Ok(update_count) Ok(update_count)
} }
@ -151,7 +150,10 @@ ON CONFLICT (id) DO NOTHING"#,
.bind(&id_blob) .bind(&id_blob)
.bind(&pubkey_blob) .bind(&pubkey_blob)
.bind(Utc.timestamp_opt(e.created_at as i64, 0).unwrap()) .bind(Utc.timestamp_opt(e.created_at as i64, 0).unwrap())
.bind(e.expiration().and_then(|x| Utc.timestamp_opt(x as i64, 0).latest())) .bind(
e.expiration()
.and_then(|x| Utc.timestamp_opt(x as i64, 0).latest()),
)
.bind(e.kind as i64) .bind(e.kind as i64)
.bind(event_str.into_bytes()) .bind(event_str.into_bytes())
.bind(delegator_blob) .bind(delegator_blob)
@ -753,7 +755,8 @@ fn query_from_filter(f: &ReqFilter) -> Option<QueryBuilder<Postgres>> {
// never display expired events // never display expired events
query query
.push(" AND (e.expires_at IS NULL OR e.expires_at > ") .push(" AND (e.expires_at IS NULL OR e.expires_at > ")
.push_bind(Utc.timestamp_opt(utils::unix_time() as i64, 0).unwrap()).push(")"); .push_bind(Utc.timestamp_opt(utils::unix_time() as i64, 0).unwrap())
.push(")");
// Apply per-filter limit to this query. // Apply per-filter limit to this query.
// The use of a LIMIT implies a DESC order, to capture only the most recent events. // The use of a LIMIT implies a DESC order, to capture only the most recent events.

View File

@ -2,8 +2,8 @@
//use crate::config::SETTINGS; //use crate::config::SETTINGS;
use crate::config::Settings; use crate::config::Settings;
use crate::db::QueryResult; use crate::db::QueryResult;
use crate::error::Result;
use crate::error::Error::SqlError; use crate::error::Error::SqlError;
use crate::error::Result;
use crate::event::{single_char_tagname, Event}; use crate::event::{single_char_tagname, Event};
use crate::hexrange::hex_range; use crate::hexrange::hex_range;
use crate::hexrange::HexSearch; use crate::hexrange::HexSearch;
@ -257,13 +257,15 @@ impl NostrRepo for SqliteRepo {
self.maint_pool.clone(), self.maint_pool.clone(),
Duration::from_secs(60), Duration::from_secs(60),
self.write_in_progress.clone(), self.write_in_progress.clone(),
self.checkpoint_in_progress.clone() self.checkpoint_in_progress.clone(),
).await?; )
.await?;
cleanup_expired( cleanup_expired(
self.maint_pool.clone(), self.maint_pool.clone(),
Duration::from_secs(600), Duration::from_secs(600),
self.write_in_progress.clone() self.write_in_progress.clone(),
).await )
.await
} }
async fn migrate_up(&self) -> Result<usize> { async fn migrate_up(&self) -> Result<usize> {
@ -294,16 +296,21 @@ impl NostrRepo for SqliteRepo {
// writer was using the database between us // writer was using the database between us
// reading and promoting the connection to a // reading and promoting the connection to a
// write lock. // write lock.
info!("event write failed, DB locked (attempt: {}); sqlite err: {}", info!(
attempts, e.extended_code); "event write failed, DB locked (attempt: {}); sqlite err: {}",
}, attempts, e.extended_code
_ => {return wr;}, );
}
_ => {
return wr;
}
} }
if attempts >= max_write_attempts { if attempts >= max_write_attempts {
return wr; return wr;
} }
} }
}).await?; })
.await?;
self.metrics self.metrics
.write_events .write_events
.observe(start.elapsed().as_secs_f64()); .observe(start.elapsed().as_secs_f64());
@ -865,7 +872,8 @@ fn query_from_filter(f: &ReqFilter) -> (String, Vec<Box<dyn ToSql>>, Option<Stri
let until_clause; let until_clause;
if let Some(ks) = &f.kinds { if let Some(ks) = &f.kinds {
// kind is number, no escaping needed // kind is number, no escaping needed
let str_kinds: Vec<String> = ks.iter().map(std::string::ToString::to_string).collect(); let str_kinds: Vec<String> =
ks.iter().map(std::string::ToString::to_string).collect();
kind_clause = format!("AND kind IN ({})", str_kinds.join(", ")); kind_clause = format!("AND kind IN ({})", str_kinds.join(", "));
} else { } else {
kind_clause = format!(""); kind_clause = format!("");
@ -998,7 +1006,11 @@ pub fn build_pool(
} }
/// Cleanup expired events on a regular basis /// Cleanup expired events on a regular basis
async fn cleanup_expired(pool: SqlitePool, frequency: Duration, write_in_progress: Arc<Mutex<u64>>) -> Result<()> { async fn cleanup_expired(
pool: SqlitePool,
frequency: Duration,
write_in_progress: Arc<Mutex<u64>>,
) -> Result<()> {
tokio::task::spawn(async move { tokio::task::spawn(async move {
loop { loop {
tokio::select! { tokio::select! {
@ -1050,7 +1062,8 @@ pub async fn db_checkpoint_task(
pool: SqlitePool, pool: SqlitePool,
frequency: Duration, frequency: Duration,
write_in_progress: Arc<Mutex<u64>>, write_in_progress: Arc<Mutex<u64>>,
checkpoint_in_progress: Arc<Mutex<u64>>) -> Result<()> { checkpoint_in_progress: Arc<Mutex<u64>>,
) -> Result<()> {
// TODO; use acquire_many on the reader semaphore to stop them from interrupting this. // TODO; use acquire_many on the reader semaphore to stop them from interrupting this.
tokio::task::spawn(async move { tokio::task::spawn(async move {
// WAL size in pages. // WAL size in pages.

View File

@ -4,13 +4,13 @@ use crate::error::Result;
use crate::event::{single_char_tagname, Event}; use crate::event::{single_char_tagname, Event};
use crate::utils::is_lower_hex; use crate::utils::is_lower_hex;
use const_format::formatcp; use const_format::formatcp;
use indicatif::{ProgressBar, ProgressStyle};
use rusqlite::limits::Limit; use rusqlite::limits::Limit;
use rusqlite::params; use rusqlite::params;
use rusqlite::Connection; use rusqlite::Connection;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::time::Instant; use std::time::Instant;
use tracing::{debug, error, info}; use tracing::{debug, error, info};
use indicatif::{ProgressBar, ProgressStyle};
/// Startup DB Pragmas /// Startup DB Pragmas
pub const STARTUP_SQL: &str = r##" pub const STARTUP_SQL: &str = r##"
@ -692,8 +692,7 @@ CREATE INDEX IF NOT EXISTS tag_covering_index ON tag(name,kind,value,created_at,
let start = Instant::now(); let start = Instant::now();
let tx = conn.transaction()?; let tx = conn.transaction()?;
let bar = ProgressBar::new(count.try_into().unwrap()) let bar = ProgressBar::new(count.try_into().unwrap()).with_message("rebuilding tags table");
.with_message("rebuilding tags table");
bar.set_style( bar.set_style(
ProgressStyle::with_template( ProgressStyle::with_template(
"[{elapsed_precise}] {bar:40.white/blue} {pos:>7}/{len:7} [{percent}%] {msg}", "[{elapsed_precise}] {bar:40.white/blue} {pos:>7}/{len:7} [{percent}%] {msg}",
@ -702,7 +701,8 @@ CREATE INDEX IF NOT EXISTS tag_covering_index ON tag(name,kind,value,created_at,
); );
{ {
tx.execute_batch(upgrade_sql)?; tx.execute_batch(upgrade_sql)?;
let mut stmt = tx.prepare("select id, kind, created_at, content from event order by id;")?; let mut stmt =
tx.prepare("select id, kind, created_at, content from event order by id;")?;
let mut tag_rows = stmt.query([])?; let mut tag_rows = stmt.query([])?;
let mut count = 0; let mut count = 0;
while let Some(row) = tag_rows.next()? { while let Some(row) = tag_rows.next()? {
@ -735,7 +735,10 @@ CREATE INDEX IF NOT EXISTS tag_covering_index ON tag(name,kind,value,created_at,
} }
bar.finish(); bar.finish();
tx.commit()?; tx.commit()?;
info!("database schema upgraded v15 -> v16 in {:?}", start.elapsed()); info!(
"database schema upgraded v15 -> v16 in {:?}",
start.elapsed()
);
Ok(16) Ok(16)
} }

View File

@ -6,14 +6,15 @@ use crate::conn;
use crate::db; use crate::db;
use crate::db::SubmittedEvent; use crate::db::SubmittedEvent;
use crate::error::{Error, Result}; use crate::error::{Error, Result};
use crate::event::EventWrapper;
use crate::server::EventWrapper::{WrappedAuth, WrappedEvent};
use crate::event::Event; use crate::event::Event;
use crate::event::EventCmd; use crate::event::EventCmd;
use crate::event::EventWrapper;
use crate::info::RelayInfo; use crate::info::RelayInfo;
use crate::nip05; use crate::nip05;
use crate::notice::Notice; use crate::notice::Notice;
use crate::repo::NostrRepo; use crate::repo::NostrRepo;
use crate::server::Error::CommandUnknownError;
use crate::server::EventWrapper::{WrappedAuth, WrappedEvent};
use crate::subscription::Subscription; use crate::subscription::Subscription;
use futures::SinkExt; use futures::SinkExt;
use futures::StreamExt; use futures::StreamExt;
@ -53,7 +54,6 @@ use tungstenite::error::Error as WsError;
use tungstenite::handshake; use tungstenite::handshake;
use tungstenite::protocol::Message; use tungstenite::protocol::Message;
use tungstenite::protocol::WebSocketConfig; use tungstenite::protocol::WebSocketConfig;
use crate::server::Error::CommandUnknownError;
/// Handle arbitrary HTTP requests, including for `WebSocket` upgrades. /// Handle arbitrary HTTP requests, including for `WebSocket` upgrades.
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
@ -283,15 +283,20 @@ fn create_metrics() -> (Registry, NostrMetrics) {
let query_aborts = IntCounterVec::new( let query_aborts = IntCounterVec::new(
Opts::new("nostr_query_abort_total", "Aborted queries"), Opts::new("nostr_query_abort_total", "Aborted queries"),
vec!["reason"].as_slice(), vec!["reason"].as_slice(),
).unwrap(); )
.unwrap();
let cmd_req = IntCounter::with_opts(Opts::new("nostr_cmd_req_total", "REQ commands")).unwrap(); let cmd_req = IntCounter::with_opts(Opts::new("nostr_cmd_req_total", "REQ commands")).unwrap();
let cmd_event = let cmd_event =
IntCounter::with_opts(Opts::new("nostr_cmd_event_total", "EVENT commands")).unwrap(); IntCounter::with_opts(Opts::new("nostr_cmd_event_total", "EVENT commands")).unwrap();
let cmd_close = let cmd_close =
IntCounter::with_opts(Opts::new("nostr_cmd_close_total", "CLOSE commands")).unwrap(); IntCounter::with_opts(Opts::new("nostr_cmd_close_total", "CLOSE commands")).unwrap();
let cmd_auth = IntCounter::with_opts(Opts::new("nostr_cmd_auth_total", "AUTH commands")).unwrap(); let cmd_auth =
let disconnects = IntCounterVec::new(Opts::new("nostr_disconnects_total", "Client disconnects"), IntCounter::with_opts(Opts::new("nostr_cmd_auth_total", "AUTH commands")).unwrap();
vec!["reason"].as_slice()).unwrap(); let disconnects = IntCounterVec::new(
Opts::new("nostr_disconnects_total", "Client disconnects"),
vec!["reason"].as_slice(),
)
.unwrap();
registry.register(Box::new(query_sub.clone())).unwrap(); registry.register(Box::new(query_sub.clone())).unwrap();
registry.register(Box::new(query_db.clone())).unwrap(); registry.register(Box::new(query_db.clone())).unwrap();
registry.register(Box::new(write_events.clone())).unwrap(); registry.register(Box::new(write_events.clone())).unwrap();
@ -650,9 +655,7 @@ async fn nostr_server(
let unspec = "<unspecified>".to_string(); let unspec = "<unspecified>".to_string();
info!("new client connection (cid: {}, ip: {:?})", cid, conn.ip()); info!("new client connection (cid: {}, ip: {:?})", cid, conn.ip());
let origin = client_info.origin.as_ref().unwrap_or_else(|| &unspec); let origin = client_info.origin.as_ref().unwrap_or_else(|| &unspec);
let user_agent = client_info let user_agent = client_info.user_agent.as_ref().unwrap_or_else(|| &unspec);
.user_agent.as_ref()
.unwrap_or_else(|| &unspec);
info!( info!(
"cid: {}, origin: {:?}, user-agent: {:?}", "cid: {}, origin: {:?}, user-agent: {:?}",
cid, origin, user_agent cid, origin, user_agent
@ -664,8 +667,12 @@ async fn nostr_server(
if settings.authorization.nip42_auth { if settings.authorization.nip42_auth {
conn.generate_auth_challenge(); conn.generate_auth_challenge();
if let Some(challenge) = conn.auth_challenge() { if let Some(challenge) = conn.auth_challenge() {
ws_stream.send( ws_stream
make_notice_message(&Notice::AuthChallenge(challenge.to_string()))).await.ok(); .send(make_notice_message(&Notice::AuthChallenge(
challenge.to_string(),
)))
.await
.ok();
} }
} }

View File

@ -38,7 +38,9 @@ pub fn is_lower_hex(s: &str) -> bool {
} }
pub fn host_str(url: &String) -> Option<String> { pub fn host_str(url: &String) -> Option<String> {
Url::parse(url).ok().and_then(|u| u.host_str().map(|s| s.to_string())) Url::parse(url)
.ok()
.and_then(|u| u.host_str().map(|s| s.to_string()))
} }
#[cfg(test)] #[cfg(test)]