1
0
mirror of https://github.com/scsibug/nostr-rs-relay.git synced 2025-05-05 09:09:57 -04:00

Compare commits

...

7 Commits

Author SHA1 Message Date
Greg Heartsfield
d72af96d5f refactor: rustfmt 2025-02-23 11:23:22 -06:00
Greg Heartsfield
b4234eae25 refactor: clippy suggestions 2025-02-23 11:22:12 -06:00
Greg Heartsfield
d73cde2844 fix: only send events to the nip05 verifier if grpc permits
Prior to this, the NIP05 verifier would receieve metadata events for
GRPC-denied events.  If  the verifier passed, it would try to write
the verification record, but referencing a non-existent event, which
would fail with a SQL constraint error.
2025-02-23 11:04:35 -06:00
Greg Heartsfield
afbd7559e8 improvement: update dependencies
Updating addr2line v0.22.0 -> v0.24.2
Removing adler v1.0.2
Updating allocator-api2 v0.2.18 -> v0.2.21
Updating anstream v0.6.15 -> v0.6.18
Updating anstyle v1.0.8 -> v1.0.10
Updating anstyle-parse v0.2.5 -> v0.2.6
Updating anstyle-query v1.1.1 -> v1.1.2
Updating anstyle-wincon v3.0.4 -> v3.0.7
Updating anyhow v1.0.86 -> v1.0.96
Updating async-executor v1.13.0 -> v1.13.1
Removing async-io v1.13.0
Removing async-io v2.3.4
  Adding async-io v2.4.0
Removing async-lock v2.8.0
Updating async-std v1.12.0 -> v1.13.0
Updating async-stream v0.3.5 -> v0.3.6
Updating async-stream-impl v0.3.5 -> v0.3.6
Updating async-trait v0.1.82 -> v0.1.86
Updating autocfg v1.3.0 -> v1.4.0
Updating backtrace v0.3.73 -> v0.3.74
Updating bitflags v2.6.0 -> v2.8.0
Updating bumpalo v3.16.0 -> v3.17.0
Updating bytes v1.7.1 -> v1.10.0
Updating cc v1.1.16 -> v1.2.15
Updating chrono v0.4.38 -> v0.4.39
Updating clap v4.5.17 -> v4.5.30
Updating clap_builder v4.5.17 -> v4.5.30
Updating clap_derive v4.5.13 -> v4.5.28
Updating clap_lex v0.7.2 -> v0.7.4
Updating colorchoice v1.0.2 -> v1.0.3
Updating console v0.15.8 -> v0.15.10
Updating const_format v0.2.33 -> v0.2.34
Updating const_format_proc_macros v0.2.33 -> v0.2.34
Updating cpufeatures v0.2.14 -> v0.2.17
Updating crossbeam-channel v0.5.13 -> v0.5.14
Updating crossbeam-queue v0.3.11 -> v0.3.12
Updating crossbeam-utils v0.8.20 -> v0.8.21
  Adding displaydoc v0.2.5
Updating encode_unicode v0.3.6 -> v1.0.0
Updating equivalent v1.0.1 -> v1.0.2
Updating errno v0.3.9 -> v0.3.10
Updating event-listener v5.3.1 -> v5.4.0
Updating event-listener-strategy v0.5.2 -> v0.5.3
Removing fastrand v1.9.0
Removing fastrand v2.1.1
  Adding fastrand v2.3.0
Updating flate2 v1.0.33 -> v1.0.35
Updating futures v0.3.30 -> v0.3.31
Updating futures-channel v0.3.30 -> v0.3.31
Updating futures-core v0.3.30 -> v0.3.31
Updating futures-executor v0.3.30 -> v0.3.31
Updating futures-io v0.3.30 -> v0.3.31
Removing futures-lite v1.13.0
Removing futures-lite v2.3.0
  Adding futures-lite v2.6.0
Updating futures-macro v0.3.30 -> v0.3.31
Updating futures-sink v0.3.30 -> v0.3.31
Updating futures-task v0.3.30 -> v0.3.31
Updating futures-util v0.3.30 -> v0.3.31
  Adding getrandom v0.3.1
