0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-25 23:14:13 +01:00

ircd:Ⓜ️:vm: Massage edus through the core eval path; rename inserted to accept.

This commit is contained in:
Jason Volk 2018-03-07 11:02:23 -08:00
parent b7adb44429
commit 901a77266e
4 changed files with 142 additions and 87 deletions

View file

@ -26,7 +26,7 @@ namespace ircd::m::vm
extern struct log::log log;
extern uint64_t current_sequence;
extern ctx::view<const event> inserted;
extern ctx::shared_view<const event> accept;
extern const opts default_opts;
event::id::buf commit(json::iov &event);

View file

@ -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{"<edu>"},
e.what(),
e.content);
if(opts->warnlog & e.code)
log.warning("eval %s: %s %s",
json::get<"event_id"_>(event)?: json::string{"<edu>"},
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{"<edu>"},
e.what());
if(opts->warnlog & fault::GENERAL)
log.warning("eval %s: #GP: %s",
json::get<"event_id"_>(event)?: json::string{"<edu>"},
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)

View file

@ -291,15 +291,15 @@ synchronizer_worker()
{
while(1) try
{
std::unique_lock<decltype(m::vm::inserted)> lock
std::unique_lock<decltype(m::vm::accept)> 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())

View file

@ -50,14 +50,25 @@ void
handle_edu(client &client,
const resource::request::object<m::txn> &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
{