Skip to content

Commit

Permalink
fix ReceivedBy and refactor contact serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
Green-Sky committed Apr 23, 2024
1 parent 1a3fcc6 commit e574c4f
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 51 deletions.
132 changes: 84 additions & 48 deletions src/solanaceae/message3/message_serializer.cpp
Expand Up @@ -18,51 +18,57 @@ static Contact3 findContactByID(Contact3Registry& cr, const std::vector<uint8_t>
return entt::null;
}

template<>
bool MessageSerializerNJ::component_get_json<Message::Components::ContactFrom>(MessageSerializerNJ& msc, const Handle h, nlohmann::json& j) {
const Contact3 c = h.get<Message::Components::ContactFrom>().c;
if (!msc.cr.valid(c)) {
nlohmann::json MessageSerializerNJ::serlContactByID(Contact3 c) const {
if (!cr.valid(c)) {
// while this is invalid registry state, it is valid serialization
j = nullptr;
std::cerr << "MSC warning: encountered invalid contact\n";
return true;
return nullptr;
}

if (!msc.cr.all_of<Contact::Components::ID>(c)) {
if (!cr.all_of<Contact::Components::ID>(c)) {
// unlucky, this contact is purely ephemeral
j = nullptr;
std::cerr << "MSC warning: encountered contact without ID\n";
return true;
return nullptr;
}

j = nlohmann::json::binary(msc.cr.get<Contact::Components::ID>(c).data);

return true;
return nlohmann::json::binary(cr.get<Contact::Components::ID>(c).data);
}

template<>
bool MessageSerializerNJ::component_emplace_or_replace_json<Message::Components::ContactFrom>(MessageSerializerNJ& msc, Handle h, const nlohmann::json& j) {
if (j.is_null()) {
std::cerr << "MSC warning: encountered null contact\n";
h.emplace_or_replace<Message::Components::ContactFrom>();
return true;
}

Contact3 MessageSerializerNJ::deserlContactByID(const nlohmann::json& j) {
std::vector<uint8_t> id;
if (j.is_binary()) {
id = j.get_binary();
} else {
j["bytes"].get_to(id);
}

Contact3 other_c = findContactByID(msc.cr, id);
if (!msc.cr.valid(other_c)) {
Contact3 other_c = findContactByID(cr, id);
if (!cr.valid(other_c)) {
// create sparse contact with id only
other_c = msc.cr.create();
msc.cr.emplace_or_replace<Contact::Components::ID>(other_c, id);
other_c = cr.create();
cr.emplace_or_replace<Contact::Components::ID>(other_c, id);
}

return other_c;
}

template<>
bool MessageSerializerNJ::component_get_json<Message::Components::ContactFrom>(MessageSerializerNJ& msc, const Handle h, nlohmann::json& j) {
const Contact3 c = h.get<Message::Components::ContactFrom>().c;
j = msc.serlContactByID(c);

return true;
}

template<>
bool MessageSerializerNJ::component_emplace_or_replace_json<Message::Components::ContactFrom>(MessageSerializerNJ& msc, Handle h, const nlohmann::json& j) {
if (j.is_null()) {
std::cerr << "MSC warning: encountered null contact\n";
h.emplace_or_replace<Message::Components::ContactFrom>();
return true;
}

h.emplace_or_replace<Message::Components::ContactFrom>(other_c);
h.emplace_or_replace<Message::Components::ContactFrom>(msc.deserlContactByID(j));

// TODO: should we return false if the contact is unknown??
return true;
Expand All @@ -71,48 +77,78 @@ bool MessageSerializerNJ::component_emplace_or_replace_json<Message::Components:
template<>
bool MessageSerializerNJ::component_get_json<Message::Components::ContactTo>(MessageSerializerNJ& msc, const Handle h, nlohmann::json& j) {
const Contact3 c = h.get<Message::Components::ContactTo>().c;
if (!msc.cr.valid(c)) {
// while this is invalid registry state, it is valid serialization
j = nullptr;
std::cerr << "MSC warning: encountered invalid contact\n";
j = msc.serlContactByID(c);

return true;
}

template<>
bool MessageSerializerNJ::component_emplace_or_replace_json<Message::Components::ContactTo>(MessageSerializerNJ& msc, Handle h, const nlohmann::json& j) {
if (j.is_null()) {
std::cerr << "MSC warning: encountered null contact\n";
h.emplace_or_replace<Message::Components::ContactTo>();
return true;
}

if (!msc.cr.all_of<Contact::Components::ID>(c)) {
// unlucky, this contact is purely ephemeral
j = nullptr;
std::cerr << "MSC warning: encountered contact without ID\n";
h.emplace_or_replace<Message::Components::ContactTo>(msc.deserlContactByID(j));

// TODO: should we return false if the contact is unknown??
return true;
}

template<>
bool MessageSerializerNJ::component_get_json<Message::Components::ReceivedBy>(MessageSerializerNJ& msc, const Handle h, nlohmann::json& j) {
const auto& comp = h.get<Message::Components::ReceivedBy>();
if (comp.ts.empty()) {
// empty array
j = nlohmann::json::array();
return true;
}

j = nlohmann::json::binary(msc.cr.get<Contact::Components::ID>(c).data);
for (const auto& [c, v] : comp.ts) {
if (!msc.cr.valid(c) || !msc.cr.all_of<Contact::Components::ID>(c)) {
// while this is invalid registry state, it is valid serialization
// we just skip this contact entirely and drop the time
std::cerr << "MSC warning: encountered invalid contact / contact without ID\n";
continue;
}
auto& new_entry = j.emplace_back(nlohmann::json::array());
new_entry.emplace_back(msc.serlContactByID(c));
new_entry.emplace_back(v);
}

return true;
}

template<>
bool MessageSerializerNJ::component_emplace_or_replace_json<Message::Components::ContactTo>(MessageSerializerNJ& msc, Handle h, const nlohmann::json& j) {
bool MessageSerializerNJ::component_emplace_or_replace_json<Message::Components::ReceivedBy>(MessageSerializerNJ& msc, Handle h, const nlohmann::json& j) {
if (j.is_null()) {
std::cerr << "MSC warning: encountered null contact\n";
h.emplace_or_replace<Message::Components::ContactTo>();
std::cerr << "MSC warning: encountered null ReceivedBy\n";
h.emplace_or_replace<Message::Components::ReceivedBy>();
return true;
}

std::vector<uint8_t> id;
if (j.is_binary()) {
id = j.get_binary();
} else {
j["bytes"].get_to(id);
if (!j.is_array()) {
throw (nlohmann::detail::type_error::create(302, nlohmann::detail::concat("type must be array, but is ", j.type_name()), &j));
}

Contact3 other_c = findContactByID(msc.cr, id);
if (!msc.cr.valid(other_c)) {
// create sparse contact with id only
other_c = msc.cr.create();
msc.cr.emplace_or_replace<Contact::Components::ID>(other_c, id);
auto& comp = h.emplace_or_replace<Message::Components::ReceivedBy>();

if (j.empty()) {
// empty comp
return true;
}

h.emplace_or_replace<Message::Components::ContactTo>(other_c);
for (const auto& p : j) {
if (!p.is_array()) {
throw (nlohmann::detail::type_error::create(302, nlohmann::detail::concat("type must be array, but is ", p.type_name()), &j));
}

comp.ts.emplace(
msc.deserlContactByID(p.at(0)), // TODO: error checking?
p.at(1).get<decltype(comp.ts)::mapped_type>()
);
}

// TODO: should we return false if the contact is unknown??
return true;
Expand Down
11 changes: 11 additions & 0 deletions src/solanaceae/message3/message_serializer.hpp
Expand Up @@ -70,12 +70,19 @@ struct MessageSerializerNJ {
}

// TODO: deregister



// helper
nlohmann::json serlContactByID(Contact3 c) const;
Contact3 deserlContactByID(const nlohmann::json& j);
};

// fwd
namespace Message::Components {
struct ContactFrom;
struct ContactTo;
struct ReceivedBy;
}

// make specializations known
Expand All @@ -87,3 +94,7 @@ template<>
bool MessageSerializerNJ::component_get_json<Message::Components::ContactTo>(MessageSerializerNJ& msc, const Handle h, nlohmann::json& j);
template<>
bool MessageSerializerNJ::component_emplace_or_replace_json<Message::Components::ContactTo>(MessageSerializerNJ& msc, Handle h, const nlohmann::json& j);
template<>
bool MessageSerializerNJ::component_get_json<Message::Components::ReceivedBy>(MessageSerializerNJ& msc, const Handle h, nlohmann::json& j);
template<>
bool MessageSerializerNJ::component_emplace_or_replace_json<Message::Components::ReceivedBy>(MessageSerializerNJ& msc, Handle h, const nlohmann::json& j);
6 changes: 3 additions & 3 deletions src/solanaceae/message3/nj/message_components.hpp
Expand Up @@ -11,12 +11,12 @@ namespace Message::Components {
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Timestamp, ts)
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(TimestampProcessed, ts)
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(TimestampWritten, ts)
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ContactFrom, c)
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ContactTo, c)
//NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ContactFrom, c) // ms special
//NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ContactTo, c) // ms special
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Read, ts)


NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ReceivedBy, ts)
//NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ReceivedBy, ts) // ms special
// ReadBy
// SyncedBy

Expand Down

0 comments on commit e574c4f

Please sign in to comment.