Updating gimli v0.29.0 -> v0.31.1
Updating gloo-timers v0.2.6 -> v0.3.0
  Adding hashbrown v0.15.2
Removing hermit-abi v0.3.9
Updating home v0.5.9 -> v0.5.11
Updating httparse v1.9.4 -> v1.10.0
Updating hyper v0.14.30 -> v0.14.32 (available: v1.6.0)
Updating iana-time-zone v0.1.60 -> v0.1.61
  Adding icu_collections v1.5.0
  Adding icu_locid v1.5.0
  Adding icu_locid_transform v1.5.0
  Adding icu_locid_transform_data v1.5.0
  Adding icu_normalizer v1.5.0
  Adding icu_normalizer_data v1.5.0
  Adding icu_properties v1.5.1
  Adding icu_properties_data v1.5.0
  Adding icu_provider v1.5.0
  Adding icu_provider_macros v1.5.0
Updating idna v0.5.0 -> v1.0.3
  Adding idna_adapter v1.2.0
Updating indexmap v2.5.0 -> v2.7.1
Updating indicatif v0.17.8 -> v0.17.11
Updating inout v0.1.3 -> v0.1.4
Removing io-lifetimes v1.0.11
Updating itoa v1.0.11 -> v1.0.14
Updating js-sys v0.3.70 -> v0.3.77
Updating libc v0.2.158 -> v0.2.170
Removing linux-raw-sys v0.3.8
Removing linux-raw-sys v0.4.14
  Adding linux-raw-sys v0.4.15
  Adding litemap v0.7.4
Updating log v0.4.22 -> v0.4.26
Removing miniz_oxide v0.7.4
Removing miniz_oxide v0.8.0
  Adding miniz_oxide v0.8.5
Updating mio v1.0.2 -> v1.0.3
Updating object v0.36.4 -> v0.36.7
Updating once_cell v1.19.0 -> v1.20.3
Updating openssl-probe v0.1.5 -> v0.1.6
Updating parking v2.2.0 -> v2.2.1
Updating pathdiff v0.2.1 -> v0.2.3
Updating pest v2.7.12 -> v2.7.15
Updating pest_derive v2.7.12 -> v2.7.15
Updating pest_generator v2.7.12 -> v2.7.15
Updating pest_meta v2.7.12 -> v2.7.15
Updating pin-project v1.1.5 -> v1.1.9
Updating pin-project-internal v1.1.5 -> v1.1.9
Updating pin-project-lite v0.2.14 -> v0.2.16
Updating pkg-config v0.3.30 -> v0.3.31
Removing polling v2.8.0
Removing polling v3.7.3
  Adding polling v3.7.4
Updating portable-atomic v1.7.0 -> v1.10.0
Updating proc-macro2 v1.0.86 -> v1.0.93
Updating quote v1.0.37 -> v1.0.38
Updating redox_syscall v0.5.3 -> v0.5.9
Updating regex v1.10.6 -> v1.11.1
Updating regex-automata v0.4.7 -> v0.4.9
Updating regex-syntax v0.8.4 -> v0.8.5
Updating ring v0.17.8 -> v0.17.11
Removing rustix v0.37.27
Removing rustix v0.38.36
  Adding rustix v0.38.44
Updating rustversion v1.0.17 -> v1.0.19
Updating ryu v1.0.18 -> v1.0.19
Updating schannel v0.1.23 -> v0.1.27
Updating security-framework-sys v2.11.1 -> v2.14.0
Updating serde v1.0.209 -> v1.0.218
Updating serde_derive v1.0.209 -> v1.0.218
Updating serde_json v1.0.128 -> v1.0.139
Updating smallvec v1.13.2 -> v1.14.0
Removing socket2 v0.4.10
Removing socket2 v0.5.7
  Adding socket2 v0.5.8
Removing spin v0.9.8
  Adding stable_deref_trait v1.2.0
Updating syn v2.0.77 -> v2.0.98
  Adding synstructure v0.13.1
