diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2025-11-21 03:49:05 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2025-11-21 03:49:05 +0000 |
| commit | 25b206c00766579f2322619f4716ca999f9b92ec (patch) | |
| tree | e265b9568b1c19cfe68df886d19d2df6fde9f3db /src | |
| parent | 8f7f0d87f238c490a6f1c6fdef3333e8d2f9e7af (diff) | |
fix: correct addressable event format for regular replaceable events
- Fixed bug where regular replaceable events (10000-19999) were using
wrong address format (3 colons instead of 2)
- Regular replaceable now use kind:pubkey format (1 colon)
- Parameterized replaceable (30000-39999) correctly use kind:pubkey:d-identifier (2 colons)
- Refactored to eliminate code duplication between both replaceable event types
- Updated documentation to reflect correct addressing for both types
Diffstat (limited to 'src')
| -rw-r--r-- | src/nostr/builder.rs | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/src/nostr/builder.rs b/src/nostr/builder.rs index 61b36d5..09b2fe2 100644 --- a/src/nostr/builder.rs +++ b/src/nostr/builder.rs | |||
| @@ -171,32 +171,41 @@ impl Nip34WritePolicy { | |||
| 171 | 171 | ||
| 172 | /// Check if any accepted event references this event (forward reference) | 172 | /// Check if any accepted event references this event (forward reference) |
| 173 | /// | 173 | /// |
| 174 | /// For addressable events (kind >= 30000): Only checks addressable reference tags (a, A, q) | 174 | /// For regular replaceable events (10000-19999): Checks addressable tags with kind:pubkey format |
| 175 | /// For parameterized replaceable (30000-39999): Checks addressable tags with kind:pubkey:d-identifier format | ||
| 175 | /// For regular events: Only checks event ID reference tags (e, E, q) | 176 | /// For regular events: Only checks event ID reference tags (e, E, q) |
| 176 | /// | 177 | /// |
| 177 | /// This optimization recognizes that addressable events won't be referenced by ID, | 178 | /// This optimization recognizes that replaceable events are referenced by coordinate address, |
| 178 | /// and regular events won't be referenced by coordinate. | 179 | /// while regular events are referenced by event ID. |
| 179 | async fn is_referenced_by_accepted( | 180 | async fn is_referenced_by_accepted( |
| 180 | database: &Arc<MemoryDatabase>, | 181 | database: &Arc<MemoryDatabase>, |
| 181 | event: &Event, | 182 | event: &Event, |
| 182 | ) -> Result<bool, String> { | 183 | ) -> Result<bool, String> { |
| 183 | // Check if this is an addressable event (parameterized replaceable) | 184 | let kind_u16 = event.kind.as_u16(); |
| 184 | let is_addressable = event.kind.as_u16() >= 30000 && event.kind.as_u16() < 40000; | 185 | |
| 185 | 186 | // Check if this is any kind of replaceable event | |
| 186 | if is_addressable { | 187 | let is_regular_replaceable = kind_u16 >= 10000 && kind_u16 < 20000; |
| 187 | // For addressable events, build the coordinate string (handles empty identifier) | 188 | let is_parameterized_replaceable = kind_u16 >= 30000 && kind_u16 < 40000; |
| 188 | let identifier = event.tags.iter() | 189 | |
| 189 | .find_map(|tag| { | 190 | if is_regular_replaceable || is_parameterized_replaceable { |
| 190 | let tag_vec = tag.clone().to_vec(); | 191 | // Build the appropriate address format based on event type |
| 191 | if tag_vec.len() >= 2 && tag_vec[0] == "d" { | 192 | let address = if is_parameterized_replaceable { |
| 192 | Some(tag_vec[1].clone()) | 193 | // For parameterized replaceable: kind:pubkey:d-identifier format (2 colons) |
| 193 | } else { | 194 | let identifier = event.tags.iter() |
| 194 | None | 195 | .find_map(|tag| { |
| 195 | } | 196 | let tag_vec = tag.clone().to_vec(); |
| 196 | }) | 197 | if tag_vec.len() >= 2 && tag_vec[0] == "d" { |
| 197 | .unwrap_or_default(); // Empty string if no 'd' tag | 198 | Some(tag_vec[1].clone()) |
| 198 | 199 | } else { | |
| 199 | let address = format!("{}:{}:{}", event.kind.as_u16(), event.pubkey.to_hex(), identifier); | 200 | None |
| 201 | } | ||
| 202 | }) | ||
| 203 | .unwrap_or_default(); // Empty string if no 'd' tag | ||
| 204 | format!("{}:{}:{}", event.kind.as_u16(), event.pubkey.to_hex(), identifier) | ||
| 205 | } else { | ||
| 206 | // For regular replaceable: kind:pubkey format (1 colon) | ||
| 207 | format!("{}:{}", event.kind.as_u16(), event.pubkey.to_hex()) | ||
| 208 | }; | ||
| 200 | 209 | ||
| 201 | // Check addressable reference tags: a, A, q (with address format) | 210 | // Check addressable reference tags: a, A, q (with address format) |
| 202 | let addressable_tags = [ | 211 | let addressable_tags = [ |