mirror of
https://relay.ngit.dev/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp.git
synced 2026-09-14 04:45:07 +00:00
build: upgrade rust-nostr to stable 0.45.0
Move the relay and audit workspace from the alpha.8 prerelease to the published stable rust-nostr 0.45 line so the embedded relay receives the upstream NEG-OPEN fix through a supported release. Adapt removed Alphabet constructors to the stable named SingleLetterTag constants and replace the removed all-zero EventId helper with an explicit zero byte array. Raise grasp-audit's declared MSRV to the 1.85 required by rust-nostr 0.45 and refresh the shared lockfile. This commit deliberately excludes any pagination-policy changes; the stable dependency revealed a reproducible failure in the existing large REQ+EOSE concurrency scenario that requires separate diagnosis before this upgrade is merge-ready. Validated with workspace all-target compilation and both Nix package builds. The NIP-77 and NEG-concurrency scenarios pass; the full suite is blocked only by the separately noted REQ+EOSE historic-pagination regression.
This commit is contained in:
+6
-1
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
|
||||
- Upgraded the rust-nostr crates from `0.45.0-alpha.8` to the stable `0.45.0`
|
||||
release, including the upstream NEG-OPEN handling fix.
|
||||
|
||||
### Security
|
||||
|
||||
- Restricted event-directed sync targets to globally reachable endpoints.
|
||||
@@ -57,7 +62,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
IDs that fail with `Invalid input length 64` - closed the session, forcing
|
||||
clients to reconnect and re-subscribe. Invalid messages are now answered with
|
||||
a `NOTICE` and the connection stays open. Fixed upstream in rust-nostr and
|
||||
picked up by upgrading to `0.45.0-alpha.8`.
|
||||
picked up by upgrading to the stable `0.45.0` release.
|
||||
- Fixed proactive sync losing repository events when public relays cap active
|
||||
subscriptions. Compatible GRASP filters now share bounded NIP-01 REQs while
|
||||
retaining per-filter history pagination.
|
||||
|
||||
Generated
+58
-24
@@ -1,6 +1,6 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
@@ -114,9 +114,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-wsocket"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efa9ef232c1731ddbe4a306b5b5dcf9e50a924d6bd086d4784939d14f8e78daa"
|
||||
checksum = "2c713e1f14c7b82e32ea159af1c6e2f070cfadbdf23fb2512acce9af0a26f1a2"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"futures-util",
|
||||
@@ -156,11 +156,26 @@ version = "2.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90dbd31c98227229239363921e60fcf5e558e43ec69094d46fc4996f08d1d5bc"
|
||||
dependencies = [
|
||||
"bitcoin_hashes",
|
||||
"bitcoin_hashes 0.14.100",
|
||||
"serde",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitcoin-consensus-encoding"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "207311705279250ba465076a1bac4b1ac982855fff73fc5f67e22158ac58cdc9"
|
||||
dependencies = [
|
||||
"bitcoin-internals",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitcoin-internals"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d573f4cf32996a8dce612e4348cece65a241f1882ed594047c9ba348e8869fa5"
|
||||
|
||||
[[package]]
|
||||
name = "bitcoin-io"
|
||||
version = "0.1.100"
|
||||
@@ -174,7 +189,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c9901a56e133a1fc86eeb1113e2591f45f4682451ca893bff494d2f88918e3f"
|
||||
dependencies = [
|
||||
"bitcoin-io",
|
||||
"hex-conservative",
|
||||
"hex-conservative 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitcoin_hashes"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5304e53726dbe5f93141535e102ed97b5bf4714fbecefdda8f9fb98d7fdaff0e"
|
||||
dependencies = [
|
||||
"bitcoin-consensus-encoding",
|
||||
"bitcoin-internals",
|
||||
"hex-conservative 1.2.0",
|
||||
"serde",
|
||||
]
|
||||
|
||||
@@ -880,6 +906,15 @@ dependencies = [
|
||||
"arrayvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex-conservative"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35431185f361ccf3ffc58254628af5f1f5d5f28531da2e02e5d6c82bbc282a10"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "1.4.2"
|
||||
@@ -1274,7 +1309,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"base64",
|
||||
"bitcoin_hashes",
|
||||
"bitcoin_hashes 0.14.100",
|
||||
"clap",
|
||||
"dashmap",
|
||||
"dotenvy",
|
||||
@@ -1306,14 +1341,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nostr"
|
||||
version = "0.45.0-alpha.8"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0334ad7a19f229983c808840f65d813d09c7fc030775db5d325abffa1295fe6c"
|
||||
checksum = "7279feef28d43a04c0b3529acd4fea923ac816729bd643191b292296f1f6cc13"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bech32",
|
||||
"bip39",
|
||||
"bitcoin_hashes",
|
||||
"bitcoin_hashes 1.2.0",
|
||||
"cbc",
|
||||
"chacha20 0.9.1",
|
||||
"chacha20poly1305",
|
||||
@@ -1330,21 +1365,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nostr-database"
|
||||
version = "0.45.0-alpha.8"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82e3827aa36205889d9950bb07e9ab9380f7881ab3b059956f2d87651fa64281"
|
||||
checksum = "81c7ffd33114d62c737dd2b8f77ffec4693c64b7a1c6090cab0d0009f9986e22"
|
||||
dependencies = [
|
||||
"btreecap",
|
||||
"flatbuffers",
|
||||
"nostr",
|
||||
"opaquerr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nostr-gossip"
|
||||
version = "0.45.0-alpha.8"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4696e01b02eb84daa6d8419f529c6e6f3063b742a54925dc0300a3230871477"
|
||||
checksum = "fa07539e52a71cb91fe0d693facaa298f03fcf9edcd66a521094e18e286e2336"
|
||||
dependencies = [
|
||||
"nostr",
|
||||
"opaquerr",
|
||||
@@ -1352,11 +1385,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nostr-lmdb"
|
||||
version = "0.45.0-alpha.8"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2832ab8243313733630c90208f36b9859dd939b13c745c977f2a0c465b5ec117"
|
||||
checksum = "b7a313418ff58bfa444ba4b71200ff8fe2d3eb31f2b5d0d8fdb7f5e60a703d31"
|
||||
dependencies = [
|
||||
"async-utility",
|
||||
"flatbuffers",
|
||||
"flume",
|
||||
"heed",
|
||||
"nostr",
|
||||
@@ -1367,9 +1401,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nostr-memory"
|
||||
version = "0.45.0-alpha.8"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1688a4bfea60f72ca212c55f23cc9f068bfb5e787829d85fc7f689c3df9de842"
|
||||
checksum = "1a827de4b11c4f2b235eabe37f1a67460db68e453606f4755e1ac5a522347a86"
|
||||
dependencies = [
|
||||
"btreecap",
|
||||
"nostr",
|
||||
@@ -1379,9 +1413,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nostr-sdk"
|
||||
version = "0.45.0-alpha.8"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2ffff8a1d69b9828574ead3b34d615bffe4c75ff3e3335a28f111867c7f7cdd"
|
||||
checksum = "359881fbaded2d19a5003609673744b8b68c4973817598eb0e262d049ec9c3f3"
|
||||
dependencies = [
|
||||
"async-utility",
|
||||
"async-wsocket",
|
||||
@@ -1430,9 +1464,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
||||
|
||||
[[package]]
|
||||
name = "opaquerr"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e55a7b7f0accc9fdd8e514f122a697adf824d55de481ca26c31ff8f9a8e813c5"
|
||||
checksum = "4f933a4265d5cdad61d19bbdfc972ea5726d56cd8d3d57b8f2d3c365dd42bee9"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
@@ -1920,7 +1954,7 @@ version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252"
|
||||
dependencies = [
|
||||
"bitcoin_hashes",
|
||||
"bitcoin_hashes 0.14.100",
|
||||
"rand 0.8.6",
|
||||
"secp256k1-sys",
|
||||
]
|
||||
|
||||
+7
-12
@@ -18,23 +18,18 @@ http-body-util = "0.1"
|
||||
|
||||
# Nostr
|
||||
#
|
||||
# These are prerelease (alpha) requirements and are pinned exactly with `=`.
|
||||
# Cargo treats `"0.45.0-alpha.8"` as `^0.45.0-alpha.8`, which accepts *any*
|
||||
# later prerelease of 0.45.0 even though alphas carry no compatibility
|
||||
# guarantee (alpha.4 deleted the `nostr-relay-builder` crate outright). Exact
|
||||
# pins keep lockfile-less builds - `cargo install`, downstream consumers of the
|
||||
# `ngit_grasp` library - on the version this tree is tested against.
|
||||
# Relax to caret requirements once 0.45.0 is released.
|
||||
nostr = "=0.45.0-alpha.8"
|
||||
# The stable 0.45 series contains the upstream NEG-OPEN handling fix used by
|
||||
# the embedded relay. Caret requirements accept compatible patch releases.
|
||||
nostr = "0.45.0"
|
||||
# `local-relay` carries the embedded relay implementation, previously the
|
||||
# separate `nostr-relay-builder` crate.
|
||||
nostr-sdk = { version = "=0.45.0-alpha.8", features = ["local-relay"] }
|
||||
nostr-lmdb = "=0.45.0-alpha.8"
|
||||
nostr-memory = "=0.45.0-alpha.8"
|
||||
nostr-sdk = { version = "0.45.0", features = ["local-relay"] }
|
||||
nostr-lmdb = "0.45.0"
|
||||
nostr-memory = "0.45.0"
|
||||
|
||||
# Utilities
|
||||
# SHA-1 for the `Sec-WebSocket-Accept` handshake. `nostr` uses this same crate
|
||||
# internally but stopped re-exporting it as `nostr::hashes` in 0.45.0-alpha.8,
|
||||
# internally but stopped re-exporting it as `nostr::hashes` in 0.45,
|
||||
# so depend on it directly rather than pulling in a second hash implementation.
|
||||
bitcoin_hashes = "0.14"
|
||||
futures-util = "0.3"
|
||||
|
||||
@@ -71,7 +71,7 @@ advertised, and many relays omit `limitation` entirely. Consequence: filter
|
||||
sizing cannot be negotiated per relay — it must be statically conservative,
|
||||
with reactive fallback as the backstop.
|
||||
|
||||
### Our own embedded relay (nostr-sdk `LocalRelay`, 0.45.0-alpha.8)
|
||||
### Our own embedded relay (nostr-sdk `LocalRelay`, 0.45.0)
|
||||
|
||||
- `max_reqs` = 500, enforced for REQ only (`src/nostr/builder.rs`).
|
||||
- Negentropy: **no concurrency limit at all** (upstream `TODO`), 60000-byte
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "grasp-audit"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.75"
|
||||
rust-version = "1.85"
|
||||
description = "Audit and compliance testing tool for GRASP protocol implementations"
|
||||
license = "MIT"
|
||||
repository = "https://gitworkshop.dev/danconwaydev.com/ngit-grasp"
|
||||
@@ -13,8 +13,7 @@ path = "src/bin/grasp-audit.rs"
|
||||
|
||||
[dependencies]
|
||||
# Nostr
|
||||
# Pinned exactly: see the rationale in the workspace root Cargo.toml.
|
||||
nostr-sdk = "=0.45.0-alpha.8"
|
||||
nostr-sdk = "0.45.0"
|
||||
|
||||
# Async
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
@@ -434,12 +434,12 @@ impl AuditClient {
|
||||
|
||||
/// Query events, optionally filtered to this audit run
|
||||
pub async fn query(&self, mut filter: Filter) -> Result<Vec<Event>> {
|
||||
use nostr_sdk::prelude::{Alphabet, SingleLetterTag};
|
||||
use nostr_sdk::prelude::SingleLetterTag;
|
||||
|
||||
if self.config.mode == AuditMode::Isolated {
|
||||
// In Isolated mode, only see our own audit events
|
||||
// Filter by "t" tags (hashtags)
|
||||
let t_tag = SingleLetterTag::lowercase(Alphabet::T);
|
||||
let t_tag = SingleLetterTag::LOWERCASE_T;
|
||||
filter = filter
|
||||
.custom_tag(t_tag, "grasp-audit-test-event")
|
||||
.custom_tag(t_tag, format!("audit-{}", self.config.run_id));
|
||||
|
||||
@@ -913,7 +913,7 @@ pub async fn run_probe_with_options(
|
||||
let r2 = if r1.is_ok() {
|
||||
client.send_event(state.clone()).await
|
||||
} else {
|
||||
r1.map(|_| EventId::all_zeros())
|
||||
r1.map(|_| EventId::from_byte_array([0; 32]))
|
||||
};
|
||||
r2
|
||||
}
|
||||
@@ -1482,9 +1482,7 @@ pub async fn run_probe_with_options(
|
||||
// The relay only serves authorized state events (owner + full
|
||||
// recursive maintainer chain already resolved by the relay).
|
||||
let state_filter = Filter::new().kind(Kind::RepoState).custom_tag(
|
||||
nostr_sdk::prelude::SingleLetterTag::lowercase(
|
||||
nostr_sdk::prelude::Alphabet::D,
|
||||
),
|
||||
nostr_sdk::prelude::SingleLetterTag::LOWERCASE_D,
|
||||
ann_id.clone(),
|
||||
);
|
||||
let state_events = client
|
||||
|
||||
@@ -261,7 +261,7 @@ impl Nip01SmokeTests {
|
||||
|
||||
// Create event JSON with corrupted ID
|
||||
let invalid_event_json = serde_json::json!({
|
||||
"id": EventId::all_zeros().to_hex(), // Wrong ID!
|
||||
"id": EventId::from_byte_array([0; 32]).to_hex(), // Wrong ID!
|
||||
"pubkey": event.pubkey.to_hex(),
|
||||
"created_at": event.created_at.as_secs(),
|
||||
"kind": event.kind.as_u16(),
|
||||
|
||||
@@ -214,10 +214,7 @@ pub async fn fetch_repository_data_excluding_purgatory(
|
||||
) -> Result<RepositoryData> {
|
||||
let filter = Filter::new()
|
||||
.kinds([Kind::GitRepoAnnouncement, Kind::RepoState])
|
||||
.custom_tag(
|
||||
SingleLetterTag::lowercase(Alphabet::D),
|
||||
identifier.to_string(),
|
||||
);
|
||||
.custom_tag(SingleLetterTag::LOWERCASE_D, identifier.to_string());
|
||||
|
||||
let events: Vec<Event> = database
|
||||
.query(filter)
|
||||
@@ -770,10 +767,7 @@ impl AuthorizationContext {
|
||||
pub fn create_filter(identifier: &str) -> Filter {
|
||||
Filter::new()
|
||||
.kinds([Kind::GitRepoAnnouncement, Kind::RepoState])
|
||||
.custom_tag(
|
||||
SingleLetterTag::lowercase(Alphabet::D),
|
||||
identifier.to_string(),
|
||||
)
|
||||
.custom_tag(SingleLetterTag::LOWERCASE_D, identifier.to_string())
|
||||
}
|
||||
|
||||
/// Get the latest authorized state for a repository
|
||||
|
||||
@@ -691,10 +691,9 @@ impl Nip34WritePolicy {
|
||||
/// chain apply its preferred state before considering older candidates,
|
||||
/// without requiring an invitee-authored state event or push.
|
||||
async fn reconcile_stored_state_events_for_identifier(&self, identifier: &str) {
|
||||
let filter = Filter::new().kind(Kind::RepoState).custom_tag(
|
||||
SingleLetterTag::lowercase(Alphabet::D),
|
||||
identifier.to_string(),
|
||||
);
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::RepoState)
|
||||
.custom_tag(SingleLetterTag::LOWERCASE_D, identifier.to_string());
|
||||
let mut states: Vec<Event> = match self.ctx.database.query(filter).await {
|
||||
Ok(events) => events.into_iter().collect(),
|
||||
Err(error) => {
|
||||
|
||||
@@ -4,9 +4,7 @@ use std::path::PathBuf;
|
||||
|
||||
use flate2::write::GzEncoder;
|
||||
use flate2::Compression;
|
||||
use nostr_sdk::prelude::{
|
||||
Alphabet, Event, EventId, Filter, Kind, PublicKey, SingleLetterTag, Timestamp,
|
||||
};
|
||||
use nostr_sdk::prelude::{Event, EventId, Filter, Kind, PublicKey, SingleLetterTag, Timestamp};
|
||||
use tar::Builder as TarBuilder;
|
||||
|
||||
use super::{
|
||||
@@ -278,10 +276,7 @@ impl DeletionPolicy {
|
||||
let kind = Kind::from(kind_num);
|
||||
let mut filter = Filter::new().kind(kind).author(*author);
|
||||
if kind.is_addressable() {
|
||||
filter = filter.custom_tag(
|
||||
SingleLetterTag::lowercase(Alphabet::D),
|
||||
identifier.to_string(),
|
||||
);
|
||||
filter = filter.custom_tag(SingleLetterTag::LOWERCASE_D, identifier.to_string());
|
||||
}
|
||||
// Per NIP-09, only versions up to the deletion's created_at are deleted.
|
||||
filter = filter.until(deletion_created_at);
|
||||
@@ -478,10 +473,7 @@ impl DeletionPolicy {
|
||||
let remaining_filter = Filter::new()
|
||||
.kind(Kind::GitRepoAnnouncement)
|
||||
.author(scope.owner)
|
||||
.custom_tag(
|
||||
SingleLetterTag::lowercase(Alphabet::D),
|
||||
scope.identifier.clone(),
|
||||
);
|
||||
.custom_tag(SingleLetterTag::LOWERCASE_D, scope.identifier.clone());
|
||||
|
||||
match self.ctx.database.query(remaining_filter).await {
|
||||
Ok(remaining) if !remaining.is_empty() => {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
|
||||
use nostr_sdk::prelude::{
|
||||
Alphabet, Event, EventId, Filter, Kind, PublicKey, SingleLetterTag, Timestamp,
|
||||
};
|
||||
use nostr_sdk::prelude::{Event, EventId, Filter, Kind, PublicKey, SingleLetterTag, Timestamp};
|
||||
|
||||
use super::policy::{
|
||||
announcement_address_of, identifier_from_event, owner_directory_component, DeletionPolicy,
|
||||
@@ -344,10 +342,9 @@ impl DeletionPolicy {
|
||||
moved_ids: &mut HashSet<EventId>,
|
||||
source: DeletionSource,
|
||||
) -> DeletionOutcome {
|
||||
let announcement_filter = Filter::new().kind(Kind::GitRepoAnnouncement).custom_tag(
|
||||
SingleLetterTag::lowercase(Alphabet::D),
|
||||
identifier.to_string(),
|
||||
);
|
||||
let announcement_filter = Filter::new()
|
||||
.kind(Kind::GitRepoAnnouncement)
|
||||
.custom_tag(SingleLetterTag::LOWERCASE_D, identifier.to_string());
|
||||
|
||||
let remaining_announcements = match self.ctx.database.query(announcement_filter).await {
|
||||
Ok(events) => events,
|
||||
@@ -368,10 +365,9 @@ impl DeletionPolicy {
|
||||
return DeletionOutcome::default();
|
||||
}
|
||||
|
||||
let state_filter = Filter::new().kind(Kind::RepoState).custom_tag(
|
||||
SingleLetterTag::lowercase(Alphabet::D),
|
||||
identifier.to_string(),
|
||||
);
|
||||
let state_filter = Filter::new()
|
||||
.kind(Kind::RepoState)
|
||||
.custom_tag(SingleLetterTag::LOWERCASE_D, identifier.to_string());
|
||||
|
||||
let metadata = HoldingMetadata {
|
||||
deleted_at: deletion_created_at,
|
||||
@@ -616,7 +612,7 @@ async fn query_address_events_with_until(
|
||||
|
||||
let mut filter = Filter::new().kind(parsed.kind).author(parsed.pubkey);
|
||||
if let Some(identifier) = parsed.identifier {
|
||||
filter = filter.custom_tag(SingleLetterTag::lowercase(Alphabet::D), identifier);
|
||||
filter = filter.custom_tag(SingleLetterTag::LOWERCASE_D, identifier);
|
||||
}
|
||||
if let Some(until) = until {
|
||||
filter = filter.until(until);
|
||||
@@ -666,9 +662,9 @@ async fn query_incoming_event_refs(
|
||||
query_tag_variants(
|
||||
database,
|
||||
&[
|
||||
SingleLetterTag::lowercase(Alphabet::E),
|
||||
SingleLetterTag::uppercase(Alphabet::E),
|
||||
SingleLetterTag::lowercase(Alphabet::Q),
|
||||
SingleLetterTag::LOWERCASE_E,
|
||||
SingleLetterTag::UPPERCASE_E,
|
||||
SingleLetterTag::LOWERCASE_Q,
|
||||
],
|
||||
&hex,
|
||||
)
|
||||
@@ -682,9 +678,9 @@ async fn query_incoming_address_refs(
|
||||
query_tag_variants(
|
||||
database,
|
||||
&[
|
||||
SingleLetterTag::lowercase(Alphabet::A),
|
||||
SingleLetterTag::uppercase(Alphabet::A),
|
||||
SingleLetterTag::lowercase(Alphabet::Q),
|
||||
SingleLetterTag::LOWERCASE_A,
|
||||
SingleLetterTag::UPPERCASE_A,
|
||||
SingleLetterTag::LOWERCASE_Q,
|
||||
],
|
||||
address,
|
||||
)
|
||||
|
||||
@@ -165,7 +165,7 @@ mod tests {
|
||||
|
||||
fn deletion() -> Event {
|
||||
EventBuilder::new(Kind::EventDeletion, "")
|
||||
.tags(vec![Tag::event(EventId::all_zeros())])
|
||||
.tags(vec![Tag::event(EventId::from_byte_array([0; 32]))])
|
||||
.finalize(&Keys::generate())
|
||||
.unwrap()
|
||||
}
|
||||
@@ -236,7 +236,7 @@ mod tests {
|
||||
service
|
||||
.ctx
|
||||
.tombstones()
|
||||
.event_deletion_candidates(&EventId::all_zeros(), &request.pubkey)
|
||||
.event_deletion_candidates(&EventId::from_byte_array([0; 32]), &request.pubkey)
|
||||
.await
|
||||
.unwrap()
|
||||
.len(),
|
||||
|
||||
@@ -34,8 +34,7 @@ use std::collections::HashSet;
|
||||
|
||||
use nostr::nips::nip19::ToBech32;
|
||||
use nostr_sdk::prelude::{
|
||||
Alphabet, Event, EventId, Filter, Kind, PublicKey, SingleLetterTag, Timestamp,
|
||||
WritePolicyResult,
|
||||
Event, EventId, Filter, Kind, PublicKey, SingleLetterTag, Timestamp, WritePolicyResult,
|
||||
};
|
||||
|
||||
use super::service::{request_is_served_with_config, UNSERVED_REPLAY_MESSAGE};
|
||||
@@ -275,8 +274,7 @@ impl DeletionPolicy {
|
||||
.author(owner)
|
||||
.until(event.created_at);
|
||||
if kind.is_addressable() {
|
||||
filter =
|
||||
filter.custom_tag(SingleLetterTag::lowercase(Alphabet::D), identifier.clone());
|
||||
filter = filter.custom_tag(SingleLetterTag::LOWERCASE_D, identifier.clone());
|
||||
}
|
||||
if !self.ctx.database.query(filter).await?.is_empty() {
|
||||
return Ok(true);
|
||||
@@ -551,7 +549,7 @@ mod tests {
|
||||
async fn distinct_overlapping_deletion_requests_are_independently_accepted() {
|
||||
let ctx = make_context();
|
||||
let keys = Keys::generate();
|
||||
let target = EventId::all_zeros();
|
||||
let target = EventId::from_byte_array([0; 32]);
|
||||
|
||||
let first = EventBuilder::new(Kind::EventDeletion, "")
|
||||
.tags(vec![Tag::event(target)])
|
||||
@@ -622,7 +620,7 @@ mod tests {
|
||||
let ctx = make_context();
|
||||
let keys = Keys::generate();
|
||||
let deletion = EventBuilder::new(Kind::EventDeletion, "")
|
||||
.tags(vec![Tag::event(EventId::all_zeros())])
|
||||
.tags(vec![Tag::event(EventId::from_byte_array([0; 32]))])
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
|
||||
@@ -1005,7 +1003,7 @@ mod tests {
|
||||
async fn disrespector_records_unused_lifecycle_without_enforcing_a_gate() {
|
||||
let ctx = make_disrespector_context();
|
||||
let keys = Keys::generate();
|
||||
let target = EventId::all_zeros();
|
||||
let target = EventId::from_byte_array([0; 32]);
|
||||
|
||||
let deletion = EventBuilder::new(Kind::EventDeletion, "")
|
||||
.tags(vec![Tag::event(target)])
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use std::collections::{BTreeSet, HashSet};
|
||||
|
||||
use nostr_sdk::prelude::{
|
||||
Alphabet, Event, EventId, Filter, Kind, PublicKey, SingleLetterTag, Timestamp,
|
||||
};
|
||||
use nostr_sdk::prelude::{Event, EventId, Filter, Kind, PublicKey, SingleLetterTag, Timestamp};
|
||||
|
||||
use super::policy::{identifier_from_event, DeletionPolicy};
|
||||
use crate::git;
|
||||
@@ -161,10 +159,7 @@ impl DeletionPolicy {
|
||||
) -> Option<Event> {
|
||||
let mut filter = Filter::new().kind(kind).author(*author);
|
||||
if kind.is_addressable() {
|
||||
filter = filter.custom_tag(
|
||||
SingleLetterTag::lowercase(Alphabet::D),
|
||||
identifier.to_string(),
|
||||
);
|
||||
filter = filter.custom_tag(SingleLetterTag::LOWERCASE_D, identifier.to_string());
|
||||
}
|
||||
if let Some(cutoff) = until {
|
||||
filter = filter.until(cutoff);
|
||||
|
||||
@@ -305,7 +305,7 @@ mod tests {
|
||||
Duration::from_secs(60),
|
||||
);
|
||||
let request = EventBuilder::new(Kind::EventDeletion, "")
|
||||
.tags(vec![Tag::event(EventId::all_zeros())])
|
||||
.tags(vec![Tag::event(EventId::from_byte_array([0; 32]))])
|
||||
.finalize(&Keys::generate())
|
||||
.expect("deletion request should sign");
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use nostr_sdk::prelude::{
|
||||
nip62, Alphabet, Event, Filter, Kind, PublicKey, RelayUrl, SingleLetterTag, Timestamp,
|
||||
WritePolicyResult,
|
||||
nip62, Event, Filter, Kind, PublicKey, RelayUrl, SingleLetterTag, Timestamp, WritePolicyResult,
|
||||
};
|
||||
|
||||
use crate::nostr::events::RepositoryAnnouncement;
|
||||
@@ -523,7 +522,7 @@ impl DeletionService {
|
||||
.kind(Kind::GitRepoAnnouncement)
|
||||
.author(incoming.pubkey)
|
||||
.custom_tag(
|
||||
SingleLetterTag::lowercase(Alphabet::D),
|
||||
SingleLetterTag::LOWERCASE_D,
|
||||
incoming_announcement.identifier.clone(),
|
||||
);
|
||||
|
||||
@@ -948,9 +947,9 @@ mod tests {
|
||||
deletion_request_retention_used_unserved_gating_additional_secs: 3,
|
||||
..crate::config::Config::for_testing()
|
||||
}));
|
||||
let request = deletion(&Keys::generate(), EventId::all_zeros());
|
||||
let request = deletion(&Keys::generate(), EventId::from_byte_array([0; 32]));
|
||||
let unused = RequestLifecycleRecord {
|
||||
metadata_event_id: EventId::all_zeros(),
|
||||
metadata_event_id: EventId::from_byte_array([0; 32]),
|
||||
request: request.clone(),
|
||||
first_seen_at: Timestamp::from_secs(10),
|
||||
last_used_at: None,
|
||||
@@ -978,16 +977,16 @@ mod tests {
|
||||
fn winner_order_prefers_used_then_first_seen_then_event_id() {
|
||||
let keys = Keys::generate();
|
||||
let first_request = EventBuilder::new(Kind::EventDeletion, "first")
|
||||
.tags(vec![Tag::event(EventId::all_zeros())])
|
||||
.tags(vec![Tag::event(EventId::from_byte_array([0; 32]))])
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
let second_request = EventBuilder::new(Kind::EventDeletion, "second")
|
||||
.tags(vec![Tag::event(EventId::all_zeros())])
|
||||
.tags(vec![Tag::event(EventId::from_byte_array([0; 32]))])
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
let record = |request: Event, first_seen_at: u64, last_used_at: Option<u64>| {
|
||||
RequestLifecycleRecord {
|
||||
metadata_event_id: EventId::all_zeros(),
|
||||
metadata_event_id: EventId::from_byte_array([0; 32]),
|
||||
request,
|
||||
first_seen_at: Timestamp::from_secs(first_seen_at),
|
||||
last_used_at: last_used_at.map(Timestamp::from_secs),
|
||||
|
||||
@@ -10,7 +10,7 @@ use std::sync::Arc;
|
||||
use nostr_lmdb::NostrLmdb;
|
||||
use nostr_memory::MemoryDatabase;
|
||||
use nostr_sdk::prelude::{
|
||||
Alphabet, Event, EventBuilder, EventId, Filter, FinalizeEvent, Keys, Kind, NostrDatabase,
|
||||
Event, EventBuilder, EventId, Filter, FinalizeEvent, Keys, Kind, NostrDatabase,
|
||||
SingleLetterTag, Tag, Timestamp,
|
||||
};
|
||||
|
||||
@@ -145,10 +145,7 @@ impl ReplaceableHistoryStore {
|
||||
) -> Vec<SupersededRecord> {
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::from(HISTORY_METADATA_KIND))
|
||||
.custom_tag(
|
||||
SingleLetterTag::lowercase(Alphabet::A),
|
||||
coordinate.to_string(),
|
||||
);
|
||||
.custom_tag(SingleLetterTag::LOWERCASE_A, coordinate.to_string());
|
||||
|
||||
let events = match self.db.query(filter).await {
|
||||
Ok(events) => events,
|
||||
|
||||
@@ -12,7 +12,7 @@ use std::{collections::BTreeSet, io::ErrorKind};
|
||||
use nostr_lmdb::NostrLmdb;
|
||||
use nostr_memory::MemoryDatabase;
|
||||
use nostr_sdk::prelude::{
|
||||
Alphabet, Event, EventBuilder, EventId, Filter, FinalizeEvent, Keys, Kind, NostrDatabase,
|
||||
Event, EventBuilder, EventId, Filter, FinalizeEvent, Keys, Kind, NostrDatabase,
|
||||
SingleLetterTag, Tag, Timestamp,
|
||||
};
|
||||
|
||||
@@ -220,7 +220,7 @@ impl HoldingStore {
|
||||
pub async fn metadata_for_event(&self, id: &EventId) -> Vec<Event> {
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::from(HOLDING_METADATA_KIND))
|
||||
.custom_tag(SingleLetterTag::lowercase(Alphabet::E), id.to_hex());
|
||||
.custom_tag(SingleLetterTag::LOWERCASE_E, id.to_hex());
|
||||
|
||||
match self.db.query(filter).await {
|
||||
Ok(events) => events.into_iter().collect(),
|
||||
@@ -922,7 +922,7 @@ mod tests {
|
||||
let store = HoldingStore::in_memory();
|
||||
let metadata = EventBuilder::new(Kind::from(HOLDING_METADATA_KIND), "")
|
||||
.tags(vec![
|
||||
Tag::custom("e", vec![EventId::all_zeros().to_hex()]),
|
||||
Tag::custom("e", vec![EventId::from_byte_array([0; 32]).to_hex()]),
|
||||
Tag::custom("holding-deleted-at", vec!["not-a-number".to_string()]),
|
||||
])
|
||||
.finalize(&Keys::generate())
|
||||
|
||||
@@ -51,8 +51,8 @@ use tokio::sync::{Mutex, MutexGuard};
|
||||
use nostr_lmdb::NostrLmdb;
|
||||
use nostr_memory::MemoryDatabase;
|
||||
use nostr_sdk::prelude::{
|
||||
Alphabet, Event, EventBuilder, EventId, Filter, FinalizeEvent, Keys, Kind, NostrDatabase,
|
||||
PublicKey, SingleLetterTag, Tag, Timestamp,
|
||||
Event, EventBuilder, EventId, Filter, FinalizeEvent, Keys, Kind, NostrDatabase, PublicKey,
|
||||
SingleLetterTag, Tag, Timestamp,
|
||||
};
|
||||
|
||||
/// Directory name (under `relay_data_path`) for the LMDB tombstone database.
|
||||
@@ -765,7 +765,7 @@ impl Tombstones {
|
||||
) -> anyhow::Result<Vec<Event>> {
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::from(TOMBSTONE_REQUEST_METADATA_KIND))
|
||||
.custom_tag(SingleLetterTag::lowercase(Alphabet::E), request_id.to_hex());
|
||||
.custom_tag(SingleLetterTag::LOWERCASE_E, request_id.to_hex());
|
||||
self.db
|
||||
.query(filter)
|
||||
.await
|
||||
@@ -868,7 +868,7 @@ impl Tombstones {
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::EventDeletion)
|
||||
.author(*author)
|
||||
.custom_tag(SingleLetterTag::lowercase(Alphabet::E), id.to_hex());
|
||||
.custom_tag(SingleLetterTag::LOWERCASE_E, id.to_hex());
|
||||
self.lifecycle_candidates(filter, |request| {
|
||||
request.kind == Kind::EventDeletion
|
||||
&& request.pubkey == *author
|
||||
@@ -892,10 +892,9 @@ impl Tombstones {
|
||||
// it. Extract it so we can require the kind-5 author to match.
|
||||
let coord_owner_hex = coordinate.split(':').nth(1);
|
||||
|
||||
let filter = Filter::new().kind(Kind::EventDeletion).custom_tag(
|
||||
SingleLetterTag::lowercase(Alphabet::A),
|
||||
coordinate.to_string(),
|
||||
);
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::EventDeletion)
|
||||
.custom_tag(SingleLetterTag::LOWERCASE_A, coordinate.to_string());
|
||||
self.lifecycle_candidates(filter, |request| {
|
||||
request.kind == Kind::EventDeletion
|
||||
&& request.created_at >= event_created_at
|
||||
@@ -980,7 +979,7 @@ mod tests {
|
||||
async fn lifecycle_round_trip_for_kind_five_preserves_relay_first_seen_at() {
|
||||
let store = Tombstones::in_memory();
|
||||
let keys = Keys::generate();
|
||||
let request = deletion_by_event(&keys, EventId::all_zeros());
|
||||
let request = deletion_by_event(&keys, EventId::from_byte_array([0; 32]));
|
||||
let first_seen_at = Timestamp::from_secs(1234);
|
||||
|
||||
store
|
||||
@@ -1036,7 +1035,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn exact_replay_does_not_reset_first_seen_at() {
|
||||
let store = Tombstones::in_memory();
|
||||
let request = deletion_by_event(&Keys::generate(), EventId::all_zeros());
|
||||
let request = deletion_by_event(&Keys::generate(), EventId::from_byte_array([0; 32]));
|
||||
store
|
||||
.record_request(
|
||||
&request,
|
||||
@@ -1070,7 +1069,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn marking_request_used_advances_without_resetting_first_seen_at() {
|
||||
let store = Tombstones::in_memory();
|
||||
let request = deletion_by_event(&Keys::generate(), EventId::all_zeros());
|
||||
let request = deletion_by_event(&Keys::generate(), EventId::from_byte_array([0; 32]));
|
||||
store
|
||||
.record_request(
|
||||
&request,
|
||||
@@ -1107,7 +1106,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn canonical_metadata_selection_is_deterministic_and_compacted_on_update() {
|
||||
let store = Tombstones::in_memory();
|
||||
let request = deletion_by_event(&Keys::generate(), EventId::all_zeros());
|
||||
let request = deletion_by_event(&Keys::generate(), EventId::from_byte_array([0; 32]));
|
||||
store
|
||||
.record_request(
|
||||
&request,
|
||||
@@ -1154,7 +1153,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn malformed_and_orphan_metadata_are_ignored_safely() {
|
||||
let store = Tombstones::in_memory();
|
||||
let request = deletion_by_event(&Keys::generate(), EventId::all_zeros());
|
||||
let request = deletion_by_event(&Keys::generate(), EventId::from_byte_array([0; 32]));
|
||||
let malformed = EventBuilder::new(Kind::from(TOMBSTONE_REQUEST_METADATA_KIND), "")
|
||||
.tags(vec![Tag::event(request.id)])
|
||||
.finalize(&store.metadata_signer)
|
||||
@@ -1166,7 +1165,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.is_none());
|
||||
|
||||
let orphan_id = EventId::all_zeros();
|
||||
let orphan_id = EventId::from_byte_array([0; 32]);
|
||||
let orphan = store
|
||||
.build_metadata(
|
||||
orphan_id,
|
||||
@@ -1187,7 +1186,7 @@ mod tests {
|
||||
async fn metadata_events_do_not_affect_deletion_or_vanish_queries() {
|
||||
let store = Tombstones::in_memory();
|
||||
let keys = Keys::generate();
|
||||
let target = EventId::all_zeros();
|
||||
let target = EventId::from_byte_array([0; 32]);
|
||||
let metadata = store
|
||||
.build_metadata(
|
||||
target,
|
||||
@@ -1215,7 +1214,7 @@ mod tests {
|
||||
let store = Tombstones::in_memory();
|
||||
let owner = Keys::generate();
|
||||
let other = Keys::generate();
|
||||
let target = EventId::all_zeros();
|
||||
let target = EventId::from_byte_array([0; 32]);
|
||||
let request = deletion_by_event(&owner, target);
|
||||
store
|
||||
.record_request(
|
||||
@@ -1243,7 +1242,7 @@ mod tests {
|
||||
async fn event_deletion_candidates_resolve_duplicate_requests_together() {
|
||||
let store = Tombstones::in_memory();
|
||||
let owner = Keys::generate();
|
||||
let target = EventId::all_zeros();
|
||||
let target = EventId::from_byte_array([0; 32]);
|
||||
let mut actionable_ids = Vec::new();
|
||||
|
||||
// A single event may have many valid deletion requests. Save their
|
||||
@@ -1383,7 +1382,7 @@ mod tests {
|
||||
async fn lifecycle_metadata_survives_lmdb_reopen() {
|
||||
let directory = tempfile::tempdir().unwrap();
|
||||
let keys = Keys::generate();
|
||||
let request = deletion_by_event(&keys, EventId::all_zeros());
|
||||
let request = deletion_by_event(&keys, EventId::from_byte_array([0; 32]));
|
||||
let store = Tombstones::open_lmdb(directory.path()).await.unwrap();
|
||||
store
|
||||
.record_request(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
///
|
||||
/// Handles validation of NIP-34 repository announcements (kind 30617)
|
||||
/// according to GRASP-01 specification.
|
||||
use nostr_sdk::prelude::{Alphabet, Event, Filter, Kind, PublicKey, SingleLetterTag};
|
||||
use nostr_sdk::prelude::{Event, Filter, Kind, PublicKey, SingleLetterTag};
|
||||
use std::collections::HashSet;
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -316,10 +316,7 @@ impl AnnouncementPolicy {
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::GitRepoAnnouncement)
|
||||
.author(*pubkey)
|
||||
.custom_tag(
|
||||
SingleLetterTag::lowercase(Alphabet::D),
|
||||
identifier.to_string(),
|
||||
);
|
||||
.custom_tag(SingleLetterTag::LOWERCASE_D, identifier.to_string());
|
||||
|
||||
let events: Vec<Event> = match self.ctx.database.query(filter).await {
|
||||
Ok(events) => events.into_iter().collect(),
|
||||
@@ -434,10 +431,9 @@ impl AnnouncementPolicy {
|
||||
author: &PublicKey,
|
||||
) -> Result<bool, String> {
|
||||
// Query all announcements with this identifier that are already in the database
|
||||
let filter = Filter::new().kind(Kind::GitRepoAnnouncement).custom_tag(
|
||||
SingleLetterTag::lowercase(Alphabet::D),
|
||||
identifier.to_string(),
|
||||
);
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::GitRepoAnnouncement)
|
||||
.custom_tag(SingleLetterTag::LOWERCASE_D, identifier.to_string());
|
||||
|
||||
let db_announcements: Vec<Event> = match self.ctx.database.query(filter).await {
|
||||
Ok(events) => events.into_iter().collect(),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/// Handles validation of events that reference accepted repositories or events
|
||||
/// (backward references) and events that are referenced by accepted events
|
||||
/// (forward references).
|
||||
use nostr_sdk::prelude::{Alphabet, Event, EventId, Filter, Kind, PublicKey, SingleLetterTag};
|
||||
use nostr_sdk::prelude::{Event, EventId, Filter, Kind, PublicKey, SingleLetterTag};
|
||||
|
||||
use super::PolicyContext;
|
||||
|
||||
@@ -230,9 +230,9 @@ impl RelatedEventPolicy {
|
||||
|
||||
// Check addressable reference tags: a, A, q (with address format)
|
||||
let addressable_tags = [
|
||||
SingleLetterTag::lowercase(Alphabet::A), // 'a' - addressable event reference
|
||||
SingleLetterTag::uppercase(Alphabet::A), // 'A' - uppercase addressable reference
|
||||
SingleLetterTag::lowercase(Alphabet::Q), // 'q' - quote (can be address or ID)
|
||||
SingleLetterTag::LOWERCASE_A, // 'a' - addressable event reference
|
||||
SingleLetterTag::UPPERCASE_A, // 'A' - uppercase addressable reference
|
||||
SingleLetterTag::LOWERCASE_Q, // 'q' - quote (can be address or ID)
|
||||
];
|
||||
|
||||
for tag_type in &addressable_tags {
|
||||
@@ -252,9 +252,9 @@ impl RelatedEventPolicy {
|
||||
let event_id_hex = event.id.to_hex();
|
||||
|
||||
let event_id_tags = [
|
||||
SingleLetterTag::lowercase(Alphabet::E), // 'e' - standard event reference
|
||||
SingleLetterTag::uppercase(Alphabet::E), // 'E' - NIP-22 root event reference
|
||||
SingleLetterTag::lowercase(Alphabet::Q), // 'q' - quote reference
|
||||
SingleLetterTag::LOWERCASE_E, // 'e' - standard event reference
|
||||
SingleLetterTag::UPPERCASE_E, // 'E' - NIP-22 root event reference
|
||||
SingleLetterTag::LOWERCASE_Q, // 'q' - quote reference
|
||||
];
|
||||
|
||||
for tag_type in &event_id_tags {
|
||||
|
||||
@@ -242,7 +242,7 @@ mod tests {
|
||||
relays.insert("wss://relay1.com".to_string());
|
||||
|
||||
let mut root_events = HashSet::new();
|
||||
root_events.insert(EventId::all_zeros());
|
||||
root_events.insert(EventId::from_byte_array([0; 32]));
|
||||
|
||||
repo_index.insert(
|
||||
"repo1".to_string(),
|
||||
@@ -359,7 +359,7 @@ mod tests {
|
||||
let mut relays1 = HashSet::new();
|
||||
relays1.insert("wss://relay1.com".to_string());
|
||||
let mut root_events1 = HashSet::new();
|
||||
root_events1.insert(EventId::all_zeros());
|
||||
root_events1.insert(EventId::from_byte_array([0; 32]));
|
||||
|
||||
repo_index.insert(
|
||||
"repo1".to_string(),
|
||||
@@ -374,7 +374,7 @@ mod tests {
|
||||
let mut relays2 = HashSet::new();
|
||||
relays2.insert("wss://relay1.com".to_string());
|
||||
let mut root_events2 = HashSet::new();
|
||||
root_events2.insert(EventId::all_zeros()); // Same event
|
||||
root_events2.insert(EventId::from_byte_array([0; 32])); // Same event
|
||||
|
||||
repo_index.insert(
|
||||
"repo2".to_string(),
|
||||
@@ -729,7 +729,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_compute_actions_with_root_events() {
|
||||
let event_id = EventId::all_zeros();
|
||||
let event_id = EventId::from_byte_array([0; 32]);
|
||||
|
||||
let mut targets = HashMap::new();
|
||||
targets.insert(
|
||||
|
||||
+14
-15
@@ -120,8 +120,7 @@ pub fn state_event_filters_for_our_repos(
|
||||
|
||||
// Add #d tags for all identifiers in this chunk
|
||||
for identifier in chunk {
|
||||
filter =
|
||||
filter.custom_tag(SingleLetterTag::lowercase(Alphabet::D), identifier.as_str());
|
||||
filter = filter.custom_tag(SingleLetterTag::LOWERCASE_D, identifier.as_str());
|
||||
}
|
||||
|
||||
if let Some(ts) = since {
|
||||
@@ -160,19 +159,19 @@ pub fn tagged_one_of_our_repo_event_filters(
|
||||
// Lowercase 'a' tag - standard addressable reference
|
||||
let mut f1 = Filter::new();
|
||||
for repo in chunk {
|
||||
f1 = f1.custom_tag(SingleLetterTag::lowercase(Alphabet::A), repo.as_str());
|
||||
f1 = f1.custom_tag(SingleLetterTag::LOWERCASE_A, repo.as_str());
|
||||
}
|
||||
|
||||
// Uppercase 'A' tag - some clients use this
|
||||
let mut f2 = Filter::new();
|
||||
for repo in chunk {
|
||||
f2 = f2.custom_tag(SingleLetterTag::uppercase(Alphabet::A), repo.as_str());
|
||||
f2 = f2.custom_tag(SingleLetterTag::UPPERCASE_A, repo.as_str());
|
||||
}
|
||||
|
||||
// Quote 'q' tag - NIP-10 quote references to addressable events
|
||||
let mut f3 = Filter::new();
|
||||
for repo in chunk {
|
||||
f3 = f3.custom_tag(SingleLetterTag::lowercase(Alphabet::Q), repo.as_str());
|
||||
f3 = f3.custom_tag(SingleLetterTag::LOWERCASE_Q, repo.as_str());
|
||||
}
|
||||
|
||||
if let Some(ts) = since {
|
||||
@@ -223,19 +222,19 @@ pub fn tagged_one_of_our_root_event_filters(
|
||||
// Lowercase 'e' tag - standard event reference
|
||||
let mut f1 = Filter::new();
|
||||
for event_id in chunk {
|
||||
f1 = f1.custom_tag(SingleLetterTag::lowercase(Alphabet::E), event_id.as_str());
|
||||
f1 = f1.custom_tag(SingleLetterTag::LOWERCASE_E, event_id.as_str());
|
||||
}
|
||||
|
||||
// Uppercase 'E' tag - some clients use this
|
||||
let mut f2 = Filter::new();
|
||||
for event_id in chunk {
|
||||
f2 = f2.custom_tag(SingleLetterTag::uppercase(Alphabet::E), event_id.as_str());
|
||||
f2 = f2.custom_tag(SingleLetterTag::UPPERCASE_E, event_id.as_str());
|
||||
}
|
||||
|
||||
// Quote 'q' tag - NIP-10 quote references to events
|
||||
let mut f3 = Filter::new();
|
||||
for event_id in chunk {
|
||||
f3 = f3.custom_tag(SingleLetterTag::lowercase(Alphabet::Q), event_id.as_str());
|
||||
f3 = f3.custom_tag(SingleLetterTag::LOWERCASE_Q, event_id.as_str());
|
||||
}
|
||||
|
||||
if let Some(ts) = since {
|
||||
@@ -439,7 +438,7 @@ mod tests {
|
||||
fn test_root_event_filters_single_event() {
|
||||
let mut root_events = HashSet::new();
|
||||
// Create a valid event ID (all zeros for testing)
|
||||
root_events.insert(EventId::all_zeros());
|
||||
root_events.insert(EventId::from_byte_array([0; 32]));
|
||||
|
||||
let filters = tagged_one_of_our_root_event_filters(&root_events, None);
|
||||
|
||||
@@ -450,11 +449,11 @@ mod tests {
|
||||
#[test]
|
||||
fn test_root_event_filters_batching() {
|
||||
let mut root_events = HashSet::new();
|
||||
// EventId::all_zeros() will deduplicate, so we need unique IDs
|
||||
// EventId::from_byte_array([0; 32]) will deduplicate, so we need unique IDs
|
||||
// For testing purposes, we'll just verify with one ID since HashSet
|
||||
// deduplicates all_zeros(). In real usage these would be unique.
|
||||
for _ in 0..250 {
|
||||
root_events.insert(EventId::all_zeros());
|
||||
root_events.insert(EventId::from_byte_array([0; 32]));
|
||||
}
|
||||
|
||||
let filters = tagged_one_of_our_root_event_filters(&root_events, None);
|
||||
@@ -467,7 +466,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_root_event_filters_with_since() {
|
||||
let mut root_events = HashSet::new();
|
||||
root_events.insert(EventId::all_zeros());
|
||||
root_events.insert(EventId::from_byte_array([0; 32]));
|
||||
|
||||
let since = Timestamp::from(1700000000);
|
||||
let filters = tagged_one_of_our_root_event_filters(&root_events, Some(since));
|
||||
@@ -491,7 +490,7 @@ mod tests {
|
||||
repos.insert("30617:abc123:repo1".to_string());
|
||||
|
||||
let mut root_events = HashSet::new();
|
||||
root_events.insert(EventId::all_zeros());
|
||||
root_events.insert(EventId::from_byte_array([0; 32]));
|
||||
|
||||
let filters = build_layer2_and_layer3_filters(&repos, &root_events, None);
|
||||
|
||||
@@ -517,7 +516,7 @@ mod tests {
|
||||
let repos: HashSet<String> = HashSet::new();
|
||||
|
||||
let mut root_events = HashSet::new();
|
||||
root_events.insert(EventId::all_zeros());
|
||||
root_events.insert(EventId::from_byte_array([0; 32]));
|
||||
|
||||
let filters = build_layer2_and_layer3_filters(&repos, &root_events, None);
|
||||
|
||||
@@ -531,7 +530,7 @@ mod tests {
|
||||
repos.insert("30617:abc123:repo1".to_string());
|
||||
|
||||
let mut root_events = HashSet::new();
|
||||
root_events.insert(EventId::all_zeros());
|
||||
root_events.insert(EventId::from_byte_array([0; 32]));
|
||||
|
||||
let since = Timestamp::from(1700000000);
|
||||
let filters = build_layer2_and_layer3_filters(&repos, &root_events, Some(since));
|
||||
|
||||
+1
-1
@@ -5488,7 +5488,7 @@ mod tests {
|
||||
fn group_filters_for_req_respects_count_and_byte_budgets() {
|
||||
// Many small filters group by the count cap.
|
||||
let small: Vec<Filter> = (0..25)
|
||||
.map(|i| Filter::new().id(EventId::all_zeros()).limit(i))
|
||||
.map(|i| Filter::new().id(EventId::from_byte_array([0; 32])).limit(i))
|
||||
.collect();
|
||||
let groups = group_filters_for_req(&small);
|
||||
assert_eq!(
|
||||
|
||||
@@ -972,7 +972,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_build_layer3_comment_kind_1111() {
|
||||
let keys = Keys::generate();
|
||||
let parent_id = EventId::all_zeros();
|
||||
let parent_id = EventId::from_byte_array([0; 32]);
|
||||
|
||||
let event = build_layer3_comment_event(&keys, &parent_id, "Test comment", Kind::Comment)
|
||||
.expect("Should create event");
|
||||
@@ -990,7 +990,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_build_layer3_comment_kind_1() {
|
||||
let keys = Keys::generate();
|
||||
let parent_id = EventId::all_zeros();
|
||||
let parent_id = EventId::from_byte_array([0; 32]);
|
||||
|
||||
let event = build_layer3_comment_event(&keys, &parent_id, "Test reply", Kind::Custom(1))
|
||||
.expect("Should create event");
|
||||
@@ -1008,7 +1008,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_build_layer3_reply_with_e_tag() {
|
||||
let keys = Keys::generate();
|
||||
let parent_id = EventId::all_zeros();
|
||||
let parent_id = EventId::from_byte_array([0; 32]);
|
||||
|
||||
let event = build_layer3_reply_with_e_tag(&keys, &parent_id, "Reply content")
|
||||
.expect("Should create event");
|
||||
@@ -1025,7 +1025,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_build_layer3_comment_with_uppercase_e() {
|
||||
let keys = Keys::generate();
|
||||
let parent_id = EventId::all_zeros();
|
||||
let parent_id = EventId::from_byte_array([0; 32]);
|
||||
|
||||
let event = build_layer3_comment_with_uppercase_e_tag(&keys, &parent_id, "Comment content")
|
||||
.expect("Should create event");
|
||||
@@ -1042,7 +1042,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_build_layer3_quote_with_q() {
|
||||
let keys = Keys::generate();
|
||||
let parent_id = EventId::all_zeros();
|
||||
let parent_id = EventId::from_byte_array([0; 32]);
|
||||
|
||||
let event = build_layer3_quote_with_q_tag(&keys, &parent_id, "Quote content")
|
||||
.expect("Should create event");
|
||||
@@ -1578,7 +1578,7 @@ mod sync_helper_tests {
|
||||
let coord = repo_coord(&keys, "test");
|
||||
let historic =
|
||||
build_layer2_issue_event(&keys, &coord, "Historic").expect("Should create event");
|
||||
let live = build_layer3_reply_with_e_tag(&keys, &EventId::all_zeros(), "Live")
|
||||
let live = build_layer3_reply_with_e_tag(&keys, &EventId::from_byte_array([0; 32]), "Live")
|
||||
.expect("Should create event");
|
||||
|
||||
// Should panic - both slices provided
|
||||
|
||||
Reference in New Issue
Block a user