Updating tempfile v3.12.0 -> v3.17.1
Removing thiserror v1.0.63
  Adding thiserror v1.0.69 (available: v2.0.11)
  Adding thiserror v2.0.11
Removing thiserror-impl v1.0.63
  Adding thiserror-impl v1.0.69
  Adding thiserror-impl v2.0.11
Updating time v0.3.36 -> v0.3.37
Updating time-macros v0.2.18 -> v0.2.19
  Adding tinystr v0.7.6
Updating tinyvec v1.8.0 -> v1.8.1
Updating tokio v1.40.0 -> v1.43.0
Updating tokio-macros v2.4.0 -> v2.5.0
Updating tokio-stream v0.1.16 -> v0.1.17
Updating tokio-util v0.7.12 -> v0.7.13
Updating tracing v0.1.40 -> v0.1.41
Updating tracing-attributes v0.1.27 -> v0.1.28
Updating tracing-core v0.1.32 -> v0.1.33
Updating tracing-subscriber v0.3.18 -> v0.3.19
Updating typenum v1.17.0 -> v1.18.0
Updating ucd-trie v0.1.6 -> v0.1.7
Updating unicode-bidi v0.3.15 -> v0.3.18
Updating unicode-ident v1.0.12 -> v1.0.17
Updating unicode-normalization v0.1.23 -> v0.1.24
Updating unicode-properties v0.1.2 -> v0.1.3
Updating unicode-segmentation v1.11.0 -> v1.12.0
Updating unicode-width v0.1.13 -> v0.2.0
Updating unicode-xid v0.2.5 -> v0.2.6
Updating url v2.5.2 -> v2.5.4
  Adding utf16_iter v1.0.5
  Adding utf8_iter v1.0.4
Updating uuid v1.10.0 -> v1.14.0
Updating valuable v0.1.0 -> v0.1.1
Updating value-bag v1.9.0 -> v1.10.0
Removing waker-fn v1.2.0
  Adding wasi v0.13.3+wasi-0.2.2
Updating wasm-bindgen v0.2.93 -> v0.2.100
Updating wasm-bindgen-backend v0.2.93 -> v0.2.100
Updating wasm-bindgen-futures v0.4.43 -> v0.4.50
Updating wasm-bindgen-macro v0.2.93 -> v0.2.100
Updating wasm-bindgen-macro-support v0.2.93 -> v0.2.100
Updating wasm-bindgen-shared v0.2.93 -> v0.2.100
Updating web-sys v0.3.70 -> v0.3.77
  Adding web-time v1.1.0
Removing windows-sys v0.48.0
Removing windows-targets v0.48.5
Removing windows_aarch64_gnullvm v0.48.5
Removing windows_aarch64_msvc v0.48.5
Removing windows_i686_gnu v0.48.5
Removing windows_i686_msvc v0.48.5
Removing windows_x86_64_gnu v0.48.5
Removing windows_x86_64_gnullvm v0.48.5
Removing windows_x86_64_msvc v0.48.5
  Adding wit-bindgen-rt v0.33.0
  Adding write16 v1.0.0
  Adding writeable v0.5.5
  Adding yoke v0.7.5
  Adding yoke-derive v0.7.5
  Adding zerofrom v0.1.5
  Adding zerofrom-derive v0.1.5
  Adding zerovec v0.10.4
  Adding zerovec-derive v0.10.3
2025-02-23 11:01:27 -06:00
laanwj
a6b48620fd fix: sqlite schema comment
`event_hash` is the raw SHA256 hash of the event, not 4-byte hash.
2024-10-19 07:12:11 -05:00
Greg Heartsfield
d71f5cb029 docs: remove reference to defunct anigma channel 2024-10-04 16:54:10 -05:00
Greg Heartsfield
1ed8cc08cc docs: point github CI badge to main repo 2024-10-04 08:34:42 -05:00
14 changed files with 791 additions and 659 deletions

