diff --git a/include/ircd/m/dbs/dbs.h b/include/ircd/m/dbs/dbs.h index 357f9574c..cee023874 100644 --- a/include/ircd/m/dbs/dbs.h +++ b/include/ircd/m/dbs/dbs.h @@ -30,7 +30,6 @@ namespace ircd::m::dbs // [SET (txn)] Basic write suite string_view write(db::txn &, const event &, const write_opts &); - void blacklist(db::txn &, const event::id &, const write_opts &); } /// Database description diff --git a/include/ircd/m/dbs/write_opts.h b/include/ircd/m/dbs/write_opts.h index 73771aec9..5d02fb0db 100644 --- a/include/ircd/m/dbs/write_opts.h +++ b/include/ircd/m/dbs/write_opts.h @@ -22,7 +22,8 @@ struct ircd::m::dbs::write_opts /// actual transaction. db::op op {db::op::SET}; - /// Principal's index number. Most codepaths do not permit zero; must set. + /// Principal's index number. Most codepaths do not permit zero. This may + /// be zero for blacklisting, but the blacklist option must be set. uint64_t event_idx {0}; /// The state btree root to perform the update on. @@ -69,4 +70,15 @@ struct ircd::m::dbs::write_opts /// made indepdently; this is slow and requires external synchronization /// to not introduce inconsistent data into the txn. bool allow_queries {true}; + + /// Setting to true allows the event_idx to be 0 which allows the insertion + /// of the event_id into a "blacklist" to mark it as unprocessable; this + /// prevents the server from repeatedly trying to process an event. + /// + /// Note for now this just creates an entry in _event_idx of 0 for the + /// event_id which also means "not found" for most codepaths, a reasonable + /// default. But for codepaths that must distinguish between "not found" + /// and "blacklist" they must know that `event_id => 0` was *found* to be + /// zero. + bool blacklist {false}; }; diff --git a/ircd/m_dbs.cc b/ircd/m_dbs.cc index 51242a186..d02cfdd60 100644 --- a/ircd/m_dbs.cc +++ b/ircd/m_dbs.cc @@ -204,6 +204,38 @@ ircd::m::dbs::write_opts::appendix_all{[] // Basic write suite // +namespace ircd::m::dbs +{ + static void blacklist(db::txn &txn, const event::id &, const write_opts &); +} + +ircd::string_view +ircd::m::dbs::write(db::txn &txn, + const event &event, + const write_opts &opts) +{ + if(opts.event_idx == 0 && opts.blacklist) + { + blacklist(txn, at<"event_id"_>(event), opts); + return {}; + } + + if(unlikely(opts.event_idx == 0)) + throw panic + { + "Cannot write to database: no index specified for event." + }; + + if(opts.appendix.test(appendix::EVENT)) + _index_event(txn, event, opts); + + if(opts.appendix.test(appendix::ROOM)) + if(json::get<"room_id"_>(event)) + return _index_room(txn, event, opts); + + return {}; +} + void ircd::m::dbs::blacklist(db::txn &txn, const event::id &event_id, @@ -232,27 +264,6 @@ ircd::m::dbs::blacklist(db::txn &txn, }; } -ircd::string_view -ircd::m::dbs::write(db::txn &txn, - const event &event, - const write_opts &opts) -{ - if(unlikely(opts.event_idx == 0)) - throw panic - { - "Cannot write to database: no index specified for event." - }; - - if(opts.appendix.test(appendix::EVENT)) - _index_event(txn, event, opts); - - if(opts.appendix.test(appendix::ROOM)) - if(json::get<"room_id"_>(event)) - return _index_room(txn, event, opts); - - return {}; -} - // // Internal interface //