From 901a77266e980729fd7a6be58e73fbd868093e2e Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Wed, 7 Mar 2018 11:02:23 -0800 Subject: [PATCH] ircd::m::vm: Massage edus through the core eval path; rename inserted to accept. --- include/ircd/m/vm.h | 2 +- ircd/m/vm.cc | 143 +++++++++++++++++++++++-------------- modules/client/sync.cc | 6 +- modules/federation/send.cc | 78 ++++++++++++-------- 4 files changed, 142 insertions(+), 87 deletions(-) diff --git a/include/ircd/m/vm.h b/include/ircd/m/vm.h index 4513d823d..ed87e166a 100644 --- a/include/ircd/m/vm.h +++ b/include/ircd/m/vm.h @@ -26,7 +26,7 @@ namespace ircd::m::vm extern struct log::log log; extern uint64_t current_sequence; - extern ctx::view inserted; + extern ctx::shared_view accept; extern const opts default_opts; event::id::buf commit(json::iov &event); diff --git a/ircd/m/vm.cc b/ircd/m/vm.cc index c4d5529c9..6ab53bd83 100644 --- a/ircd/m/vm.cc +++ b/ircd/m/vm.cc @@ -16,8 +16,8 @@ ircd::m::vm::log "vm", 'v' }; -decltype(ircd::m::vm::inserted) -ircd::m::vm::inserted +decltype(ircd::m::vm::accept) +ircd::m::vm::accept {}; decltype(ircd::m::vm::current_sequence) @@ -202,12 +202,21 @@ ircd::m::vm::commit(json::iov &iov) namespace ircd::m::vm { + extern hook::site eval_hook; extern hook::site notify_hook; void _tmp_effects(const m::event &event); //TODO: X void write(eval &); + fault _eval_edu(eval &, const event &); + fault _eval_pdu(eval &, const event &); } +decltype(ircd::m::vm::eval_hook) +ircd::m::vm::eval_hook +{ + { "name", "vm.eval" } +}; + decltype(ircd::m::vm::notify_hook) ircd::m::vm::notify_hook { @@ -241,6 +250,70 @@ try fault::INVALID, "Non-conforming event: %s", string(report) }; + // A conforming (with lots of masks) event without an event_id is an EDU. + if(!json::get<"event_id"_>(event)) + return _eval_edu(*this, event); + + return _eval_pdu(*this, event); +} +catch(const error &e) +{ + if(opts->errorlog & e.code) + log.error("eval %s: %s %s", + json::get<"event_id"_>(event)?: json::string{""}, + e.what(), + e.content); + + if(opts->warnlog & e.code) + log.warning("eval %s: %s %s", + json::get<"event_id"_>(event)?: json::string{""}, + e.what(), + e.content); + + if(opts->nothrows & e.code) + return e.code; + + throw; +} +catch(const std::exception &e) +{ + if(opts->errorlog & fault::GENERAL) + log.error("eval %s: #GP: %s", + json::get<"event_id"_>(event)?: json::string{""}, + e.what()); + + if(opts->warnlog & fault::GENERAL) + log.warning("eval %s: #GP: %s", + json::get<"event_id"_>(event)?: json::string{""}, + e.what()); + + if(opts->nothrows & fault::GENERAL) + return fault::GENERAL; + + throw error + { + fault::GENERAL, "%s", e.what() + }; +} + +enum ircd::m::vm::fault +ircd::m::vm::_eval_edu(eval &eval, + const event &event) +{ + eval_hook(event); + return fault::ACCEPT; +} + +enum ircd::m::vm::fault +ircd::m::vm::_eval_pdu(eval &eval, + const event &event) +{ + assert(eval.opts); + const auto &opts + { + *eval.opts + }; + const m::event::id &event_id { at<"event_id"_>(event) @@ -251,12 +324,13 @@ try at<"room_id"_>(event) }; - if(!opts->replays && exists(event_id)) //TODO: exclusivity + if(!opts.replays && exists(event_id)) //TODO: exclusivity throw error { fault::EXISTS, "Event has already been evaluated." }; + eval_hook(event); const auto &depth { @@ -279,12 +353,12 @@ try }; //TODO: ex - if(opts->write && prev_count) + if(opts.write && prev_count) { for(size_t i(0); i < prev_count; ++i) { const auto prev_id{prev.prev_event(i)}; - if(opts->prev_check_exists && !dbs::exists(prev_id)) + if(opts.prev_check_exists && !dbs::exists(prev_id)) throw error { fault::EVENT, "Missing prev event %s", string_view{prev_id} @@ -306,10 +380,10 @@ try wopts.present = true; const auto new_root { - dbs::write(txn, event, wopts) + dbs::write(eval.txn, event, wopts) }; } - else if(opts->write) + else if(opts.write) { m::state::id_buffer new_root_buf; m::dbs::write_opts wopts; @@ -317,69 +391,30 @@ try wopts.present = true; const auto new_root { - dbs::write(txn, event, wopts) + dbs::write(eval.txn, event, wopts) }; } - if(opts->write) - write(*this); + if(opts.write) + write(eval); - if(opts->notify) + if(opts.notify) { notify_hook(event); - vm::inserted.notify(event); + vm::accept.expose(event); } - if(opts->effects) + if(opts.effects) _tmp_effects(event); - if(opts->debuglog_accept) + if(opts.debuglog_accept) log.debug("%s", pretty_oneline(event)); - if(opts->infolog_accept) + if(opts.infolog_accept) log.info("%s", pretty_oneline(event)); return fault::ACCEPT; } -catch(const error &e) -{ - if(opts->errorlog & e.code) - log.error("eval %s: %s %s", - json::get<"event_id"_>(event), - e.what(), - e.content); - - if(opts->warnlog & e.code) - log.warning("eval %s: %s %s", - json::get<"event_id"_>(event), - e.what(), - e.content); - - if(opts->nothrows & e.code) - return e.code; - - throw; -} -catch(const std::exception &e) -{ - if(opts->errorlog & fault::GENERAL) - log.error("eval %s: #GP: %s", - json::get<"event_id"_>(event), - e.what()); - - if(opts->warnlog & fault::GENERAL) - log.warning("eval %s: #GP: %s", - json::get<"event_id"_>(event), - e.what()); - - if(opts->nothrows & fault::GENERAL) - return fault::GENERAL; - - throw error - { - fault::GENERAL, "%s", e.what() - }; -} void ircd::m::vm::write(eval &eval) diff --git a/modules/client/sync.cc b/modules/client/sync.cc index 9b0645f11..7660f7b99 100644 --- a/modules/client/sync.cc +++ b/modules/client/sync.cc @@ -291,15 +291,15 @@ synchronizer_worker() { while(1) try { - std::unique_lock lock + std::unique_lock lock { - m::vm::inserted + m::vm::accept }; // reference to the event on the inserter's stack const auto &event { - m::vm::inserted.wait(lock) + m::vm::accept.wait(lock) }; if(!syncpoll::polling.empty()) diff --git a/modules/federation/send.cc b/modules/federation/send.cc index 94834e8db..981516795 100644 --- a/modules/federation/send.cc +++ b/modules/federation/send.cc @@ -50,14 +50,25 @@ void handle_edu(client &client, const resource::request::object &request, const string_view &txn_id, - const json::object &edu) + const m::edu &edu) { - //std::cout << edu << std::endl; - log::debug("%s :%s | %s | %s", - txn_id, - at<"origin"_>(request), - edu.at("edu_type"), - edu.get("sender", string_view{"*"})); + m::event event; + json::get<"origin"_>(event) = at<"origin"_>(request); + json::get<"origin_server_ts"_>(event) = at<"origin_server_ts"_>(request); + json::get<"content"_>(event) = at<"content"_>(edu); + json::get<"type"_>(event) = at<"edu_type"_>(edu); + + m::vm::opts vmopts; + vmopts.non_conform.set(m::event::conforms::INVALID_OR_MISSING_EVENT_ID); + vmopts.non_conform.set(m::event::conforms::INVALID_OR_MISSING_ROOM_ID); + vmopts.non_conform.set(m::event::conforms::INVALID_OR_MISSING_SENDER_ID); + vmopts.non_conform.set(m::event::conforms::MISSING_PREV_EVENTS); + vmopts.non_conform.set(m::event::conforms::MISSING_PREV_STATE); + vmopts.non_conform.set(m::event::conforms::DEPTH_ZERO); + m::vm::eval eval + { + event, vmopts + }; } void @@ -67,12 +78,15 @@ handle_pdu(client &client, const m::event &event) try { - //std::cout << event << std::endl; - log::debug("%s %s", - txn_id, - pretty_oneline(event)); - - m::vm::eval{event}; + m::vm::opts vmopts; + vmopts.non_conform.set(m::event::conforms::MISSING_PREV_STATE); + vmopts.non_conform.set(m::event::conforms::MISSING_MEMBERSHIP); + vmopts.prev_check_exists = false; + vmopts.nothrows = -1U; + m::vm::eval eval + { + event, vmopts + }; } catch(const ed25519::bad_sig &e) { @@ -92,11 +106,14 @@ handle_pdu_failure(client &client, const string_view &txn_id, const json::object &pdu_failure) { - log::debug("%s :%s | (pdu_failure) %s", - txn_id, - at<"origin"_>(request), - pdu_failure.get("sender", string_view{"*"}), - string_view{pdu_failure}); + log::error + { + "%s :%s | (pdu_failure) %s", + txn_id, + at<"origin"_>(request), + pdu_failure.get("sender", string_view{"*"}), + string_view{pdu_failure} + }; } resource::response @@ -128,22 +145,25 @@ handle_put(client &client, json::get<"pdu_failures"_>(request) }; + log::debug + { + "%s :%s | %s --> edus:%zu pdus:%zu errors:%zu", + txn_id, + origin, + string(remote(client)), + edus.count(), + pdus.count(), + pdu_failures.count() + }; + for(const auto &pdu_failure : pdu_failures) handle_pdu_failure(client, request, txn_id, pdu_failure); - for(const auto &edu : edus) + for(const json::object &edu : edus) handle_edu(client, request, txn_id, edu); - for(const auto &pdu : pdus) - handle_pdu(client, request, txn_id, m::event{pdu}); - - log::debug("%s :%s | %s --> edus:%zu pdus:%zu errors:%zu", - txn_id, - origin, - string(remote(client)), - edus.count(), - pdus.count(), - pdu_failures.count()); + for(const json::object &pdu : pdus) + handle_pdu(client, request, txn_id, pdu); return resource::response {