1302
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -11,7 +11,7 @@ mirrored on [GitHub](https://github.com/scsibug/nostr-rs-relay).
[![builds.sr.ht status](https://builds.sr.ht/~gheartsfield/nostr-rs-relay/commits/master.svg)](https://builds.sr.ht/~gheartsfield/nostr-rs-relay/commits/master?)
![Github CI](https://github.com/schlunsen/nostr-rs-relay/actions/workflows/ci.yml/badge.svg)
![Github CI](https://github.com/scsibug/nostr-rs-relay/actions/workflows/ci.yml/badge.svg)
## Features
@ -158,10 +158,6 @@ Proxy](docs/reverse-proxy.md).
For development discussions, please feel free to use the [sourcehut
mailing list](https://lists.sr.ht/~gheartsfield/nostr-rs-relay-devel).
Or, drop by the [Nostr Telegram Channel](https://t.me/nostr_protocol).
To chat about `nostr-rs-relay` on `nostr` itself; visit our channel on [anigma](https://anigma.io/) or another client that supports [NIP-28](https://github.com/nostr-protocol/nips/blob/master/28.md) chats:
* `2ad246a094fee48c6e455dd13d759d5f41b5a233120f5719d81ebc1935075194`
License
---

@ -15,7 +15,6 @@ use tracing::info;
/// Bulk load JSONL data from STDIN to the database specified in config.toml (or ./nostr.db as a default).
/// The database must already exist, this will not create a new one.
/// Tested against schema v13.
pub fn main() -> Result<()> {
let _trace_sub = tracing_subscriber::fmt::try_init();
println!("Nostr-rs-relay Bulk Loader");

@ -281,15 +281,6 @@ pub async fn db_writer(
}
}
// send any metadata events to the NIP-05 verifier
if nip05_active && event.is_kind_metadata() {
// we are sending this prior to even deciding if we
// persist it. this allows the nip05 module to
// inspect it, update if necessary, or persist a new
// event and broadcast it itself.
metadata_tx.send(event.clone()).ok();
}
// get a validation result for use in verification and GPRC
let validation = if nip05_active {
Some(repo.get_latest_user_verification(&event.pubkey).await)
@ -390,6 +381,15 @@ pub async fn db_writer(
}
}
// send any metadata events to the NIP-05 verifier
if nip05_active && event.is_kind_metadata() {
// we are sending this prior to even deciding if we
// persist it. this allows the nip05 module to
// inspect it, update if necessary, or persist a new
// event and broadcast it itself.
metadata_tx.send(event.clone()).ok();
}
// TODO: cache recent list of authors to remove a DB call.
let start = Instant::now();
if event.is_ephemeral() {

@ -472,12 +472,8 @@ mod tests {
let mut event = Event::simple_event();
event.tags = vec![vec!["e".to_owned(), "foo".to_owned()]];
event.build_index();
assert!(
event.generic_tag_val_intersect(
'e',
&HashSet::from(["foo".to_owned(), "bar".to_owned()])
)
);
assert!(event
.generic_tag_val_intersect('e', &HashSet::from(["foo".to_owned(), "bar".to_owned()])));
}
#[test]

@ -121,7 +121,7 @@ fn body_contains_user(username: &str, address: &str, bytes: &hyper::body::Bytes)
// get the pubkey for the requested user
let check_name = names_map.get(username).and_then(serde_json::Value::as_str);
// ensure the address is a match
Ok(check_name.map_or(false, |x| x == address))
Ok(check_name == Some(address))
}
impl Verifier {
@ -243,7 +243,11 @@ impl Verifier {
let response_content_length = match response.body().size_hint().upper() {
Some(v) => v,
None => {
info!("missing content length header for account {:?} at URL: {}", nip.to_string(), url);
info!(
"missing content length header for account {:?} at URL: {}",
nip.to_string(),
url
);
return Ok(UserWebVerificationStatus::Unknown);
}
};

@ -25,7 +25,9 @@ impl EventResultStatus {
pub fn to_bool(&self) -> bool {
match self {
Self::Duplicate | Self::Saved => true,
Self::Invalid | Self::Blocked | Self::RateLimited | Self::Error | Self::Restricted => false,
Self::Invalid | Self::Blocked | Self::RateLimited | Self::Error | Self::Restricted => {
false
}
}
}

@ -38,7 +38,7 @@ impl ClnRestPaymentProcessor {
.ok_or(ConfigError::NotFound("rune_path".to_string()))?;
let rune = String::from_utf8(fs::read(rune_path)?)
.map_err(|_| ConfigError::Message("Rune should be UTF8".to_string()))?;
let mut rune_header = HeaderValue::from_str(&rune.trim())
let mut rune_header = HeaderValue::from_str(rune.trim())
.map_err(|_| ConfigError::Message("Invalid Rune header".to_string()))?;
rune_header.set_sensitive(true);

@ -55,12 +55,12 @@ pub enum InvoiceStatus {
Expired,
}
impl ToString for InvoiceStatus {
fn to_string(&self) -> String {
impl std::fmt::Display for InvoiceStatus {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
InvoiceStatus::Paid => "Paid".to_string(),
InvoiceStatus::Unpaid => "Unpaid".to_string(),
InvoiceStatus::Expired => "Expired".to_string(),
InvoiceStatus::Paid => write!(f, "Paid"),
InvoiceStatus::Unpaid => write!(f, "Unpaid"),
InvoiceStatus::Expired => write!(f, "Expired"),
}
}
}

@ -177,28 +177,25 @@ ON CONFLICT (id) DO NOTHING"#,
let tag_val = &tag[1];
// only single-char tags are searchable
let tag_char_opt = single_char_tagname(tag_name);
match &tag_char_opt {
Some(_) => {
// if tag value is lowercase hex;
if is_lower_hex(tag_val) && (tag_val.len() % 2 == 0) {
sqlx::query("INSERT INTO tag (event_id, \"name\", value, value_hex) VALUES($1, $2, NULL, $3) \
ON CONFLICT (event_id, \"name\", value, value_hex) DO NOTHING")
if tag_char_opt.is_some() {
// if tag value is lowercase hex;
if is_lower_hex(tag_val) && (tag_val.len() % 2 == 0) {
sqlx::query("INSERT INTO tag (event_id, \"name\", value, value_hex) VALUES($1, $2, NULL, $3) \
ON CONFLICT (event_id, \"name\", value, value_hex) DO NOTHING")
.bind(&id_blob)
.bind(tag_name)
.bind(hex::decode(tag_val).ok())
.execute(&mut tx)
.await?;
} else {
sqlx::query("INSERT INTO tag (event_id, \"name\", value, value_hex) VALUES($1, $2, $3, NULL) \
ON CONFLICT (event_id, \"name\", value, value_hex) DO NOTHING")
.bind(tag_name)
.bind(hex::decode(tag_val).ok())
.execute(&mut tx)
.await?;
} else {
sqlx::query("INSERT INTO tag (event_id, \"name\", value, value_hex) VALUES($1, $2, $3, NULL) \
ON CONFLICT (event_id, \"name\", value, value_hex) DO NOTHING")
.bind(&id_blob)
.bind(tag_name)
.bind(tag_val.as_bytes())
.execute(&mut tx)
.await?;
}
.bind(tag_name)
.bind(tag_val.as_bytes())
.execute(&mut tx)
.await?;
}
None => {}
}
}
}

@ -156,14 +156,11 @@ impl SqliteRepo {
let tagval = &tag[1];
// only single-char tags are searchable
let tagchar_opt = single_char_tagname(tagname);
match &tagchar_opt {
Some(_) => {
tx.execute(
"INSERT OR IGNORE INTO tag (event_id, name, value, kind, created_at) VALUES (?1, ?2, ?3, ?4, ?5)",
params![ev_id, &tagname, &tagval, e.kind, e.created_at],
)?;
}
None => {}
if tagchar_opt.is_some() {
tx.execute(
"INSERT OR IGNORE INTO tag (event_id, name, value, kind, created_at) VALUES (?1, ?2, ?3, ?4, ?5)",
params![ev_id, &tagname, &tagval, e.kind, e.created_at],
)?;
}
}
}

@ -40,7 +40,7 @@ PRAGMA user_version = {};
-- Event Table
CREATE TABLE IF NOT EXISTS event (
id INTEGER PRIMARY KEY,
event_hash BLOB NOT NULL, -- 4-byte hash
event_hash BLOB NOT NULL, -- 32-byte SHA256 hash
first_seen INTEGER NOT NULL, -- when the event was first seen (not authored!) (seconds since 1970)
created_at INTEGER NOT NULL, -- when the event was authored
expires_at INTEGER, -- when the event expires and may be deleted

@ -202,7 +202,7 @@ async fn handle_web_request(
.header("Content-Type", "text/html; charset=UTF-8")
.body(Body::from(file_content))
.expect("request builder"));
},
}
Err(err) => {
error!("Failed to read relay_page file: {}. Will use default", err);
}
@ -920,7 +920,7 @@ pub fn start_server(settings: &Settings, shutdown_rx: MpscReceiver<()>) -> Resul
info!("starting payment process ...");
p.run().await;
});
},
}
Err(e) => {
error!("Failed to start payment process {e}");
std::process::exit(1);

@ -45,8 +45,8 @@ pub struct ReqFilter {
impl Serialize for ReqFilter {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
where
S: Serializer,
{
let mut map = serializer.serialize_map(None)?;
if let Some(ids) = &self.ids {
@ -80,8 +80,8 @@ impl Serialize for ReqFilter {
impl<'de> Deserialize<'de> for ReqFilter {
fn deserialize<D>(deserializer: D) -> Result<ReqFilter, D::Error>
where
D: Deserializer<'de>,
where
D: Deserializer<'de>,
{
let received: Value = Deserialize::deserialize(deserializer)?;
let filter = received.as_object().ok_or_else(|| {
@ -184,8 +184,8 @@ impl<'de> Deserialize<'de> for Subscription {
/// Custom deserializer for subscriptions, which have a more
/// complex structure than the other message types.
fn deserialize<D>(deserializer: D) -> Result<Subscription, D::Error>
where
D: Deserializer<'de>,
where
D: Deserializer<'de>,
{
let mut v: Value = Deserialize::deserialize(deserializer)?;
// this should be a 3-or-more element array.
@ -673,11 +673,26 @@ mod tests {
#[test]
fn is_scraper() -> Result<()> {
assert!(serde_json::from_str::<Subscription>(r#"["REQ","some-id",{"kinds": [1984],"since": 123,"limit":1}]"#)?.is_scraper());
assert!(serde_json::from_str::<Subscription>(r#"["REQ","some-id",{"kinds": [1984]},{"kinds": [1984],"authors":["aaaa"]}]"#)?.is_scraper());
assert!(!serde_json::from_str::<Subscription>(r#"["REQ","some-id",{"kinds": [1984],"authors":["aaaa"]}]"#)?.is_scraper());
assert!(!serde_json::from_str::<Subscription>(r#"["REQ","some-id",{"ids": ["aaaa"]}]"#)?.is_scraper());
assert!(!serde_json::from_str::<Subscription>(r##"["REQ","some-id",{"#p": ["aaaa"],"kinds":[1,4]}]"##)?.is_scraper());
assert!(serde_json::from_str::<Subscription>(
r#"["REQ","some-id",{"kinds": [1984],"since": 123,"limit":1}]"#
)?
.is_scraper());
assert!(serde_json::from_str::<Subscription>(
r#"["REQ","some-id",{"kinds": [1984]},{"kinds": [1984],"authors":["aaaa"]}]"#
)?
.is_scraper());
assert!(!serde_json::from_str::<Subscription>(
r#"["REQ","some-id",{"kinds": [1984],"authors":["aaaa"]}]"#
)?
.is_scraper());
assert!(
!serde_json::from_str::<Subscription>(r#"["REQ","some-id",{"ids": ["aaaa"]}]"#)?
.is_scraper()
);
assert!(!serde_json::from_str::<Subscription>(
r##"["REQ","some-id",{"#p": ["aaaa"],"kinds":[1,4]}]"##
)?
.is_scraper());
Ok(())
}
}