@@ -247,6 +247,11 @@ bool deleteEventBasic(lmdb::txn &txn, uint64_t levId) {
247247}
248248
249249
250+ static bool isEventABeforeEventB (const PackedEventView &a, const PackedEventView &b) {
251+ // If timestamps are equal, then according to NIP-01, the one with the *greatest* lexical id is considered "earlier" (ie, discarded).
252+ return a.created_at () < b.created_at () || (a.created_at () == b.created_at () && a.id () > b.id ());
253+ }
254+
250255
251256void writeEvents (lmdb::txn &txn, NegentropyFilterCache &neFilterCache, std::vector<EventToWrite> &evs, uint64_t logLevel) {
252257 std::sort (evs.begin (), evs.end (), [](auto &a, auto &b) {
@@ -291,27 +296,54 @@ void writeEvents(lmdb::txn &txn, NegentropyFilterCache &neFilterCache, std::vect
291296 auto searchKey = makeKey_StringUint64 (searchStr, packed.kind ());
292297
293298 env.generic_foreachFull (txn, env.dbi_Event__replace , searchKey, lmdb::to_sv<uint64_t >(MAX_U64), [&](auto k, auto v) {
294- ParsedKey_StringUint64 parsedKey (k);
295- if (parsedKey.s == searchStr && parsedKey.n == packed.kind ()) {
296- auto otherEv = lookupEventByLevId (txn, lmdb::from_sv<uint64_t >(v));
299+ if (k != searchKey) return false ;
297300
298- auto thisTimestamp = packed.created_at ();
301+ auto otherEv = lookupEventByLevId (txn, lmdb::from_sv<uint64_t >(v));
302+ auto otherPacked = PackedEventView (otherEv.buf );
303+
304+ if (isEventABeforeEventB (packed, otherPacked)) {
305+ ev.status = otherPacked.kind () == 5 ? EventWriteStatus::Deleted : EventWriteStatus::Replaced;
306+ return false ; // found more recent replacement event, no need to scan more
307+ }
308+ return true ;
309+ }, true );
310+
311+ // If event is accepted (pending write), then do a second pass to remove/unindex outdated events
312+
313+ if (ev.status == EventWriteStatus::Pending) {
314+ env.generic_foreachFull (txn, env.dbi_Event__replace , searchKey, lmdb::to_sv<uint64_t >(MAX_U64), [&](auto k, auto v) {
315+ if (k != searchKey) return false ;
316+
317+ auto otherEv = lookupEventByLevId (txn, lmdb::from_sv<uint64_t >(v));
299318 auto otherPacked = PackedEventView (otherEv.buf );
300- auto otherTimestamp = otherPacked.created_at ();
319+ }, true );
320+ }
301321
322+
323+ /*
324+ if (isEventABeforeEventB(otherPacked, packed)) {
302325 if (otherPacked.kind() == 5) {
303- ev.status = EventWriteStatus::Deleted;
304- } else if (otherTimestamp < thisTimestamp ||
305- (otherTimestamp == thisTimestamp && packed.id () < otherPacked.id ())) {
326+ // remove index entry?
327+ } else {
306328 if (logLevel >= 1) LI << "Deleting event (d-tag). id=" << to_hex(otherPacked.id());
307329 levIdsToDelete.push_back(otherEv.primaryKeyId);
308- } else {
309- ev.status = EventWriteStatus::Replaced;
310330 }
331+ } else {
332+ ev.status = otherPacked.kind() == 5 ? EventWriteStatus::Deleted : EventWriteStatus::Replaced;
333+ return false; // found more recent replacement event, no need to scan more
311334 }
312-
313- return false ;
314- }, true );
335+ */
336+
337+ /*
338+ if (otherPacked.kind() == 5) {
339+ ev.status = EventWriteStatus::Deleted;
340+ } else if (isEventABeforeEventB(otherPacked, packed)) {
341+ if (logLevel >= 1) LI << "Deleting event (d-tag). id=" << to_hex(otherPacked.id());
342+ levIdsToDelete.push_back(otherEv.primaryKeyId);
343+ } else {
344+ ev.status = EventWriteStatus::Replaced;
345+ }
346+ */
315347 }
316348 }
317349
@@ -332,14 +364,18 @@ void writeEvents(lmdb::txn &txn, NegentropyFilterCache &neFilterCache, std::vect
332364 auto searchKey = makeKey_StringUint64 (pubkey + dTag, kind);
333365
334366 env.generic_foreachFull (txn, env.dbi_Event__replace , searchKey, lmdb::to_sv<uint64_t >(MAX_U64), [&](auto k, auto v) {
335- if (k == searchKey) {
336- auto otherEv = lookupEventByLevId (txn, lmdb::from_sv<uint64_t >(v));
337- if (PackedEventView (otherEv.buf ).kind () == kind) { // Might be a deletion. Leave that.
338- if (logLevel >= 1 ) LI << " Deleting replaceable event (kind 5). id=" << to_hex (tagVal);
339- levIdsToDelete.push_back (lmdb::from_sv<uint64_t >(v));
340- }
367+ if (k != searchKey) return false ;
368+
369+ auto otherEv = lookupEventByLevId (txn, lmdb::from_sv<uint64_t >(v));
370+ auto otherPacked = PackedEventView (otherEv.buf );
371+
372+ if (otherPacked.kind () == kind) {
373+ if (logLevel >= 1 ) LI << " Deleting replaceable event (kind 5). id=" << to_hex (tagVal);
374+ levIdsToDelete.push_back (lmdb::from_sv<uint64_t >(v));
375+ } else if (otherPacked.kind () == kind) {
341376 }
342- return false ;
377+
378+ return true ;
343379 }, true );
344380 }
345381 } catch (...) {
0 commit comments