diff --git a/CHANGELOG.md b/CHANGELOG.md index 13af3a8..8a330b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. diff --git a/Cargo.lock b/Cargo.lock index 1c03472..2f75cd5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", ] diff --git a/Cargo.toml b/Cargo.toml index 97e148c..48eed7f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/docs/explanation/sync-scaling-constraints.md b/docs/explanation/sync-scaling-constraints.md index c3d7aee..794a068 100644 --- a/docs/explanation/sync-scaling-constraints.md +++ b/docs/explanation/sync-scaling-constraints.md @@ -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 diff --git a/grasp-audit/Cargo.toml b/grasp-audit/Cargo.toml index a418e07..503c3c8 100644 --- a/grasp-audit/Cargo.toml +++ b/grasp-audit/Cargo.toml @@ -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"] } diff --git a/grasp-audit/src/client.rs b/grasp-audit/src/client.rs index b62067d..4096807 100644 --- a/grasp-audit/src/client.rs +++ b/grasp-audit/src/client.rs @@ -434,12 +434,12 @@ impl AuditClient { /// Query events, optionally filtered to this audit run pub async fn query(&self, mut filter: Filter) -> Result> { - 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)); diff --git a/grasp-audit/src/probe.rs b/grasp-audit/src/probe.rs index 3cf0023..6414ed8 100644 --- a/grasp-audit/src/probe.rs +++ b/grasp-audit/src/probe.rs @@ -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 diff --git a/grasp-audit/src/specs/grasp01/nip01_smoke.rs b/grasp-audit/src/specs/grasp01/nip01_smoke.rs index 843bc81..f36bcbd 100644 --- a/grasp-audit/src/specs/grasp01/nip01_smoke.rs +++ b/grasp-audit/src/specs/grasp01/nip01_smoke.rs @@ -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(), diff --git a/src/git/authorization.rs b/src/git/authorization.rs index a4bd260..dfc1f8a 100644 --- a/src/git/authorization.rs +++ b/src/git/authorization.rs @@ -214,10 +214,7 @@ pub async fn fetch_repository_data_excluding_purgatory( ) -> Result { 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 = 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 diff --git a/src/nostr/builder.rs b/src/nostr/builder.rs index 655164b..2402857 100644 --- a/src/nostr/builder.rs +++ b/src/nostr/builder.rs @@ -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 = match self.ctx.database.query(filter).await { Ok(events) => events.into_iter().collect(), Err(error) => { diff --git a/src/nostr/lifecycle/deletion/archival.rs b/src/nostr/lifecycle/deletion/archival.rs index 13fc35e..d16ca51 100644 --- a/src/nostr/lifecycle/deletion/archival.rs +++ b/src/nostr/lifecycle/deletion/archival.rs @@ -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() => { diff --git a/src/nostr/lifecycle/deletion/cascade.rs b/src/nostr/lifecycle/deletion/cascade.rs index 9f5c624..5e58391 100644 --- a/src/nostr/lifecycle/deletion/cascade.rs +++ b/src/nostr/lifecycle/deletion/cascade.rs @@ -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, 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, ) diff --git a/src/nostr/lifecycle/deletion/cleanup.rs b/src/nostr/lifecycle/deletion/cleanup.rs index b352e10..c732fe8 100644 --- a/src/nostr/lifecycle/deletion/cleanup.rs +++ b/src/nostr/lifecycle/deletion/cleanup.rs @@ -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(), diff --git a/src/nostr/lifecycle/deletion/policy.rs b/src/nostr/lifecycle/deletion/policy.rs index ef0c776..7cf9caa 100644 --- a/src/nostr/lifecycle/deletion/policy.rs +++ b/src/nostr/lifecycle/deletion/policy.rs @@ -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)]) diff --git a/src/nostr/lifecycle/deletion/rollback.rs b/src/nostr/lifecycle/deletion/rollback.rs index 85e3177..c6209df 100644 --- a/src/nostr/lifecycle/deletion/rollback.rs +++ b/src/nostr/lifecycle/deletion/rollback.rs @@ -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 { 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); diff --git a/src/nostr/lifecycle/deletion/runtime.rs b/src/nostr/lifecycle/deletion/runtime.rs index f5b4709..79a723d 100644 --- a/src/nostr/lifecycle/deletion/runtime.rs +++ b/src/nostr/lifecycle/deletion/runtime.rs @@ -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"); diff --git a/src/nostr/lifecycle/deletion/service.rs b/src/nostr/lifecycle/deletion/service.rs index 22e8578..e5d614d 100644 --- a/src/nostr/lifecycle/deletion/service.rs +++ b/src/nostr/lifecycle/deletion/service.rs @@ -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| { 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), diff --git a/src/nostr/lifecycle/history.rs b/src/nostr/lifecycle/history.rs index 385ce6b..53b98c7 100644 --- a/src/nostr/lifecycle/history.rs +++ b/src/nostr/lifecycle/history.rs @@ -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 { 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, diff --git a/src/nostr/lifecycle/holding.rs b/src/nostr/lifecycle/holding.rs index eaba16a..7c709d2 100644 --- a/src/nostr/lifecycle/holding.rs +++ b/src/nostr/lifecycle/holding.rs @@ -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 { 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()) diff --git a/src/nostr/lifecycle/tombstones.rs b/src/nostr/lifecycle/tombstones.rs index c44b39a..9c789a1 100644 --- a/src/nostr/lifecycle/tombstones.rs +++ b/src/nostr/lifecycle/tombstones.rs @@ -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> { 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( diff --git a/src/nostr/policy/announcement.rs b/src/nostr/policy/announcement.rs index 5097f05..33e2081 100644 --- a/src/nostr/policy/announcement.rs +++ b/src/nostr/policy/announcement.rs @@ -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 = match self.ctx.database.query(filter).await { Ok(events) => events.into_iter().collect(), @@ -434,10 +431,9 @@ impl AnnouncementPolicy { author: &PublicKey, ) -> Result { // 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 = match self.ctx.database.query(filter).await { Ok(events) => events.into_iter().collect(), diff --git a/src/nostr/policy/related.rs b/src/nostr/policy/related.rs index 3967f61..722d399 100644 --- a/src/nostr/policy/related.rs +++ b/src/nostr/policy/related.rs @@ -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 { diff --git a/src/sync/algorithms.rs b/src/sync/algorithms.rs index 9fd4e41..7c7aa9e 100644 --- a/src/sync/algorithms.rs +++ b/src/sync/algorithms.rs @@ -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( diff --git a/src/sync/filters.rs b/src/sync/filters.rs index 8eb7514..8df8705 100644 --- a/src/sync/filters.rs +++ b/src/sync/filters.rs @@ -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 = 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)); diff --git a/src/sync/mod.rs b/src/sync/mod.rs index f604180..ac5e15d 100644 --- a/src/sync/mod.rs +++ b/src/sync/mod.rs @@ -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 = (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!( diff --git a/tests/common/sync_helpers.rs b/tests/common/sync_helpers.rs index 468e174..dbfc814 100644 --- a/tests/common/sync_helpers.rs +++ b/tests/common/sync_helpers.rs @@ -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