mirror of
https://relay.ngit.dev/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp.git
synced 2026-10-05 23:18:24 +00:00
fix(relay): keep sessions open on malformed client messages
Production traffic containing unparseable client messages tore down the entire WebSocket connection. A single bad message - most visibly requests carrying invalid event IDs, failing deserialization with `Invalid input length 64` - propagated out of the relay's read loop and closed the session, so every affected client had to reconnect and re-subscribe. One malformed frame cost a client all of its live subscriptions, and clients that retried the same payload produced sustained connection churn. The defect was upstream in rust-nostr's local relay, not in ngit-grasp, and was reported as nostr:nevent1qqsqmmfv6fxk995yr5858eev7z6zmchchgmk90d4rffuuwe6ewcvx0cpz3mhxue69uhhyetvv9ujumn8d96zuer9wckedd82 and fixed by nostr:nevent1qqs24l0rv6qw3mdqdaj8nj4wlds2gy8a9wrqs3gj5kcmz27c8gm7kagpz3mhxue69uhhyetvv9ujumn8d96zuer9wc7gp6cp Deserialization failures are now contained inside the WebSocket loop and answered with a `NOTICE`, leaving the session and its subscriptions intact. Upgrade the NostrDevKit crates from 0.45.0-alpha.3 to 0.45.0-alpha.8, the first published release containing the fix. Inclusion was verified three ways rather than by release notes: upstream commit 7c0f3aa2cf2fbeb9f0067cb2349579754919eabd is an ancestor of the `Bump to v0.45.0-alpha.8` commit on upstream master; the alpha.8 crate downloaded from crates.io contains the repaired match arm in `src/local_relay/local/inner.rs`; and it also ships the upstream regression test `test_malformed_client_message_does_not_close_connection`, which drives a real WebSocket with a short-author REQ and asserts a subsequent valid REQ still reaches EOSE on the same socket. That upstream test covers the behaviour directly, so no equivalent test is duplicated here. All four rust-nostr crates move together to keep the tree off a mixture of alpha versions. `nostr-relay-builder` is gone: upstream merged it into `nostr-sdk` at alpha.4, so its imports become `nostr_sdk::local_relay` and `nostr_sdk::prelude`, and `nostr-sdk` now enables the `local-relay` feature. Three further alpha-to-alpha API removals are absorbed: `nostr::hashes` is no longer re-exported, so the `Sec-WebSocket-Accept` derivation depends on `bitcoin_hashes` directly - the same crate `nostr` still uses internally, so no second hash implementation enters the tree; `BoxedFuture` became crate-private, so `WritePolicy::admit_event` spells out its `Pin<Box<dyn Future<...>>>` return type; and `EventBuilder::text_note` was removed in favour of `EventBuilder::new(Kind::TextNote, ..)`, which affects test code only. These requirements are pinned exactly as `=0.45.0-alpha.n` rather than left as caret requirements. Cargo reads `"0.45.0-alpha.3"` as `^0.45.0-alpha.3`, which admits *any* later prerelease of 0.45.0 even though prereleases promise no compatibility - exactly the surprise reported against ngit in nostr:nevent1qqs0yvj4z302cjsnqx9jpp78jrfujhse0w47adjncwkxr922rjltk8spz3mhxue69uhhyetvv9ujumn8d96zuer9wcr42j8n where a declared alpha.2 resolved to alpha.7. This upgrade is direct evidence that the risk is real: alpha.4 deleted a whole crate this project depended on, which a caret requirement would have accepted silently. Pinning is safe because it only narrows resolution, and the committed `Cargo.lock` already selects these versions; what it adds is protection for builds that do not honour the lockfile - `cargo install`, and downstream consumers of the `ngit_grasp` library. The pins should be relaxed to caret requirements once 0.45.0 is released. Validated in the project Nix development shell with `CARGO_BUILD_JOBS=2`: `cargo fmt --all --check` clean, `cargo clippy --workspace --all-targets -D warnings` clean, and `cargo test --workspace --no-fail-fast` at 1937 passed / 32 failed. The 32 failures were confirmed pre-existing by running the identical suite on unmodified master in this environment: the same 1937/32 split and a byte-identical set of failing test names, so this upgrade introduces no regressions. All dependencies remain crates.io sources, so no `flake.nix` or `nix/module.nix` hashes required updating.
This commit is contained in:
@@ -9,6 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed malformed client messages tearing down the whole WebSocket connection.
|
||||
A single unparseable message - in production, requests carrying invalid event
|
||||
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`.
|
||||
- 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
+41
-49
@@ -114,9 +114,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-wsocket"
|
||||
version = "0.15.0"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c69f24cf7a798027c6b0801de5bfd05d01fe343e87a8329f7c8b46a6d3bc4a79"
|
||||
checksum = "efa9ef232c1731ddbe4a306b5b5dcf9e50a924d6bd086d4784939d14f8e78daa"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"futures-util",
|
||||
@@ -132,12 +132,6 @@ dependencies = [
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic-destructor"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef49f5882e4b6afaac09ad239a4f8c70a24b8f2b0897edb1f706008efd109cf4"
|
||||
|
||||
[[package]]
|
||||
name = "atomic-waker"
|
||||
version = "1.1.2"
|
||||
@@ -152,9 +146,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "bech32"
|
||||
version = "0.11.1"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f"
|
||||
checksum = "efbd3e1070bbdf4cd88a75264e18e8a26f7cb5c6949eadf0ceb85fb159cf08f8"
|
||||
|
||||
[[package]]
|
||||
name = "bip39"
|
||||
@@ -1210,9 +1204,9 @@ checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a"
|
||||
|
||||
[[package]]
|
||||
name = "lru"
|
||||
version = "0.16.4"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39"
|
||||
checksum = "0b6180140927ee907000b0aa540091f6ea512ead4447c92b8fc35bc72788a5a6"
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
@@ -1280,6 +1274,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"base64",
|
||||
"bitcoin_hashes",
|
||||
"clap",
|
||||
"dashmap",
|
||||
"dotenvy",
|
||||
@@ -1295,7 +1290,6 @@ dependencies = [
|
||||
"nostr",
|
||||
"nostr-lmdb",
|
||||
"nostr-memory",
|
||||
"nostr-relay-builder",
|
||||
"nostr-sdk",
|
||||
"prometheus",
|
||||
"rand 0.10.1",
|
||||
@@ -1311,9 +1305,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nostr"
|
||||
version = "0.45.0-alpha.3"
|
||||
version = "0.45.0-alpha.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a901cdb1982b9bf73a8d8a7270978345aabd0c62544f6a9a5c35a13d0a7f5824"
|
||||
checksum = "0334ad7a19f229983c808840f65d813d09c7fc030775db5d325abffa1295fe6c"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bech32",
|
||||
@@ -1335,9 +1329,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nostr-database"
|
||||
version = "0.45.0-alpha.3"
|
||||
version = "0.45.0-alpha.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbc883371f13c7c6ab53e9a541fd76955d5fafe8418ccae1439fc64ff0c6bb2f"
|
||||
checksum = "82e3827aa36205889d9950bb07e9ab9380f7881ab3b059956f2d87651fa64281"
|
||||
dependencies = [
|
||||
"btreecap",
|
||||
"flatbuffers",
|
||||
@@ -1347,9 +1341,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nostr-gossip"
|
||||
version = "0.45.0-alpha.3"
|
||||
version = "0.45.0-alpha.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c719c20a592b898e636f85a030fdba3689c7a07cc8707c9c2b34f1fb72a3db70"
|
||||
checksum = "a4696e01b02eb84daa6d8419f529c6e6f3063b742a54925dc0300a3230871477"
|
||||
dependencies = [
|
||||
"nostr",
|
||||
"opaquerr",
|
||||
@@ -1357,9 +1351,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nostr-lmdb"
|
||||
version = "0.45.0-alpha.3"
|
||||
version = "0.45.0-alpha.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "352aa0d58315128c581c3046f91bbb9b39b482d5ff3300ceea748726b889d4fc"
|
||||
checksum = "2832ab8243313733630c90208f36b9859dd939b13c745c977f2a0c465b5ec117"
|
||||
dependencies = [
|
||||
"async-utility",
|
||||
"flume",
|
||||
@@ -1372,9 +1366,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nostr-memory"
|
||||
version = "0.45.0-alpha.3"
|
||||
version = "0.45.0-alpha.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96fce3c7c698afe88d9ac28f78e8dd68de6ecd3accfa99f2b7b76791e0ac24c2"
|
||||
checksum = "1688a4bfea60f72ca212c55f23cc9f068bfb5e787829d85fc7f689c3df9de842"
|
||||
dependencies = [
|
||||
"btreecap",
|
||||
"nostr",
|
||||
@@ -1382,31 +1376,11 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nostr-relay-builder"
|
||||
version = "0.45.0-alpha.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23d6f997d7bdbd18ab6fd5bf7d402c80dd1d313599461723a111a3ace10b2440"
|
||||
dependencies = [
|
||||
"async-utility",
|
||||
"async-wsocket",
|
||||
"atomic-destructor",
|
||||
"faster-hex",
|
||||
"negentropy",
|
||||
"nostr",
|
||||
"nostr-database",
|
||||
"nostr-memory",
|
||||
"nostr-sdk",
|
||||
"opaquerr",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nostr-sdk"
|
||||
version = "0.45.0-alpha.3"
|
||||
version = "0.45.0-alpha.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efa5827340f0296084ead006938172fa946531185741af15c8bf4e60b6f3ad7f"
|
||||
checksum = "c2ffff8a1d69b9828574ead3b34d615bffe4c75ff3e3335a28f111867c7f7cdd"
|
||||
dependencies = [
|
||||
"async-utility",
|
||||
"async-wsocket",
|
||||
@@ -1417,7 +1391,9 @@ dependencies = [
|
||||
"nostr",
|
||||
"nostr-database",
|
||||
"nostr-gossip",
|
||||
"nostr-memory",
|
||||
"opaquerr",
|
||||
"rand 0.10.1",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tracing",
|
||||
@@ -1703,6 +1679,8 @@ version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
@@ -1712,7 +1690,7 @@ version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
|
||||
dependencies = [
|
||||
"rand_chacha",
|
||||
"rand_chacha 0.9.0",
|
||||
"rand_core 0.9.5",
|
||||
]
|
||||
|
||||
@@ -1727,6 +1705,16 @@ dependencies = [
|
||||
"rand_core 0.10.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.9.0"
|
||||
@@ -1742,6 +1730,9 @@ name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom 0.2.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
@@ -1924,12 +1915,13 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "secp256k1"
|
||||
version = "0.29.1"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113"
|
||||
checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252"
|
||||
dependencies = [
|
||||
"bitcoin_hashes",
|
||||
"rand 0.8.6",
|
||||
"secp256k1-sys",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
+18
-7
@@ -16,16 +16,27 @@ hyper = { version = "1.4", features = ["full"] }
|
||||
hyper-util = { version = "0.1", features = ["tokio", "server", "http1", "http2"] }
|
||||
http-body-util = "0.1"
|
||||
|
||||
# Nostr relay
|
||||
nostr-relay-builder = "0.45.0-alpha.3"
|
||||
|
||||
# Nostr
|
||||
nostr = "0.45.0-alpha.3"
|
||||
nostr-sdk = "0.45.0-alpha.3"
|
||||
nostr-lmdb = "0.45.0-alpha.3"
|
||||
nostr-memory = "0.45.0-alpha.3"
|
||||
#
|
||||
# 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"
|
||||
# `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"
|
||||
|
||||
# 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,
|
||||
# so depend on it directly rather than pulling in a second hash implementation.
|
||||
bitcoin_hashes = "0.14"
|
||||
futures-util = "0.3"
|
||||
base64 = "0.22"
|
||||
flate2 = "1.0"
|
||||
|
||||
@@ -13,7 +13,8 @@ path = "src/bin/grasp-audit.rs"
|
||||
|
||||
[dependencies]
|
||||
# Nostr
|
||||
nostr-sdk = "0.45.0-alpha.3"
|
||||
# Pinned exactly: see the rationale in the workspace root Cargo.toml.
|
||||
nostr-sdk = "=0.45.0-alpha.8"
|
||||
|
||||
# Async
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use hyper::body::Bytes;
|
||||
use nostr_relay_builder::prelude::*;
|
||||
use nostr_sdk::prelude::*;
|
||||
use nostr_sdk::prelude::{EventId, ToBech32};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::Arc;
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
use futures_util::stream;
|
||||
use http_body_util::{BodyExt, StreamBody};
|
||||
use hyper::{body::Bytes, body::Frame, Response, StatusCode};
|
||||
use nostr_relay_builder::LocalRelay;
|
||||
use nostr_sdk::local_relay::LocalRelay;
|
||||
use std::collections::HashSet;
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
|
||||
+5
-5
@@ -879,7 +879,7 @@ pub async fn process_newly_available_git_data(
|
||||
source_repo_path: &Path,
|
||||
new_oids: &HashSet<String>,
|
||||
database: &SharedDatabase,
|
||||
local_relay: Option<&nostr_relay_builder::LocalRelay>,
|
||||
local_relay: Option<&nostr_sdk::local_relay::LocalRelay>,
|
||||
purgatory: &Purgatory,
|
||||
git_data_path: &Path,
|
||||
promotion_hooks: Option<&dyn PurgatoryPromotionHooks>,
|
||||
@@ -995,7 +995,7 @@ pub async fn process_repos_populated_by_state_copy(
|
||||
state: &RepositoryState,
|
||||
repo_data: &RepositoryData,
|
||||
database: &SharedDatabase,
|
||||
local_relay: Option<&nostr_relay_builder::LocalRelay>,
|
||||
local_relay: Option<&nostr_sdk::local_relay::LocalRelay>,
|
||||
purgatory: &Purgatory,
|
||||
git_data_path: &Path,
|
||||
promotion_hooks: Option<&dyn PurgatoryPromotionHooks>,
|
||||
@@ -1053,7 +1053,7 @@ async fn process_purgatory_state_events(
|
||||
identifier: &str,
|
||||
source_repo_path: &Path,
|
||||
database: &SharedDatabase,
|
||||
local_relay: Option<&nostr_relay_builder::LocalRelay>,
|
||||
local_relay: Option<&nostr_sdk::local_relay::LocalRelay>,
|
||||
purgatory: &Purgatory,
|
||||
git_data_path: &Path,
|
||||
promotion_hooks: Option<&dyn PurgatoryPromotionHooks>,
|
||||
@@ -1432,7 +1432,7 @@ async fn process_purgatory_pr_events(
|
||||
identifier: &str,
|
||||
source_repo_path: &Path,
|
||||
database: &SharedDatabase,
|
||||
local_relay: Option<&nostr_relay_builder::LocalRelay>,
|
||||
local_relay: Option<&nostr_sdk::local_relay::LocalRelay>,
|
||||
purgatory: &Purgatory,
|
||||
git_data_path: &Path,
|
||||
promotion_hooks: Option<&dyn PurgatoryPromotionHooks>,
|
||||
@@ -1574,7 +1574,7 @@ async fn process_purgatory_announcements(
|
||||
identifier: &str,
|
||||
source_repo_path: &Path,
|
||||
database: &SharedDatabase,
|
||||
local_relay: Option<&nostr_relay_builder::LocalRelay>,
|
||||
local_relay: Option<&nostr_sdk::local_relay::LocalRelay>,
|
||||
purgatory: &Purgatory,
|
||||
git_data_path: &Path,
|
||||
promotion_hooks: Option<&dyn PurgatoryPromotionHooks>,
|
||||
|
||||
@@ -64,7 +64,7 @@ use std::sync::Arc;
|
||||
use dashmap::DashMap;
|
||||
use hyper::body::{Bytes, Frame};
|
||||
use hyper::Response;
|
||||
use nostr_relay_builder::LocalRelay;
|
||||
use nostr_sdk::local_relay::LocalRelay;
|
||||
use nostr_sdk::prelude::*;
|
||||
use std::sync::Mutex;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
|
||||
+3
-3
@@ -10,6 +10,8 @@ use std::pin::Pin;
|
||||
use std::sync::Arc;
|
||||
|
||||
use base64::Engine;
|
||||
use bitcoin_hashes::sha1::Hash as Sha1Hash;
|
||||
use bitcoin_hashes::{Hash, HashEngine};
|
||||
use http_body_util::BodyExt;
|
||||
use hyper::body::{Bytes, Incoming};
|
||||
use hyper::header::{CONNECTION, SEC_WEBSOCKET_ACCEPT, UPGRADE};
|
||||
@@ -17,9 +19,7 @@ use hyper::server::conn::http1;
|
||||
use hyper::service::Service;
|
||||
use hyper::{Method, Request, Response};
|
||||
use hyper_util::rt::TokioIo;
|
||||
use nostr::hashes::sha1::Hash as Sha1Hash;
|
||||
use nostr::hashes::{Hash, HashEngine};
|
||||
use nostr_relay_builder::LocalRelay;
|
||||
use nostr_sdk::local_relay::LocalRelay;
|
||||
use nostr_sdk::prelude::PublicKey;
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
|
||||
@@ -4,16 +4,18 @@
|
||||
/// Deletion behaviour is owned by the `nostr::lifecycle` subsystem;
|
||||
/// this module keeps top-level `admit_event`
|
||||
/// dispatch and non-deletion admission/router policy logic.
|
||||
use std::future::Future;
|
||||
use std::net::SocketAddr;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::path::Path;
|
||||
use std::pin::Pin;
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use anyhow::Result;
|
||||
use nostr::nips::nip19::ToBech32;
|
||||
use nostr_lmdb::NostrLmdb;
|
||||
use nostr_memory::MemoryDatabase;
|
||||
use nostr_relay_builder::prelude::*;
|
||||
use nostr_sdk::prelude::*;
|
||||
|
||||
use crate::config::{Config, DatabaseBackend};
|
||||
use crate::nostr::events::RepositoryAnnouncement;
|
||||
@@ -143,7 +145,7 @@ impl Nip34WritePolicy {
|
||||
///
|
||||
/// This must be called after the relay is created since the relay depends
|
||||
/// on this policy, but purgatory sync needs the relay to notify subscribers.
|
||||
pub fn set_local_relay(&self, relay: nostr_relay_builder::LocalRelay) {
|
||||
pub fn set_local_relay(&self, relay: nostr_sdk::local_relay::LocalRelay) {
|
||||
self.ctx.set_local_relay(relay);
|
||||
}
|
||||
|
||||
@@ -163,7 +165,7 @@ impl Nip34WritePolicy {
|
||||
.clone()
|
||||
}
|
||||
|
||||
pub(crate) fn local_relay(&self) -> Option<nostr_relay_builder::LocalRelay> {
|
||||
pub(crate) fn local_relay(&self) -> Option<nostr_sdk::local_relay::LocalRelay> {
|
||||
self.ctx.get_local_relay()
|
||||
}
|
||||
|
||||
@@ -793,9 +795,9 @@ impl Nip34WritePolicy {
|
||||
impl WritePolicy for Nip34WritePolicy {
|
||||
fn admit_event<'a>(
|
||||
&'a self,
|
||||
event: &'a nostr_relay_builder::prelude::Event,
|
||||
event: &'a nostr_sdk::prelude::Event,
|
||||
addr: &'a SocketAddr,
|
||||
) -> BoxedFuture<'a, WritePolicyResult> {
|
||||
) -> Pin<Box<dyn Future<Output = WritePolicyResult> + Send + 'a>> {
|
||||
Box::pin(async move {
|
||||
// Check event blacklist FIRST - it overrides everything
|
||||
if let Some(reason) = self.check_event_blacklist(event) {
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::path::PathBuf;
|
||||
|
||||
use flate2::write::GzEncoder;
|
||||
use flate2::Compression;
|
||||
use nostr_relay_builder::prelude::{
|
||||
use nostr_sdk::prelude::{
|
||||
Alphabet, Event, EventId, Filter, Kind, PublicKey, SingleLetterTag, Timestamp,
|
||||
};
|
||||
use tar::Builder as TarBuilder;
|
||||
@@ -255,7 +255,7 @@ impl DeletionPolicy {
|
||||
&self,
|
||||
author: &PublicKey,
|
||||
coordinate: &str,
|
||||
deletion_created_at: nostr_relay_builder::prelude::Timestamp,
|
||||
deletion_created_at: nostr_sdk::prelude::Timestamp,
|
||||
moved_ids: &mut HashSet<EventId>,
|
||||
source: DeletionSource,
|
||||
) -> DeletionOutcome {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
|
||||
use nostr_relay_builder::prelude::{
|
||||
use nostr_sdk::prelude::{
|
||||
Alphabet, Event, EventId, Filter, Kind, PublicKey, SingleLetterTag, Timestamp,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use anyhow::Result;
|
||||
use nostr_relay_builder::prelude::{Filter, Kind, Timestamp};
|
||||
use nostr_sdk::prelude::{Filter, Kind, Timestamp};
|
||||
|
||||
use crate::nostr::lifecycle::RequestLifecycleRecord;
|
||||
|
||||
@@ -129,7 +129,7 @@ mod tests {
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use nostr_relay_builder::prelude::{Event, EventBuilder, EventId, FinalizeEvent, Keys, Tag};
|
||||
use nostr_sdk::prelude::{Event, EventBuilder, EventId, FinalizeEvent, Keys, Tag};
|
||||
|
||||
use super::*;
|
||||
use crate::grasp06::receive::new_repo_init_locks;
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use nostr::nips::nip19::ToBech32;
|
||||
use nostr_relay_builder::prelude::{
|
||||
use nostr_sdk::prelude::{
|
||||
Alphabet, Event, EventId, Filter, Kind, PublicKey, SingleLetterTag, Timestamp,
|
||||
WritePolicyResult,
|
||||
};
|
||||
@@ -414,7 +414,7 @@ mod tests {
|
||||
use crate::nostr::lifecycle::RequestLifecycleRecord;
|
||||
use crate::nostr::lifecycle::Tombstones;
|
||||
use crate::purgatory::Purgatory;
|
||||
use nostr_relay_builder::prelude::*;
|
||||
use nostr_sdk::prelude::*;
|
||||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
@@ -804,10 +804,10 @@ mod tests {
|
||||
let attacker_keys = Keys::generate();
|
||||
let victim_keys = Keys::generate();
|
||||
|
||||
let foreign_target = EventBuilder::text_note("real event from victim")
|
||||
let foreign_target = EventBuilder::new(Kind::TextNote, "real event from victim")
|
||||
.finalize(&victim_keys)
|
||||
.unwrap();
|
||||
let valid_target = EventBuilder::text_note("real event from deleter")
|
||||
let valid_target = EventBuilder::new(Kind::TextNote, "real event from deleter")
|
||||
.finalize(&attacker_keys)
|
||||
.unwrap();
|
||||
let deletion = EventBuilder::new(Kind::EventDeletion, "")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::collections::BTreeSet;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use nostr_relay_builder::prelude::{Event, Kind};
|
||||
use nostr_sdk::prelude::{Event, Kind};
|
||||
|
||||
use super::policy::{owner_directory_component, DeletionPolicy};
|
||||
use crate::git;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::collections::HashSet;
|
||||
use std::process::Command;
|
||||
|
||||
use nostr_relay_builder::prelude::{Event, Kind, Timestamp};
|
||||
use nostr_sdk::prelude::{Event, Kind, Timestamp};
|
||||
|
||||
use super::{policy::DeletionPolicy, DeletionOutcome};
|
||||
use crate::nostr::events::RepositoryAnnouncement;
|
||||
@@ -181,10 +181,10 @@ impl DeletionPolicy {
|
||||
/// Only removes entries whose author matches `author`.
|
||||
fn remove_by_event_id(
|
||||
&self,
|
||||
author: &nostr_relay_builder::prelude::PublicKey,
|
||||
author: &nostr_sdk::prelude::PublicKey,
|
||||
target_id_hex: &str,
|
||||
_deletion_created_at: u64,
|
||||
removed_ids: &mut HashSet<nostr_relay_builder::prelude::EventId>,
|
||||
removed_ids: &mut HashSet<nostr_sdk::prelude::EventId>,
|
||||
) -> DeletionOutcome {
|
||||
// --- Check PR events (kind 1617/1618) first — O(1) direct lookup ---
|
||||
// PR purgatory is keyed by event ID hex, so this is the cheapest check.
|
||||
@@ -273,10 +273,10 @@ impl DeletionPolicy {
|
||||
/// Per NIP-09, all versions up to `deletion_created_at` are considered deleted.
|
||||
fn remove_by_coordinate(
|
||||
&self,
|
||||
author: &nostr_relay_builder::prelude::PublicKey,
|
||||
author: &nostr_sdk::prelude::PublicKey,
|
||||
coordinate: &str,
|
||||
deletion_created_at: u64,
|
||||
removed_ids: &mut HashSet<nostr_relay_builder::prelude::EventId>,
|
||||
removed_ids: &mut HashSet<nostr_sdk::prelude::EventId>,
|
||||
) -> DeletionOutcome {
|
||||
let mut outcome = DeletionOutcome::default();
|
||||
// Parse coordinate: `<kind>:<pubkey>:<d-identifier>`
|
||||
@@ -356,9 +356,9 @@ impl DeletionPolicy {
|
||||
/// Remove a purgatory announcement and delete its bare repository from disk.
|
||||
fn evict_purgatory_entry(
|
||||
&self,
|
||||
author: &nostr_relay_builder::prelude::PublicKey,
|
||||
author: &nostr_sdk::prelude::PublicKey,
|
||||
identifier: &str,
|
||||
removed_ids: &mut HashSet<nostr_relay_builder::prelude::EventId>,
|
||||
removed_ids: &mut HashSet<nostr_sdk::prelude::EventId>,
|
||||
) -> DeletionOutcome {
|
||||
let mut outcome = DeletionOutcome::default();
|
||||
// Get repo path before removing
|
||||
|
||||
@@ -14,7 +14,7 @@ use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
use flate2::read::GzDecoder;
|
||||
use nostr_relay_builder::prelude::{Event, Kind, PublicKey, Timestamp};
|
||||
use nostr_sdk::prelude::{Event, Kind, PublicKey, Timestamp};
|
||||
use tar::Archive as TarArchive;
|
||||
|
||||
use super::DeletionService;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::collections::{BTreeSet, HashSet};
|
||||
|
||||
use nostr_relay_builder::prelude::{
|
||||
use nostr_sdk::prelude::{
|
||||
Alphabet, Event, EventId, Filter, Kind, PublicKey, SingleLetterTag, Timestamp,
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::time::Duration;
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::Args;
|
||||
use nostr_relay_builder::prelude::{PublicKey, Timestamp};
|
||||
use nostr_sdk::prelude::{PublicKey, Timestamp};
|
||||
use tokio::sync::watch;
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
@@ -263,7 +263,7 @@ mod tests {
|
||||
use std::sync::Arc;
|
||||
|
||||
use nostr_memory::MemoryDatabase;
|
||||
use nostr_relay_builder::prelude::{
|
||||
use nostr_sdk::prelude::{
|
||||
EventBuilder, EventId, FinalizeEvent, Keys, Kind, NostrDatabase, Tag,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use anyhow::Result;
|
||||
use nostr_relay_builder::prelude::{
|
||||
use nostr_sdk::prelude::{
|
||||
nip62, Alphabet, Event, Filter, Kind, PublicKey, RelayUrl, SingleLetterTag, Timestamp,
|
||||
WritePolicyResult,
|
||||
};
|
||||
@@ -876,7 +876,7 @@ mod tests {
|
||||
self.lifecycle_for_request_result(request_id).await.unwrap()
|
||||
}
|
||||
}
|
||||
use nostr_relay_builder::prelude::{EventBuilder, EventId, FinalizeEvent, Keys, Tag};
|
||||
use nostr_sdk::prelude::{EventBuilder, EventId, FinalizeEvent, Keys, Tag};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -904,7 +904,7 @@ mod tests {
|
||||
|
||||
fn vanish(keys: &Keys, content: &str) -> Event {
|
||||
EventBuilder::new(Kind::RequestToVanish, content)
|
||||
.tags(vec![nostr_relay_builder::prelude::Tag::custom(
|
||||
.tags(vec![nostr_sdk::prelude::Tag::custom(
|
||||
"relay",
|
||||
vec!["ALL_RELAYS".to_string()],
|
||||
)])
|
||||
@@ -914,7 +914,7 @@ mod tests {
|
||||
|
||||
fn non_targeting_vanish(keys: &Keys) -> Event {
|
||||
EventBuilder::new(Kind::RequestToVanish, "non-targeting")
|
||||
.tags(vec![nostr_relay_builder::prelude::Tag::custom(
|
||||
.tags(vec![nostr_sdk::prelude::Tag::custom(
|
||||
"relay",
|
||||
vec!["wss://other.example".to_string()],
|
||||
)])
|
||||
@@ -1230,9 +1230,7 @@ mod tests {
|
||||
let service = DeletionService::new(ctx.clone());
|
||||
let keys = Keys::generate();
|
||||
let state = EventBuilder::new(Kind::RepoState, "")
|
||||
.tags(vec![nostr_relay_builder::prelude::Tag::identifier(
|
||||
"purgatory-only",
|
||||
)])
|
||||
.tags(vec![nostr_sdk::prelude::Tag::identifier("purgatory-only")])
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
ctx.purgatory.add_state(
|
||||
@@ -1330,7 +1328,7 @@ mod tests {
|
||||
.unwrap();
|
||||
ctx.database.save_event(&target).await.unwrap();
|
||||
let state = EventBuilder::new(Kind::RepoState, "")
|
||||
.tags(vec![nostr_relay_builder::prelude::Tag::identifier(
|
||||
.tags(vec![nostr_sdk::prelude::Tag::identifier(
|
||||
"preserve-purgatory",
|
||||
)])
|
||||
.finalize(&keys)
|
||||
@@ -1376,7 +1374,7 @@ mod tests {
|
||||
let service = DeletionService::new(ctx.clone());
|
||||
let keys = Keys::generate();
|
||||
let state = EventBuilder::new(Kind::RepoState, "")
|
||||
.tags(vec![nostr_relay_builder::prelude::Tag::identifier(
|
||||
.tags(vec![nostr_sdk::prelude::Tag::identifier(
|
||||
"disrespector-purgatory",
|
||||
)])
|
||||
.finalize(&keys)
|
||||
|
||||
@@ -2,7 +2,7 @@ use nostr::nips::nip19::ToBech32;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use anyhow::Result;
|
||||
use nostr_relay_builder::prelude::{Event, Filter, Kind, PublicKey, Timestamp};
|
||||
use nostr_sdk::prelude::{Event, Filter, Kind, PublicKey, Timestamp};
|
||||
|
||||
use crate::nostr::events::RepositoryAnnouncement;
|
||||
use crate::nostr::lifecycle::{DeletionSource, RequestClassification};
|
||||
@@ -704,7 +704,7 @@ mod tests {
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use nostr_relay_builder::prelude::{EventBuilder, FinalizeEvent, Keys, Tag};
|
||||
use nostr_sdk::prelude::{EventBuilder, FinalizeEvent, Keys, Tag};
|
||||
|
||||
use super::super::DeletionContext;
|
||||
use super::*;
|
||||
|
||||
@@ -9,7 +9,7 @@ use std::sync::Arc;
|
||||
|
||||
use nostr_lmdb::NostrLmdb;
|
||||
use nostr_memory::MemoryDatabase;
|
||||
use nostr_relay_builder::prelude::{
|
||||
use nostr_sdk::prelude::{
|
||||
Alphabet, Event, EventBuilder, EventId, Filter, FinalizeEvent, Keys, Kind, NostrDatabase,
|
||||
SingleLetterTag, Tag, Timestamp,
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@ use std::{collections::BTreeSet, io::ErrorKind};
|
||||
|
||||
use nostr_lmdb::NostrLmdb;
|
||||
use nostr_memory::MemoryDatabase;
|
||||
use nostr_relay_builder::prelude::{
|
||||
use nostr_sdk::prelude::{
|
||||
Alphabet, Event, EventBuilder, EventId, Filter, FinalizeEvent, Keys, Kind, NostrDatabase,
|
||||
SingleLetterTag, Tag, Timestamp,
|
||||
};
|
||||
|
||||
@@ -217,7 +217,7 @@ impl RepositoryLifecycle {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use nostr_relay_builder::prelude::Keys;
|
||||
use nostr_sdk::prelude::Keys;
|
||||
|
||||
#[tokio::test]
|
||||
async fn lifecycle_read_locks_can_be_held_concurrently() {
|
||||
|
||||
@@ -50,7 +50,7 @@ use tokio::sync::{Mutex, MutexGuard};
|
||||
|
||||
use nostr_lmdb::NostrLmdb;
|
||||
use nostr_memory::MemoryDatabase;
|
||||
use nostr_relay_builder::prelude::{
|
||||
use nostr_sdk::prelude::{
|
||||
Alphabet, Event, EventBuilder, EventId, Filter, FinalizeEvent, Keys, Kind, NostrDatabase,
|
||||
PublicKey, SingleLetterTag, Tag, Timestamp,
|
||||
};
|
||||
|
||||
+1
-1
@@ -5,4 +5,4 @@ pub mod persistence;
|
||||
pub mod policy;
|
||||
|
||||
/// Shared database type used across nostr modules.
|
||||
pub type SharedDatabase = std::sync::Arc<dyn nostr_relay_builder::prelude::NostrDatabase>;
|
||||
pub type SharedDatabase = std::sync::Arc<dyn nostr_sdk::prelude::NostrDatabase>;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
//! module provides the direct accepted-event save facade for paths outside the
|
||||
//! relay builder.
|
||||
|
||||
use nostr_relay_builder::prelude::Event;
|
||||
use nostr_sdk::prelude::Event;
|
||||
|
||||
use crate::nostr::SharedDatabase;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
///
|
||||
/// Handles validation of NIP-34 repository announcements (kind 30617)
|
||||
/// according to GRASP-01 specification.
|
||||
use nostr_relay_builder::prelude::{Alphabet, Event, Filter, Kind, PublicKey, SingleLetterTag};
|
||||
use nostr_sdk::prelude::{Alphabet, Event, Filter, Kind, PublicKey, SingleLetterTag};
|
||||
use std::collections::HashSet;
|
||||
use std::time::Duration;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ pub use crate::git::sync::AlignmentResult;
|
||||
|
||||
use super::SharedDatabase;
|
||||
use crate::purgatory::Purgatory;
|
||||
use nostr_relay_builder::LocalRelay;
|
||||
use nostr_sdk::local_relay::LocalRelay;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Shared context for all sub-policies
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/// Handles validation of NIP-34 PR events (kind 1618) and PR Update events (kind 1619)
|
||||
/// according to GRASP-01 specification.
|
||||
use anyhow::{bail, Result};
|
||||
use nostr_relay_builder::prelude::Event;
|
||||
use nostr_sdk::prelude::Event;
|
||||
|
||||
use super::PolicyContext;
|
||||
use crate::git;
|
||||
|
||||
@@ -3,9 +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_relay_builder::prelude::{
|
||||
Alphabet, Event, EventId, Filter, Kind, PublicKey, SingleLetterTag,
|
||||
};
|
||||
use nostr_sdk::prelude::{Alphabet, Event, EventId, Filter, Kind, PublicKey, SingleLetterTag};
|
||||
|
||||
use super::PolicyContext;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ use std::borrow::Cow;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use nostr::message::relay::SingleWord;
|
||||
use nostr_relay_builder::prelude::{MachineReadablePrefix, WritePolicyResult};
|
||||
use nostr_sdk::prelude::{MachineReadablePrefix, WritePolicyResult};
|
||||
|
||||
/// The `purgatory:` machine-readable prefix.
|
||||
///
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use nostr_relay_builder::builder::WritePolicyResult;
|
||||
use nostr_sdk::local_relay::WritePolicyResult;
|
||||
/// State Policy - State event validation + ref alignment
|
||||
///
|
||||
/// Handles validation of NIP-34 repository state events (kind 30618)
|
||||
/// and aligns git refs with authorized state according to GRASP-01.
|
||||
use nostr_relay_builder::prelude::Event;
|
||||
use nostr_sdk::prelude::Event;
|
||||
|
||||
use super::{accepted_purgatory, duplicate, reject_invalid, reject_restricted, PolicyContext};
|
||||
use crate::git;
|
||||
|
||||
+83
-35
@@ -1843,7 +1843,9 @@ mod tests {
|
||||
|
||||
// Add some test data
|
||||
let keys = Keys::generate();
|
||||
let event = EventBuilder::text_note("test").finalize(&keys).unwrap();
|
||||
let event = EventBuilder::new(Kind::TextNote, "test")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
|
||||
purgatory.add_state(
|
||||
event.clone(),
|
||||
@@ -1905,7 +1907,9 @@ mod tests {
|
||||
assert!(!purgatory.has_pending_events("test-repo"));
|
||||
|
||||
// Add a state event
|
||||
let event = EventBuilder::text_note("state").finalize(&keys).unwrap();
|
||||
let event = EventBuilder::new(Kind::TextNote, "state")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
purgatory.add_state(event, "test-repo".to_string(), keys.public_key(), false);
|
||||
|
||||
// Now should have pending events
|
||||
@@ -1997,7 +2001,9 @@ mod tests {
|
||||
fn test_pr_event_vs_placeholder() {
|
||||
let purgatory = Purgatory::new(PathBuf::new());
|
||||
let keys = Keys::generate();
|
||||
let event = EventBuilder::text_note("test PR").finalize(&keys).unwrap();
|
||||
let event = EventBuilder::new(Kind::TextNote, "test PR")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
|
||||
// Add a PR event with actual event
|
||||
purgatory.add_pr(
|
||||
@@ -2049,10 +2055,12 @@ fn test_cleanup_removes_expired_entries() {
|
||||
let keys = Keys::generate();
|
||||
|
||||
// Create events
|
||||
let state_event = EventBuilder::text_note("state event")
|
||||
let state_event = EventBuilder::new(Kind::TextNote, "state event")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
let pr_event = EventBuilder::new(Kind::TextNote, "pr event")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
let pr_event = EventBuilder::text_note("pr event").finalize(&keys).unwrap();
|
||||
|
||||
// Add entries to purgatory
|
||||
purgatory.add_state(
|
||||
@@ -2105,10 +2113,12 @@ fn test_cleanup_preserves_non_expired_entries() {
|
||||
let purgatory = Purgatory::new(PathBuf::new());
|
||||
let keys = Keys::generate();
|
||||
|
||||
let state_event = EventBuilder::text_note("state event")
|
||||
let state_event = EventBuilder::new(Kind::TextNote, "state event")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
let pr_event = EventBuilder::new(Kind::TextNote, "pr event")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
let pr_event = EventBuilder::text_note("pr event").finalize(&keys).unwrap();
|
||||
|
||||
// Add fresh entries
|
||||
purgatory.add_state(
|
||||
@@ -2145,8 +2155,12 @@ fn test_cleanup_mixed_expired_and_fresh() {
|
||||
let keys = Keys::generate();
|
||||
|
||||
// Add multiple state events for same repo
|
||||
let event1 = EventBuilder::text_note("event1").finalize(&keys).unwrap();
|
||||
let event2 = EventBuilder::text_note("event2").finalize(&keys).unwrap();
|
||||
let event1 = EventBuilder::new(Kind::TextNote, "event1")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
let event2 = EventBuilder::new(Kind::TextNote, "event2")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
|
||||
purgatory.add_state(event1, "test-repo".to_string(), keys.public_key(), false);
|
||||
purgatory.add_state(event2, "test-repo".to_string(), keys.public_key(), false);
|
||||
@@ -2159,8 +2173,12 @@ fn test_cleanup_mixed_expired_and_fresh() {
|
||||
}
|
||||
|
||||
// Add PR events
|
||||
let pr1 = EventBuilder::text_note("pr1").finalize(&keys).unwrap();
|
||||
let pr2 = EventBuilder::text_note("pr2").finalize(&keys).unwrap();
|
||||
let pr1 = EventBuilder::new(Kind::TextNote, "pr1")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
let pr2 = EventBuilder::new(Kind::TextNote, "pr2")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
|
||||
purgatory.add_pr(pr1, "pr-1".to_string(), "commit-1".to_string(), false);
|
||||
purgatory.add_pr(pr2, "pr-2".to_string(), "commit-2".to_string(), false);
|
||||
@@ -2190,8 +2208,12 @@ fn test_remove_expired_legacy_method() {
|
||||
let purgatory = Purgatory::new(PathBuf::new());
|
||||
let keys = Keys::generate();
|
||||
|
||||
let state_event = EventBuilder::text_note("state").finalize(&keys).unwrap();
|
||||
let pr_event = EventBuilder::text_note("pr").finalize(&keys).unwrap();
|
||||
let state_event = EventBuilder::new(Kind::TextNote, "state")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
let pr_event = EventBuilder::new(Kind::TextNote, "pr")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
|
||||
purgatory.add_state(state_event, "repo".to_string(), keys.public_key(), false);
|
||||
purgatory.add_pr(pr_event, "pr-id".to_string(), "commit".to_string(), false);
|
||||
@@ -2219,8 +2241,12 @@ fn test_expired_event_tracking() {
|
||||
let purgatory = Purgatory::new(PathBuf::new());
|
||||
let keys = Keys::generate();
|
||||
|
||||
let state_event = EventBuilder::text_note("state").finalize(&keys).unwrap();
|
||||
let pr_event = EventBuilder::text_note("pr").finalize(&keys).unwrap();
|
||||
let state_event = EventBuilder::new(Kind::TextNote, "state")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
let pr_event = EventBuilder::new(Kind::TextNote, "pr")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
|
||||
let state_event_id = state_event.id;
|
||||
let pr_event_id = pr_event.id;
|
||||
@@ -2268,8 +2294,12 @@ fn test_cleanup_expired_events() {
|
||||
let purgatory = Purgatory::new(PathBuf::new());
|
||||
let keys = Keys::generate();
|
||||
|
||||
let event1 = EventBuilder::text_note("event1").finalize(&keys).unwrap();
|
||||
let event2 = EventBuilder::text_note("event2").finalize(&keys).unwrap();
|
||||
let event1 = EventBuilder::new(Kind::TextNote, "event1")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
let event2 = EventBuilder::new(Kind::TextNote, "event2")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
|
||||
let event1_id = event1.id;
|
||||
let event2_id = event2.id;
|
||||
@@ -2320,7 +2350,9 @@ fn test_expired_events_prevent_readdition() {
|
||||
let purgatory = Purgatory::new(PathBuf::new());
|
||||
let keys = Keys::generate();
|
||||
|
||||
let event = EventBuilder::text_note("test").finalize(&keys).unwrap();
|
||||
let event = EventBuilder::new(Kind::TextNote, "test")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
let event_id = event.id;
|
||||
|
||||
// Add event to purgatory
|
||||
@@ -2381,7 +2413,9 @@ fn test_user_can_resubmit_expired_event() {
|
||||
let purgatory = Purgatory::new(PathBuf::new());
|
||||
let keys = Keys::generate();
|
||||
|
||||
let event = EventBuilder::text_note("test").finalize(&keys).unwrap();
|
||||
let event = EventBuilder::new(Kind::TextNote, "test")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
let event_id = event.id;
|
||||
|
||||
// Add event to purgatory
|
||||
@@ -2424,10 +2458,10 @@ async fn test_save_and_restore_state_events() {
|
||||
let keys = Keys::generate();
|
||||
|
||||
// Add multiple state events for the same identifier
|
||||
let event1 = EventBuilder::text_note("state event 1")
|
||||
let event1 = EventBuilder::new(Kind::TextNote, "state event 1")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
let event2 = EventBuilder::text_note("state event 2")
|
||||
let event2 = EventBuilder::new(Kind::TextNote, "state event 2")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
|
||||
@@ -2568,7 +2602,9 @@ async fn test_save_and_restore_expired_events() {
|
||||
let purgatory = Purgatory::new(PathBuf::new());
|
||||
let keys = Keys::generate();
|
||||
|
||||
let event = EventBuilder::text_note("test").finalize(&keys).unwrap();
|
||||
let event = EventBuilder::new(Kind::TextNote, "test")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
let event_id = event.id;
|
||||
|
||||
// Add and expire event
|
||||
@@ -2707,7 +2743,9 @@ async fn test_downtime_calculation() {
|
||||
let keys = Keys::generate();
|
||||
|
||||
// Add state event
|
||||
let event = EventBuilder::text_note("test").finalize(&keys).unwrap();
|
||||
let event = EventBuilder::new(Kind::TextNote, "test")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
|
||||
purgatory.add_state(event.clone(), "repo".to_string(), keys.public_key(), false);
|
||||
|
||||
@@ -2761,7 +2799,9 @@ async fn test_expiry_times_preserved() {
|
||||
let keys = Keys::generate();
|
||||
|
||||
// Add state event
|
||||
let event = EventBuilder::text_note("test").finalize(&keys).unwrap();
|
||||
let event = EventBuilder::new(Kind::TextNote, "test")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
|
||||
purgatory.add_state(event.clone(), "repo".to_string(), keys.public_key(), false);
|
||||
|
||||
@@ -2808,13 +2848,13 @@ async fn test_multiple_state_events_same_identifier() {
|
||||
let keys3 = Keys::generate();
|
||||
|
||||
// Add multiple state events for the same identifier from different authors
|
||||
let event1 = EventBuilder::text_note("maintainer 1")
|
||||
let event1 = EventBuilder::new(Kind::TextNote, "maintainer 1")
|
||||
.finalize(&keys1)
|
||||
.unwrap();
|
||||
let event2 = EventBuilder::text_note("maintainer 2")
|
||||
let event2 = EventBuilder::new(Kind::TextNote, "maintainer 2")
|
||||
.finalize(&keys2)
|
||||
.unwrap();
|
||||
let event3 = EventBuilder::text_note("maintainer 3")
|
||||
let event3 = EventBuilder::new(Kind::TextNote, "maintainer 3")
|
||||
.finalize(&keys3)
|
||||
.unwrap();
|
||||
|
||||
@@ -2973,7 +3013,9 @@ async fn test_file_cleanup_after_successful_restore() {
|
||||
let keys = Keys::generate();
|
||||
|
||||
// Add some data
|
||||
let event = EventBuilder::text_note("test").finalize(&keys).unwrap();
|
||||
let event = EventBuilder::new(Kind::TextNote, "test")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
purgatory.add_state(event, "repo".to_string(), keys.public_key(), false);
|
||||
|
||||
// Save to disk
|
||||
@@ -3002,7 +3044,7 @@ async fn test_save_and_restore_announcement_events() {
|
||||
let purgatory = Purgatory::new(PathBuf::new());
|
||||
let keys = Keys::generate();
|
||||
|
||||
let ann_event = EventBuilder::text_note("announcement event")
|
||||
let ann_event = EventBuilder::new(Kind::TextNote, "announcement event")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
let ann_event_id = ann_event.id;
|
||||
@@ -3057,7 +3099,7 @@ async fn test_soft_expired_announcements_not_persisted() {
|
||||
let purgatory = Purgatory::new(PathBuf::new());
|
||||
let keys = Keys::generate();
|
||||
|
||||
let ann_event = EventBuilder::text_note("announcement event")
|
||||
let ann_event = EventBuilder::new(Kind::TextNote, "announcement event")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
|
||||
@@ -3100,7 +3142,7 @@ async fn test_announcement_with_missing_repo_skipped_on_restore() {
|
||||
let purgatory = Purgatory::new(PathBuf::new());
|
||||
let keys = Keys::generate();
|
||||
|
||||
let ann_event = EventBuilder::text_note("announcement event")
|
||||
let ann_event = EventBuilder::new(Kind::TextNote, "announcement event")
|
||||
.finalize(&keys)
|
||||
.unwrap();
|
||||
|
||||
@@ -3140,7 +3182,7 @@ async fn test_comprehensive_roundtrip() {
|
||||
let keys2 = Keys::generate();
|
||||
|
||||
// Add announcement
|
||||
let ann_event = EventBuilder::text_note("announcement")
|
||||
let ann_event = EventBuilder::new(Kind::TextNote, "announcement")
|
||||
.finalize(&keys1)
|
||||
.unwrap();
|
||||
let ann_event_id = ann_event.id;
|
||||
@@ -3153,8 +3195,12 @@ async fn test_comprehensive_roundtrip() {
|
||||
);
|
||||
|
||||
// Add multiple state events
|
||||
let state1 = EventBuilder::text_note("state 1").finalize(&keys1).unwrap();
|
||||
let state2 = EventBuilder::text_note("state 2").finalize(&keys2).unwrap();
|
||||
let state1 = EventBuilder::new(Kind::TextNote, "state 1")
|
||||
.finalize(&keys1)
|
||||
.unwrap();
|
||||
let state2 = EventBuilder::new(Kind::TextNote, "state 2")
|
||||
.finalize(&keys2)
|
||||
.unwrap();
|
||||
|
||||
purgatory.add_state(
|
||||
state1.clone(),
|
||||
@@ -3186,7 +3232,9 @@ async fn test_comprehensive_roundtrip() {
|
||||
purgatory.add_pr_placeholder("pr-2".to_string(), "commit-2".to_string());
|
||||
|
||||
// Add and expire an event
|
||||
let expired_event = EventBuilder::text_note("expired").finalize(&keys1).unwrap();
|
||||
let expired_event = EventBuilder::new(Kind::TextNote, "expired")
|
||||
.finalize(&keys1)
|
||||
.unwrap();
|
||||
let expired_id = expired_event.id;
|
||||
purgatory.add_state(
|
||||
expired_event,
|
||||
|
||||
@@ -9,9 +9,9 @@ use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use nostr_relay_builder::prelude::{Event, WritePolicy, WritePolicyResult};
|
||||
use nostr_relay_builder::LocalRelay;
|
||||
use nostr_sdk::local_relay::LocalRelay;
|
||||
use nostr_sdk::prelude::PublicKey;
|
||||
use nostr_sdk::prelude::{Event, WritePolicy, WritePolicyResult};
|
||||
use tracing::{debug, info, warn};
|
||||
|
||||
use crate::git::sync::{PurgatoryPromotionHooks, PurgatorySaveContext};
|
||||
|
||||
@@ -189,7 +189,7 @@ pub trait SyncContext: Send + Sync {
|
||||
// Real Implementation
|
||||
// =============================================================================
|
||||
|
||||
use nostr_relay_builder::LocalRelay;
|
||||
use nostr_sdk::local_relay::LocalRelay;
|
||||
use std::process::Command;
|
||||
use std::sync::Arc;
|
||||
use tracing::debug;
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use nostr_relay_builder::LocalRelay;
|
||||
use nostr_sdk::local_relay::LocalRelay;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio::task::JoinHandle;
|
||||
use tracing::{error, info, warn};
|
||||
|
||||
+3
-3
@@ -52,7 +52,7 @@ use tokio::sync::{broadcast, Mutex, RwLock, Semaphore};
|
||||
use crate::config::Config;
|
||||
use crate::nostr::builder::Nip34WritePolicy;
|
||||
use crate::nostr::SharedDatabase;
|
||||
use nostr_relay_builder::prelude::LocalRelay;
|
||||
use nostr_sdk::prelude::LocalRelay;
|
||||
|
||||
const MAX_PURGATORY_DEPENDENCY_EVENTS_PER_TICK: usize = 32;
|
||||
const MAX_PURGATORY_FILTER_ACTIONS_PER_TICK: usize = 1;
|
||||
@@ -3699,7 +3699,7 @@ impl SyncManager {
|
||||
rejected_events_index: &Arc<RejectedEventsIndex>,
|
||||
save_context: crate::nostr::persistence::SaveContext,
|
||||
) -> ProcessResult {
|
||||
use nostr_relay_builder::prelude::{WritePolicy, WritePolicyResult};
|
||||
use nostr_sdk::prelude::{WritePolicy, WritePolicyResult};
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||
// Check if event already exists
|
||||
match database.event_by_id(&event.id).await {
|
||||
@@ -5076,7 +5076,7 @@ mod tests {
|
||||
.expect("build metadata event");
|
||||
pagination.record_event(&event);
|
||||
}
|
||||
let note = EventBuilder::text_note("one note")
|
||||
let note = EventBuilder::new(Kind::TextNote, "one note")
|
||||
.custom_created_at(Timestamp::from_secs(100))
|
||||
.finalize(&keys)
|
||||
.expect("build text note");
|
||||
|
||||
+22
-17
@@ -1036,11 +1036,11 @@ impl RejectedEventsIndex {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use nostr_sdk::prelude::{EventBuilder, FinalizeUnsignedEvent, Keys, SignEvent};
|
||||
use nostr_sdk::prelude::{EventBuilder, FinalizeUnsignedEvent, Keys, Kind, SignEvent};
|
||||
|
||||
async fn create_test_event() -> Event {
|
||||
let keys = Keys::generate();
|
||||
let unsigned = nostr_sdk::prelude::EventBuilder::text_note("test")
|
||||
let unsigned = nostr_sdk::prelude::EventBuilder::new(Kind::TextNote, "test")
|
||||
.finalize_unsigned(keys.public_key());
|
||||
keys.sign_event(unsigned).unwrap()
|
||||
}
|
||||
@@ -1290,10 +1290,15 @@ mod tests {
|
||||
RejectedEventsIndex::new(Duration::from_millis(50), Duration::from_secs(604800));
|
||||
let keys = Keys::generate();
|
||||
let dependency_event = keys
|
||||
.sign_event(EventBuilder::text_note("dependency").finalize_unsigned(keys.public_key()))
|
||||
.sign_event(
|
||||
EventBuilder::new(Kind::TextNote, "dependency")
|
||||
.finalize_unsigned(keys.public_key()),
|
||||
)
|
||||
.unwrap();
|
||||
let permanent_event = keys
|
||||
.sign_event(EventBuilder::text_note("permanent").finalize_unsigned(keys.public_key()))
|
||||
.sign_event(
|
||||
EventBuilder::new(Kind::TextNote, "permanent").finalize_unsigned(keys.public_key()),
|
||||
)
|
||||
.unwrap();
|
||||
let pubkey = keys.public_key();
|
||||
let identifier = "test-repo".to_string();
|
||||
@@ -1329,11 +1334,11 @@ mod tests {
|
||||
let keys1 = Keys::generate();
|
||||
let keys2 = Keys::generate();
|
||||
|
||||
let unsigned1 = nostr_sdk::prelude::EventBuilder::text_note("test1")
|
||||
let unsigned1 = nostr_sdk::prelude::EventBuilder::new(Kind::TextNote, "test1")
|
||||
.finalize_unsigned(keys1.public_key());
|
||||
let event1 = keys1.sign_event(unsigned1).unwrap();
|
||||
|
||||
let unsigned2 = nostr_sdk::prelude::EventBuilder::text_note("test2")
|
||||
let unsigned2 = nostr_sdk::prelude::EventBuilder::new(Kind::TextNote, "test2")
|
||||
.finalize_unsigned(keys2.public_key());
|
||||
let event2 = keys2.sign_event(unsigned2).unwrap();
|
||||
|
||||
@@ -1374,12 +1379,12 @@ mod tests {
|
||||
let keys = Keys::generate();
|
||||
|
||||
// Create an announcement event
|
||||
let unsigned_ann = nostr_sdk::prelude::EventBuilder::text_note("announcement")
|
||||
let unsigned_ann = nostr_sdk::prelude::EventBuilder::new(Kind::TextNote, "announcement")
|
||||
.finalize_unsigned(keys.public_key());
|
||||
let event_ann = keys.sign_event(unsigned_ann).unwrap();
|
||||
|
||||
// Create a state event
|
||||
let unsigned_state = nostr_sdk::prelude::EventBuilder::text_note("state")
|
||||
let unsigned_state = nostr_sdk::prelude::EventBuilder::new(Kind::TextNote, "state")
|
||||
.finalize_unsigned(keys.public_key());
|
||||
let event_state = keys.sign_event(unsigned_state).unwrap();
|
||||
|
||||
@@ -1434,12 +1439,12 @@ mod tests {
|
||||
let keys = Keys::generate();
|
||||
|
||||
// Create an announcement event
|
||||
let unsigned_ann = nostr_sdk::prelude::EventBuilder::text_note("announcement")
|
||||
let unsigned_ann = nostr_sdk::prelude::EventBuilder::new(Kind::TextNote, "announcement")
|
||||
.finalize_unsigned(keys.public_key());
|
||||
let event_ann = keys.sign_event(unsigned_ann).unwrap();
|
||||
|
||||
// Create a state event
|
||||
let unsigned_state = nostr_sdk::prelude::EventBuilder::text_note("state")
|
||||
let unsigned_state = nostr_sdk::prelude::EventBuilder::new(Kind::TextNote, "state")
|
||||
.finalize_unsigned(keys.public_key());
|
||||
let event_state = keys.sign_event(unsigned_state).unwrap();
|
||||
|
||||
@@ -1581,11 +1586,11 @@ mod tests {
|
||||
let keys = Keys::generate();
|
||||
|
||||
// Create two events
|
||||
let unsigned1 = nostr_sdk::prelude::EventBuilder::text_note("event1")
|
||||
let unsigned1 = nostr_sdk::prelude::EventBuilder::new(Kind::TextNote, "event1")
|
||||
.finalize_unsigned(keys.public_key());
|
||||
let event1 = keys.sign_event(unsigned1).unwrap();
|
||||
|
||||
let unsigned2 = nostr_sdk::prelude::EventBuilder::text_note("event2")
|
||||
let unsigned2 = nostr_sdk::prelude::EventBuilder::new(Kind::TextNote, "event2")
|
||||
.finalize_unsigned(keys.public_key());
|
||||
let event2 = keys.sign_event(unsigned2).unwrap();
|
||||
|
||||
@@ -1794,12 +1799,12 @@ mod tests {
|
||||
let keys = Keys::generate();
|
||||
|
||||
// Create announcement event
|
||||
let unsigned_ann = nostr_sdk::prelude::EventBuilder::text_note("announcement")
|
||||
let unsigned_ann = nostr_sdk::prelude::EventBuilder::new(Kind::TextNote, "announcement")
|
||||
.finalize_unsigned(keys.public_key());
|
||||
let event_ann = keys.sign_event(unsigned_ann).unwrap();
|
||||
|
||||
// Create state event
|
||||
let unsigned_state = nostr_sdk::prelude::EventBuilder::text_note("state")
|
||||
let unsigned_state = nostr_sdk::prelude::EventBuilder::new(Kind::TextNote, "state")
|
||||
.finalize_unsigned(keys.public_key());
|
||||
let event_state = keys.sign_event(unsigned_state).unwrap();
|
||||
|
||||
@@ -1849,15 +1854,15 @@ mod tests {
|
||||
let keys = Keys::generate();
|
||||
|
||||
// Create events with different rejection reasons
|
||||
let unsigned1 = nostr_sdk::prelude::EventBuilder::text_note("event1")
|
||||
let unsigned1 = nostr_sdk::prelude::EventBuilder::new(Kind::TextNote, "event1")
|
||||
.finalize_unsigned(keys.public_key());
|
||||
let event1 = keys.sign_event(unsigned1).unwrap();
|
||||
|
||||
let unsigned2 = nostr_sdk::prelude::EventBuilder::text_note("event2")
|
||||
let unsigned2 = nostr_sdk::prelude::EventBuilder::new(Kind::TextNote, "event2")
|
||||
.finalize_unsigned(keys.public_key());
|
||||
let event2 = keys.sign_event(unsigned2).unwrap();
|
||||
|
||||
let unsigned3 = nostr_sdk::prelude::EventBuilder::text_note("event3")
|
||||
let unsigned3 = nostr_sdk::prelude::EventBuilder::new(Kind::TextNote, "event3")
|
||||
.finalize_unsigned(keys.public_key());
|
||||
let event3 = keys.sign_event(unsigned3).unwrap();
|
||||
|
||||
|
||||
@@ -735,7 +735,7 @@ impl RelayConnection {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use nostr_relay_builder::prelude::LocalRelayBuilder;
|
||||
use nostr_sdk::prelude::LocalRelayBuilder;
|
||||
use std::future::pending;
|
||||
|
||||
#[tokio::test]
|
||||
@@ -804,7 +804,7 @@ mod tests {
|
||||
let other = LocalRelayBuilder::default().build();
|
||||
other.run().await.expect("start other relay");
|
||||
|
||||
let expected = EventBuilder::text_note("only on the other relay")
|
||||
let expected = EventBuilder::new(Kind::TextNote, "only on the other relay")
|
||||
.finalize(&Keys::generate())
|
||||
.expect("build event");
|
||||
other
|
||||
|
||||
@@ -43,7 +43,7 @@ use hyper::server::conn::http1;
|
||||
use hyper::service::service_fn;
|
||||
use hyper::{Request, Response, StatusCode};
|
||||
use hyper_util::rt::TokioIo;
|
||||
use nostr_relay_builder::prelude::*;
|
||||
use nostr_sdk::prelude::*;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio::sync::oneshot;
|
||||
|
||||
@@ -267,8 +267,8 @@ async fn handle_request(
|
||||
|
||||
/// Derive the Sec-WebSocket-Accept key from the request key.
|
||||
fn derive_accept_key(request_key: &[u8]) -> String {
|
||||
use nostr::hashes::sha1::Hash as Sha1Hash;
|
||||
use nostr::hashes::{Hash, HashEngine};
|
||||
use bitcoin_hashes::sha1::Hash as Sha1Hash;
|
||||
use bitcoin_hashes::{Hash, HashEngine};
|
||||
|
||||
const WS_GUID: &[u8] = b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||
|
||||
@@ -307,6 +307,9 @@ async fn wait_for_server_ready(port: u16) {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
// Disambiguate from `nostr_sdk::local_relay::MockRelay`, which the SDK
|
||||
// prelude also exports since the relay builder was merged into nostr-sdk.
|
||||
use super::MockRelay;
|
||||
use nostr_sdk::prelude::*;
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -339,7 +342,7 @@ mod tests {
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
|
||||
// Create and send a simple event
|
||||
let event = EventBuilder::text_note("Test note from MockRelay test")
|
||||
let event = EventBuilder::new(Kind::TextNote, "Test note from MockRelay test")
|
||||
.finalize(&keys)
|
||||
.expect("Failed to sign event");
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ use ngit_grasp::nostr::lifecycle::{
|
||||
use ngit_grasp::nostr::SharedDatabase;
|
||||
use ngit_grasp::purgatory::Purgatory;
|
||||
use ngit_grasp::sync::rejected_index::RejectedEventsIndex;
|
||||
use nostr_relay_builder::prelude::LocalRelayBuilder;
|
||||
use nostr_sdk::prelude::LocalRelayBuilder;
|
||||
use nostr_sdk::prelude::*;
|
||||
use tokio::sync::Semaphore;
|
||||
use tokio::time::timeout;
|
||||
|
||||
@@ -357,7 +357,7 @@ async fn newer_30617_supersedes_older_and_preserves_old_in_history() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn sync_style_admit_then_save_captures_superseded_history_once() {
|
||||
use nostr_relay_builder::prelude::{WritePolicy, WritePolicyResult};
|
||||
use nostr_sdk::prelude::{WritePolicy, WritePolicyResult};
|
||||
|
||||
let git_dir = tempfile::tempdir().expect("git tempdir");
|
||||
let db: SharedDatabase = Arc::new(nostr_memory::MemoryDatabase::unbounded());
|
||||
|
||||
@@ -40,7 +40,9 @@ use std::time::Duration;
|
||||
|
||||
/// Helper to create a test event
|
||||
async fn create_test_event(keys: &Keys, content: &str) -> Event {
|
||||
EventBuilder::text_note(content).finalize(keys).unwrap()
|
||||
EventBuilder::new(Kind::TextNote, content)
|
||||
.finalize(keys)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Helper to create a state event with specific refs
|
||||
|
||||
Reference in New Issue
Block a user