idempotent event deletion, prevent levId reuse when latest event is replaced or deleted

This commit is contained in:
Doug Hoyte
2023-04-30 13:47:01 -04:00
parent d4290d8a4f
commit 371f95bce3
5 changed files with 47 additions and 33 deletions

View File

@ -57,10 +57,7 @@ void RelayServer::runCron() {
uint64_t numDeleted = 0;
for (auto levId : expiredLevIds) {
auto view = env.lookup_Event(txn, levId);
if (!view) continue; // Deleted in between transactions
deleteEvent(txn, *view);
numDeleted++;
if (deleteEvent(txn, levId)) numDeleted++;
}
txn.commit();
@ -114,10 +111,7 @@ void RelayServer::runCron() {
uint64_t numDeleted = 0;
for (auto levId : expiredLevIds) {
auto view = env.lookup_Event(txn, levId);
if (!view) continue; // Deleted in between transactions
deleteEvent(txn, *view);
numDeleted++;
if (deleteEvent(txn, levId)) numDeleted++;
}
txn.commit();

View File

@ -70,9 +70,7 @@ void cmd_delete(const std::vector<std::string> &subArgs) {
auto txn = env.txn_rw();
for (auto levId : levIds) {
auto view = env.lookup_Event(txn, levId);
if (!view) continue; // Deleted in between transactions
deleteEvent(txn, *view);
deleteEvent(txn, levId);
}
txn.commit();

View File

@ -243,9 +243,10 @@ std::string_view getEventJson(lmdb::txn &txn, Decompressor &decomp, uint64_t lev
void deleteEvent(lmdb::txn &txn, defaultDb::environment::View_Event &ev) {
env.dbi_EventPayload.del(txn, lmdb::to_sv<uint64_t>(ev.primaryKeyId));
env.delete_Event(txn, ev.primaryKeyId);
bool deleteEvent(lmdb::txn &txn, uint64_t levId) {
bool deleted = env.dbi_EventPayload.del(txn, lmdb::to_sv<uint64_t>(levId));
env.delete_Event(txn, levId);
return deleted;
}
@ -258,6 +259,7 @@ void writeEvents(lmdb::txn &txn, std::vector<EventToWrite> &evs, uint64_t logLev
return aC < bC;
});
std::vector<uint64_t> levIdsToDelete;
std::string tmpBuf;
for (size_t i = 0; i < evs.size(); i++) {
@ -296,7 +298,7 @@ void writeEvents(lmdb::txn &txn, std::vector<EventToWrite> &evs, uint64_t logLev
if (otherEv.flat_nested()->created_at() < flat->created_at()) {
if (logLevel >= 1) LI << "Deleting event (d-tag). id=" << to_hex(sv(otherEv.flat_nested()->id()));
deleteEvent(txn, otherEv);
levIdsToDelete.push_back(otherEv.primaryKeyId);
} else {
ev.status = EventWriteStatus::Replaced;
}
@ -314,7 +316,7 @@ void writeEvents(lmdb::txn &txn, std::vector<EventToWrite> &evs, uint64_t logLev
auto otherEv = lookupEventById(txn, sv(tagPair->val()));
if (otherEv && sv(otherEv->flat_nested()->pubkey()) == sv(flat->pubkey())) {
if (logLevel >= 1) LI << "Deleting event (kind 5). id=" << to_hex(sv(tagPair->val()));
deleteEvent(txn, *otherEv);
levIdsToDelete.push_back(otherEv->primaryKeyId);
}
}
}
@ -329,6 +331,13 @@ void writeEvents(lmdb::txn &txn, std::vector<EventToWrite> &evs, uint64_t logLev
env.dbi_EventPayload.put(txn, lmdb::to_sv<uint64_t>(ev.levId), tmpBuf);
ev.status = EventWriteStatus::Written;
// Deletions happen after event was written to ensure levIds are not reused
for (auto levId : levIdsToDelete) deleteEvent(txn, levId);
levIdsToDelete.clear();
}
if (levIdsToDelete.size()) throw herr("unprocessed deletion");
}
}

View File

@ -112,4 +112,4 @@ struct EventToWrite {
void writeEvents(lmdb::txn &txn, std::vector<EventToWrite> &evs, uint64_t logLevel = 1);
void deleteEvent(lmdb::txn &txn, defaultDb::environment::View_Event &ev);
bool deleteEvent(lmdb::txn &txn, uint64_t levId);