diff --git a/src/events.cpp b/src/events.cpp index 52b1602..7a8f6a6 100644 --- a/src/events.cpp +++ b/src/events.cpp @@ -21,6 +21,14 @@ std::string nostrJsonToFlat(const tao::json::value &v) { uint64_t expiration = 0; + if (isReplaceableKind(kind)) { + // Prepend virtual d-tag + tagsGeneral.emplace_back(NostrIndex::CreateTagGeneral(builder, + 'd', + builder.CreateVector((uint8_t*)"", 0) + )); + } + if (v.at("tags").get_array().size() > cfg().events__maxNumTags) throw herr("too many tags: ", v.at("tags").get_array().size()); for (auto &tagArr : v.at("tags").get_array()) { auto &tag = tagArr.get_array(); @@ -42,8 +50,6 @@ std::string nostrJsonToFlat(const tao::json::value &v) { expiration = parseUint64(tagVal); if (expiration < 100) throw herr("invalid expiration"); } - } else if (tagName == "ephemeral") { - expiration = 1; } else if (tagName.size() == 1) { if (tagVal.size() > cfg().events__maxTagValSize) throw herr("tag val too large: ", tagVal.size()); @@ -56,14 +62,15 @@ std::string nostrJsonToFlat(const tao::json::value &v) { } } - if (isDefaultReplaceableKind(kind)) { + if (isParamReplaceableKind(kind)) { + // Append virtual d-tag tagsGeneral.emplace_back(NostrIndex::CreateTagGeneral(builder, 'd', builder.CreateVector((uint8_t*)"", 0) )); } - if (isDefaultEphemeralKind(kind)) { + if (isEphemeralKind(kind)) { expiration = 1; } @@ -280,11 +287,13 @@ void writeEvents(lmdb::txn &txn, std::vector &evs, uint64_t logLev { std::optional replace; - for (const auto &tagPair : *(flat->tagsGeneral())) { - auto tagName = (char)tagPair->key(); - if (tagName != 'd') continue; - replace = std::string(sv(tagPair->val())); - break; + if (isReplaceableKind(flat->kind()) || isParamReplaceableKind(flat->kind())) { + for (const auto &tagPair : *(flat->tagsGeneral())) { + auto tagName = (char)tagPair->key(); + if (tagName != 'd') continue; + replace = std::string(sv(tagPair->val())); + break; + } } if (replace) { diff --git a/src/events.h b/src/events.h index 095f71b..94c89d5 100644 --- a/src/events.h +++ b/src/events.h @@ -9,17 +9,22 @@ -inline bool isDefaultReplaceableKind(uint64_t kind) { +inline bool isReplaceableKind(uint64_t kind) { return ( kind == 0 || kind == 3 || kind == 41 || - (kind >= 10'000 && kind < 20'000) || + (kind >= 10'000 && kind < 20'000) + ); +} + +inline bool isParamReplaceableKind(uint64_t kind) { + return ( (kind >= 30'000 && kind < 40'000) ); } -inline bool isDefaultEphemeralKind(uint64_t kind) { +inline bool isEphemeralKind(uint64_t kind) { return ( (kind >= 20'000 && kind < 30'000) ); diff --git a/test/writeTest.pl b/test/writeTest.pl index 7c09300..ba61338 100644 --- a/test/writeTest.pl +++ b/test/writeTest.pl @@ -43,16 +43,6 @@ doTest({ }); -doTest({ - desc => "Same, but explicit empty d tag", - events => [ - qq{--sec $ids->[0]->{sec} --content "hi" --kind 10000 --created-at 5000 }, - qq{--sec $ids->[0]->{sec} --content "hi 2" --kind 10000 --created-at 5001 --tag d '' }, - qq{--sec $ids->[0]->{sec} --content "hi" --kind 10000 --created-at 5000 }, - ], - verify => [ 1, ], -}); - doTest({ desc => "Replacement is dropped", @@ -84,6 +74,17 @@ doTest({ }); +doTest({ + desc => "d tags are ignored in 10k-20k range", + events => [ + qq{--sec $ids->[0]->{sec} --content "hi" --kind 10003 --created-at 5000 }, + qq{--sec $ids->[0]->{sec} --content "hi 2" --kind 10003 --created-at 5001 --tag d 'myrepl' }, + ], + verify => [ 1, ], +}); + + + doTest({ desc => "Deletion", @@ -135,19 +136,27 @@ doTest({ doTest({ desc => "Parameterized Replaceable Events", events => [ - qq{--sec $ids->[0]->{sec} --content "hi1" --kind 1 --created-at 5000 --tag d myrepl }, - qq{--sec $ids->[0]->{sec} --content "hi2" --kind 1 --created-at 5001 --tag d myrepl }, + qq{--sec $ids->[0]->{sec} --content "hi1" --kind 30001 --created-at 5000 --tag d myrepl }, + qq{--sec $ids->[0]->{sec} --content "hi2" --kind 30001 --created-at 5001 --tag d myrepl }, ], verify => [ 1, ], }); +doTest({ + desc => "d tag only works in range 30k-40k", + events => [ + qq{--sec $ids->[0]->{sec} --content "hi1" --kind 1 --created-at 5000 --tag d myrepl }, + qq{--sec $ids->[0]->{sec} --content "hi2" --kind 1 --created-at 5001 --tag d myrepl }, + ], + verify => [ 0, 1, ], +}); doTest({ desc => "d tags have to match", events => [ - qq{--sec $ids->[0]->{sec} --content "hi1" --kind 1 --created-at 5000 --tag d myrepl }, - qq{--sec $ids->[0]->{sec} --content "hi2" --kind 1 --created-at 5001 --tag d myrepl2 }, - qq{--sec $ids->[0]->{sec} --content "hi3" --kind 1 --created-at 5002 --tag d myrepl }, + qq{--sec $ids->[0]->{sec} --content "hi1" --kind 30001 --created-at 5000 --tag d myrepl }, + qq{--sec $ids->[0]->{sec} --content "hi2" --kind 30001 --created-at 5001 --tag d myrepl2 }, + qq{--sec $ids->[0]->{sec} --content "hi3" --kind 30001 --created-at 5002 --tag d myrepl }, ], verify => [ 1, 2, ], }); @@ -156,8 +165,8 @@ doTest({ doTest({ desc => "Kinds have to match", events => [ - qq{--sec $ids->[0]->{sec} --content "hi1" --kind 1 --created-at 5000 --tag d myrepl }, - qq{--sec $ids->[0]->{sec} --content "hi2" --kind 2 --created-at 5001 --tag d myrepl }, + qq{--sec $ids->[0]->{sec} --content "hi1" --kind 30001 --created-at 5000 --tag d myrepl }, + qq{--sec $ids->[0]->{sec} --content "hi2" --kind 30002 --created-at 5001 --tag d myrepl }, ], verify => [ 0, 1, ], }); @@ -166,23 +175,34 @@ doTest({ doTest({ desc => "Pubkeys have to match", events => [ - qq{--sec $ids->[0]->{sec} --content "hi1" --kind 1 --created-at 5000 --tag d myrepl }, - qq{--sec $ids->[1]->{sec} --content "hi2" --kind 1 --created-at 5001 --tag d myrepl }, + qq{--sec $ids->[0]->{sec} --content "hi1" --kind 30001 --created-at 5000 --tag d myrepl }, + qq{--sec $ids->[1]->{sec} --content "hi2" --kind 30001 --created-at 5001 --tag d myrepl }, ], verify => [ 0, 1, ], }); doTest({ - desc => "Timestamp", + desc => "Newer param replaceable event isn't replaced", events => [ - qq{--sec $ids->[0]->{sec} --content "hi1" --kind 1 --created-at 5001 --tag d myrepl }, - qq{--sec $ids->[0]->{sec} --content "hi2" --kind 1 --created-at 5000 --tag d myrepl }, + qq{--sec $ids->[0]->{sec} --content "hi1" --kind 30001 --created-at 5001 --tag d myrepl }, + qq{--sec $ids->[0]->{sec} --content "hi2" --kind 30001 --created-at 5000 --tag d myrepl }, ], verify => [ 0, ], }); +doTest({ + desc => "Explicit empty d tag", + events => [ + qq{--sec $ids->[0]->{sec} --content "hi" --kind 30003 --created-at 5000 }, + qq{--sec $ids->[0]->{sec} --content "hi 2" --kind 30003 --created-at 5001 --tag d '' }, + qq{--sec $ids->[0]->{sec} --content "hi" --kind 30003 --created-at 5000 }, + ], + verify => [ 1, ], +}); + + print "\nOK\n";