port to contact4 (not using events yet)

This commit is contained in:
Green Sky
2025-03-10 15:09:45 +01:00
parent 7a54552bd2
commit dacda24390
18 changed files with 133 additions and 122 deletions

View File

@ -123,7 +123,7 @@ static constexpr size_t flowWindowToRequestCount(size_t flow_window) {
}
void ChunkPicker::updateParticipation(
Contact3Handle c,
ContactHandle4 c,
ObjectRegistry& objreg
) {
if (!c.all_of<Contact::Components::FT1Participation>()) {
@ -211,7 +211,7 @@ void ChunkPicker::updateParticipation(
}
std::vector<ChunkPicker::ContentChunkR> ChunkPicker::updateChunkRequests(
Contact3Handle c,
ContactHandle4 c,
ObjectRegistry& objreg,
const ReceivingTransfers& rt,
const size_t open_requests

View File

@ -1,6 +1,6 @@
#pragma once
#include <solanaceae/contact/contact_model3.hpp>
#include <solanaceae/contact/fwd.hpp>
#include <solanaceae/object_store/object_store.hpp>
#include "./components.hpp"
@ -50,7 +50,7 @@ struct ChunkPicker {
private: // TODO: properly sort
// updates participating_unfinished
void updateParticipation(
Contact3Handle c,
ContactHandle4 c,
ObjectRegistry& objreg
);
public:
@ -66,7 +66,7 @@ struct ChunkPicker {
};
// returns list of chunks to request
[[nodiscard]] std::vector<ContentChunkR> updateChunkRequests(
Contact3Handle c,
ContactHandle4 c,
ObjectRegistry& objreg,
const ReceivingTransfers& rt,
const size_t open_requests

View File

@ -1,5 +1,7 @@
#include "./chunk_picker_systems.hpp"
#include <solanaceae/contact/contact_store_i.hpp>
#include <solanaceae/ngc_ft1/ngcft1_file_kind.hpp>
#include "./components.hpp"
@ -12,17 +14,19 @@
namespace Systems {
void chunk_picker_updates(
Contact3Registry& cr,
ContactStore4I& cs,
ObjectRegistry& os_reg,
const entt::dense_map<Contact3, size_t>& peer_open_requests,
const entt::dense_map<Contact4, size_t>& peer_open_requests,
const ReceivingTransfers& receiving_transfers,
NGCFT1& nft, // TODO: remove this somehow
const float delta
) {
std::vector<Contact3Handle> cp_to_remove;
std::vector<ContactHandle4> cp_to_remove;
auto& cr = cs.registry();
// first, update timers
cr.view<ChunkPickerTimer>().each([&cr, delta](const Contact3 cv, ChunkPickerTimer& cpt) {
cr.view<ChunkPickerTimer>().each([&cr, delta](const Contact4 cv, ChunkPickerTimer& cpt) {
cpt.timer -= delta;
if (cpt.timer <= 0.f) {
cr.emplace_or_replace<ChunkPickerUpdateTag>(cv);
@ -33,8 +37,8 @@ void chunk_picker_updates(
// now check for potentially missing cp
auto cput_view = cr.view<ChunkPickerUpdateTag>();
cput_view.each([&cr, &cp_to_remove](const Contact3 cv) {
Contact3Handle c{cr, cv};
cput_view.each([&cr, &cp_to_remove](const Contact4 cv) {
ContactHandle4 c{cr, cv};
//std::cout << "cput :)\n";
@ -52,8 +56,8 @@ void chunk_picker_updates(
});
// now update all cp that are tagged
cr.view<ChunkPicker, ChunkPickerUpdateTag>().each([&cr, &os_reg, &peer_open_requests, &receiving_transfers, &nft, &cp_to_remove](const Contact3 cv, ChunkPicker& cp) {
Contact3Handle c{cr, cv};
cr.view<ChunkPicker, ChunkPickerUpdateTag>().each([&cr, &os_reg, &peer_open_requests, &receiving_transfers, &nft, &cp_to_remove](const Contact4 cv, ChunkPicker& cp) {
ContactHandle4 c{cr, cv};
if (!c.all_of<Contact::Components::ToxGroupPeerEphemeral, Contact::Components::FT1Participation>()) {
cp_to_remove.push_back(c);

View File

@ -1,6 +1,6 @@
#pragma once
#include <solanaceae/contact/contact_model3.hpp>
#include <solanaceae/contact/fwd.hpp>
#include <solanaceae/object_store/object_store.hpp>
#include <solanaceae/tox_contacts/components.hpp>
#include <solanaceae/ngc_ft1/ngcft1.hpp>
@ -10,9 +10,9 @@
namespace Systems {
void chunk_picker_updates(
Contact3Registry& cr,
ContactStore4I& cs,
ObjectRegistry& os_reg,
const entt::dense_map<Contact3, size_t>& peer_open_requests,
const entt::dense_map<Contact4, size_t>& peer_open_requests,
const ReceivingTransfers& receiving_transfers,
NGCFT1& nft, // TODO: remove this somehow
const float delta

View File

@ -60,14 +60,14 @@ namespace Components {
// requested chunks with a timer since last request
struct Entry {
float timer {0.f};
Contact3 c {entt::null};
Contact4 c {entt::null};
};
entt::dense_map<size_t, Entry> chunks;
};
// TODO: once announce is shipped, remove the "Suspected"
struct SuspectedParticipants {
entt::dense_set<Contact3> participants;
entt::dense_set<Contact4> participants;
};
struct ReRequestInfoTimer {
@ -75,7 +75,7 @@ namespace Components {
};
struct AnnounceTargets {
entt::dense_set<Contact3> targets;
entt::dense_set<Contact4> targets;
};
struct ReAnnounceTimer {
@ -92,7 +92,7 @@ namespace Components {
};
struct TransferStatsSeparated {
entt::dense_map<Contact3, ObjComp::Ephemeral::File::TransferStats> stats;
entt::dense_map<Contact4, ObjComp::Ephemeral::File::TransferStats> stats;
};
// used to populate stats
@ -111,7 +111,7 @@ namespace Components {
void trimSent(const float time_now);
void trimReceived(const float time_now);
};
entt::dense_map<Contact3, Peer> tally;
entt::dense_map<Contact4, Peer> tally;
};
} // Components

View File

@ -5,7 +5,7 @@
#include <iostream>
bool addParticipation(Contact3Handle c, ObjectHandle o) {
bool addParticipation(ContactHandle4 c, ObjectHandle o) {
bool was_new {false};
assert(static_cast<bool>(o));
assert(static_cast<bool>(c));
@ -25,7 +25,7 @@ bool addParticipation(Contact3Handle c, ObjectHandle o) {
return was_new;
}
void removeParticipation(Contact3Handle c, ObjectHandle o) {
void removeParticipation(ContactHandle4 c, ObjectHandle o) {
assert(static_cast<bool>(o));
assert(static_cast<bool>(c));

View File

@ -1,8 +1,8 @@
#pragma once
#include <solanaceae/object_store/object_store.hpp>
#include <solanaceae/contact/contact_model3.hpp>
#include <solanaceae/contact/fwd.hpp>
bool addParticipation(Contact3Handle c, ObjectHandle o);
void removeParticipation(Contact3Handle c, ObjectHandle o);
bool addParticipation(ContactHandle4 c, ObjectHandle o);
void removeParticipation(ContactHandle4 c, ObjectHandle o);

View File

@ -2,6 +2,7 @@
#include "./components.hpp"
#include <solanaceae/object_store/meta_components_file.hpp>
#include <solanaceae/contact/contact_store_i.hpp>
#include <solanaceae/tox_contacts/components.hpp>
#include <solanaceae/ngc_ft1/ngcft1_file_kind.hpp>
#include <vector>
@ -11,12 +12,12 @@ namespace Systems {
void re_announce(
ObjectRegistry& os_reg,
Contact3Registry& cr,
ContactStore4I& cs,
NGCEXTEventProvider& neep,
const float delta
) {
std::vector<Object> to_remove;
os_reg.view<Components::ReAnnounceTimer>().each([&os_reg, &cr, &neep, &to_remove, delta](Object ov, Components::ReAnnounceTimer& rat) {
os_reg.view<Components::ReAnnounceTimer>().each([&os_reg, &cr = cs.registry(), &neep, &to_remove, delta](Object ov, Components::ReAnnounceTimer& rat) {
ObjectHandle o{os_reg, ov};
// if no known targets, or no hash, remove
if (!o.all_of<Components::AnnounceTargets, Components::FT1InfoSHA1Hash>()) {

View File

@ -1,14 +1,14 @@
#pragma once
#include <solanaceae/object_store/object_store.hpp>
#include <solanaceae/contact/contact_model3.hpp>
#include <solanaceae/contact/fwd.hpp>
#include <solanaceae/ngc_ext/ngcext.hpp>
namespace Systems {
void re_announce(
ObjectRegistry& os_reg,
Contact3Registry& cr,
ContactStore4I& cs,
NGCEXTEventProvider& neep,
const float delta
);

View File

@ -3,6 +3,8 @@
#include <solanaceae/util/utils.hpp>
#include <solanaceae/util/time.hpp>
#include <solanaceae/contact/contact_store_i.hpp>
#include <solanaceae/contact/components.hpp>
#include <solanaceae/tox_contacts/components.hpp>
#include <solanaceae/message3/components.hpp>
@ -90,6 +92,8 @@ std::optional<std::pair<uint32_t, uint32_t>> SHA1_NGCFT1::selectPeerForRequest(O
// get a list of peers we can request this file from
std::vector<std::pair<uint32_t, uint32_t>> tox_peers;
const auto& cr = _cs.registry();
// 1 in 20 chance to ask random peer instead
// also works well for empty SuspectedParticipants
if ((_rng()%20) == 0) {
@ -102,17 +106,17 @@ std::optional<std::pair<uint32_t, uint32_t>> SHA1_NGCFT1::selectPeerForRequest(O
}
for (const auto& target : ce.get<Components::AnnounceTargets>().targets) {
for (const auto child : _cr.get<Contact::Components::ParentOf>(target).subs) {
if (const auto* cs = _cr.try_get<Contact::Components::ConnectionState>(child); cs == nullptr || cs->state == Contact::Components::ConnectionState::State::disconnected) {
for (const auto child : cr.get<Contact::Components::ParentOf>(target).subs) {
if (const auto* cs = cr.try_get<Contact::Components::ConnectionState>(child); cs == nullptr || cs->state == Contact::Components::ConnectionState::State::disconnected) {
continue;
}
if (_cr.all_of<Contact::Components::TagSelfStrong>(child)) {
if (cr.all_of<Contact::Components::TagSelfStrong>(child)) {
continue; // skip self
}
if (_cr.all_of<Contact::Components::ToxGroupPeerEphemeral>(child)) {
const auto& tgpe = _cr.get<Contact::Components::ToxGroupPeerEphemeral>(child);
if (cr.all_of<Contact::Components::ToxGroupPeerEphemeral>(child)) {
const auto& tgpe = cr.get<Contact::Components::ToxGroupPeerEphemeral>(child);
tox_peers.push_back({tgpe.group_number, tgpe.peer_number});
}
}
@ -122,17 +126,17 @@ std::optional<std::pair<uint32_t, uint32_t>> SHA1_NGCFT1::selectPeerForRequest(O
for (const auto c : ce.get<Components::SuspectedParticipants>().participants) {
// TODO: sort by con state?
// prio to direct?
if (const auto* cs = _cr.try_get<Contact::Components::ConnectionState>(c); cs == nullptr || cs->state == Contact::Components::ConnectionState::State::disconnected) {
if (const auto* cs = cr.try_get<Contact::Components::ConnectionState>(c); cs == nullptr || cs->state == Contact::Components::ConnectionState::State::disconnected) {
continue;
}
if (_cr.all_of<Contact::Components::TagSelfStrong>(c)) {
if (cr.all_of<Contact::Components::TagSelfStrong>(c)) {
// FIXME: how did we select ourselfs to be a suspected participant
continue;
}
if (_cr.all_of<Contact::Components::ToxGroupPeerEphemeral>(c)) {
const auto& tgpe = _cr.get<Contact::Components::ToxGroupPeerEphemeral>(c);
if (cr.all_of<Contact::Components::ToxGroupPeerEphemeral>(c)) {
const auto& tgpe = cr.get<Contact::Components::ToxGroupPeerEphemeral>(c);
tox_peers.push_back({tgpe.group_number, tgpe.peer_number});
}
}
@ -148,7 +152,7 @@ std::optional<std::pair<uint32_t, uint32_t>> SHA1_NGCFT1::selectPeerForRequest(O
return std::make_pair(group_number, peer_number);
}
void SHA1_NGCFT1::queueBitsetSendFull(Contact3Handle c, ObjectHandle o) {
void SHA1_NGCFT1::queueBitsetSendFull(ContactHandle4 c, ObjectHandle o) {
if (!static_cast<bool>(c) || !static_cast<bool>(o)) {
assert(false);
return;
@ -201,7 +205,7 @@ File2I* SHA1_NGCFT1::objGetFile2Read(ObjectHandle o) {
SHA1_NGCFT1::SHA1_NGCFT1(
ObjectStore2& os,
Contact3Registry& cr,
ContactStore4I& cs,
RegistryMessageModelI& rmm,
NGCFT1& nft,
ToxContactModel2& tcm,
@ -210,7 +214,7 @@ SHA1_NGCFT1::SHA1_NGCFT1(
) :
_os(os),
_os_sr(_os.newSubRef(this)),
_cr(cr),
_cs(cs),
_rmm(rmm),
_rmm_sr(_rmm.newSubRef(this)),
_nft(nft),
@ -321,7 +325,7 @@ float SHA1_NGCFT1::iterate(float delta) {
}
}
Systems::re_announce(_os.registry(), _cr, _neep, delta);
Systems::re_announce(_os.registry(), _cs, _neep, delta);
{ // send out bitsets
// currently 1 per tick
@ -455,7 +459,7 @@ float SHA1_NGCFT1::iterate(float delta) {
// new chunk picker code
// TODO: need to either split up or remove some things here
Systems::chunk_picker_updates(
_cr,
_cs,
_os.registry(),
_peer_open_requests,
_receiving_transfers,
@ -476,7 +480,7 @@ float SHA1_NGCFT1::iterate(float delta) {
}
// gets called back on main thread after a "new" file info got built on a different thread
void SHA1_NGCFT1::onSendFileHashFinished(ObjectHandle o, Message3Registry* reg_ptr, Contact3 c, uint64_t ts) {
void SHA1_NGCFT1::onSendFileHashFinished(ObjectHandle o, Message3Registry* reg_ptr, Contact4 c, uint64_t ts) {
// sanity
if (!o.all_of<Components::FT1InfoSHA1, Components::FT1InfoSHA1Hash>()) {
assert(false);
@ -505,7 +509,7 @@ void SHA1_NGCFT1::onSendFileHashFinished(ObjectHandle o, Message3Registry* reg_p
// something happend, update all chunk pickers
if (o.all_of<Components::SuspectedParticipants>()) {
for (const auto& pcv : o.get<Components::SuspectedParticipants>().participants) {
Contact3Handle pch{_cr, pcv};
ContactHandle4 pch = _cs.contactHandle(pcv);
assert(static_cast<bool>(pch));
pch.emplace_or_replace<ChunkPickerUpdateTag>();
}
@ -514,9 +518,11 @@ void SHA1_NGCFT1::onSendFileHashFinished(ObjectHandle o, Message3Registry* reg_p
// in both cases, private and public, c (contact to) is the target
o.get_or_emplace<Components::AnnounceTargets>().targets.emplace(c);
const auto& cr = _cs.registry();
// create message
const auto c_self = _cr.get<Contact::Components::Self>(c).self;
if (!_cr.valid(c_self)) {
const auto c_self = cr.get<Contact::Components::Self>(c).self;
if (!cr.valid(c_self)) {
std::cerr << "SHA1_NGCFT1 error: failed to get self!\n";
return;
}
@ -537,8 +543,8 @@ void SHA1_NGCFT1::onSendFileHashFinished(ObjectHandle o, Message3Registry* reg_p
// file id would be sha1_info hash or something
//reg_ptr->emplace<Message::Components::Transfer::FileID>(e, file_id);
if (_cr.any_of<Contact::Components::ToxGroupEphemeral>(c)) {
const uint32_t group_number = _cr.get<Contact::Components::ToxGroupEphemeral>(c).group_number;
if (cr.any_of<Contact::Components::ToxGroupEphemeral>(c)) {
const uint32_t group_number = cr.get<Contact::Components::ToxGroupEphemeral>(c).group_number;
uint32_t message_id = 0;
// TODO: check return
@ -546,7 +552,7 @@ void SHA1_NGCFT1::onSendFileHashFinished(ObjectHandle o, Message3Registry* reg_p
reg_ptr->emplace<Message::Components::ToxGroupMessageID>(msg_e, message_id);
} else if (
// non online group
_cr.any_of<Contact::Components::ToxGroupPersistent>(c)
cr.any_of<Contact::Components::ToxGroupPersistent>(c)
) {
// create msg_id
const uint32_t message_id = randombytes_random();
@ -584,8 +590,8 @@ ObjectHandle SHA1_NGCFT1::constructFileMessageInPlace(Message3Handle msg, NGCFT1
msg.emplace_or_replace<Message::Components::MessageFileObject>(o);
// TODO: use to_c instead?
if (const auto* from_c_comp = msg.try_get<Message::Components::ContactFrom>(); from_c_comp != nullptr && _cr.valid(from_c_comp->c)) {
Contact3Handle c{_cr, from_c_comp->c};
if (const auto* from_c_comp = msg.try_get<Message::Components::ContactFrom>(); from_c_comp != nullptr && _cs.registry().valid(from_c_comp->c)) {
ContactHandle4 c = _cs.contactHandle(from_c_comp->c);
// TODO: check if public
// since public
@ -747,7 +753,7 @@ bool SHA1_NGCFT1::onEvent(const ObjectStore::Events::ObjectUpdate& e) {
if (e.e.all_of<Components::SuspectedParticipants>()) {
std::cout << "SHA1_NGCFT1: accepted ft has " << e.e.get<Components::SuspectedParticipants>().participants.size() << " sp\n";
for (const auto cv : e.e.get<Components::SuspectedParticipants>().participants) {
_cr.emplace_or_replace<ChunkPickerUpdateTag>(cv);
_cs.registry().emplace_or_replace<ChunkPickerUpdateTag>(cv);
}
} else {
std::cout << "accepted ft has NO sp!\n";
@ -990,7 +996,7 @@ bool SHA1_NGCFT1::onEvent(const Events::NGCFT1_recv_data& e) {
}
}
Contact3Handle c;
ContactHandle4 c;
const auto tpcc_it = _tox_peer_to_contact.find(combine_ids(e.group_number, e.peer_number));
if (tpcc_it != _tox_peer_to_contact.cend()) {
c = tpcc_it->second;
@ -1057,7 +1063,7 @@ bool SHA1_NGCFT1::onEvent(const Events::NGCFT1_send_data& e) {
// TODO: add event to propergate to messages
//_rmm.throwEventUpdate(transfer); // should we?
Contact3Handle c;
ContactHandle4 c;
const auto tpcc_it = _tox_peer_to_contact.find(combine_ids(e.group_number, e.peer_number));
if (tpcc_it != _tox_peer_to_contact.cend()) {
c = tpcc_it->second;
@ -1202,14 +1208,16 @@ bool SHA1_NGCFT1::onEvent(const Events::NGCFT1_recv_done& e) {
o.remove<ObjComp::F::LocalHaveBitset>(); // save space
}
const auto& cr = _cs.registry();
// queue chunk have for all participants
// HACK: send immediatly to all participants
for (const auto c_part : o.get<Components::SuspectedParticipants>().participants) {
if (!_cr.all_of<Contact::Components::ToxGroupPeerEphemeral>(c_part)) {
if (!cr.all_of<Contact::Components::ToxGroupPeerEphemeral>(c_part)) {
continue;
}
const auto [part_group_number, part_peer_number] = _cr.get<Contact::Components::ToxGroupPeerEphemeral>(c_part);
const auto [part_group_number, part_peer_number] = cr.get<Contact::Components::ToxGroupPeerEphemeral>(c_part);
const auto& info_hash = o.get<Components::FT1InfoSHA1Hash>().hash;
@ -1350,10 +1358,10 @@ bool SHA1_NGCFT1::onEvent(const Events::NGCFT1_recv_message& e) {
return true; // false?
}
bool SHA1_NGCFT1::sendFilePath(const Contact3 c, std::string_view file_name, std::string_view file_path) {
bool SHA1_NGCFT1::sendFilePath(const Contact4 c, std::string_view file_name, std::string_view file_path) {
if (
// TODO: add support of offline queuing
!_cr.all_of<Contact::Components::ToxGroupEphemeral>(c)
!_cs.registry().all_of<Contact::Components::ToxGroupEphemeral>(c)
) {
return false;
}

View File

@ -3,7 +3,7 @@
// solanaceae port of sha1 fts for NGCFT1
#include <solanaceae/object_store/object_store.hpp>
#include <solanaceae/contact/contact_model3.hpp>
#include <solanaceae/contact/fwd.hpp>
#include <solanaceae/message3/registry_message_model.hpp>
#include <solanaceae/tox_contacts/tox_contact_model2.hpp>
@ -24,7 +24,7 @@ class SHA1_NGCFT1 : public ToxEventI, public RegistryMessageModelEventI, public
ObjectStore2& _os;
ObjectStore2::SubscriptionReference _os_sr;
// TODO: backend abstraction
Contact3Registry& _cr;
ContactStore4I& _cs;
RegistryMessageModelI& _rmm;
RegistryMessageModelI::SubscriptionReference _rmm_sr;
NGCFT1& _nft;
@ -67,23 +67,23 @@ class SHA1_NGCFT1 : public ToxEventI, public RegistryMessageModelEventI, public
std::deque<ObjectHandle> _queue_content_want_info;
struct QBitsetEntry {
Contact3Handle c;
ContactHandle4 c;
ObjectHandle o;
};
std::deque<QBitsetEntry> _queue_send_bitset;
// FIXME: workaround missing contact events
// only used on peer exit (no, also used to quicken lookups)
entt::dense_map<uint64_t, Contact3Handle> _tox_peer_to_contact;
entt::dense_map<uint64_t, ContactHandle4> _tox_peer_to_contact;
// reset every iterate; kept here as an allocation optimization
entt::dense_map<Contact3, size_t> _peer_open_requests;
entt::dense_map<Contact4, size_t> _peer_open_requests;
void updateMessages(ObjectHandle ce);
std::optional<std::pair<uint32_t, uint32_t>> selectPeerForRequest(ObjectHandle ce);
void queueBitsetSendFull(Contact3Handle c, ObjectHandle o);
void queueBitsetSendFull(ContactHandle4 c, ObjectHandle o);
File2I* objGetFile2Write(ObjectHandle o);
File2I* objGetFile2Read(ObjectHandle o);
@ -97,7 +97,7 @@ class SHA1_NGCFT1 : public ToxEventI, public RegistryMessageModelEventI, public
public:
SHA1_NGCFT1(
ObjectStore2& os,
Contact3Registry& cr,
ContactStore4I& cs,
RegistryMessageModelI& rmm,
NGCFT1& nft,
ToxContactModel2& tcm,
@ -107,13 +107,13 @@ class SHA1_NGCFT1 : public ToxEventI, public RegistryMessageModelEventI, public
float iterate(float delta);
void onSendFileHashFinished(ObjectHandle o, Message3Registry* reg_ptr, Contact3 c, uint64_t ts);
void onSendFileHashFinished(ObjectHandle o, Message3Registry* reg_ptr, Contact4 c, uint64_t ts);
// construct the file part in a partially constructed message
ObjectHandle constructFileMessageInPlace(Message3Handle msg, NGCFT1_file_kind file_kind, ByteSpan file_id);
protected: // rmm events (actions)
bool sendFilePath(const Contact3 c, std::string_view file_name, std::string_view file_path) override;
bool sendFilePath(const Contact4 c, std::string_view file_name, std::string_view file_path) override;
protected: // os events (actions)
bool onEvent(const ObjectStore::Events::ObjectUpdate&) override;

View File

@ -12,7 +12,7 @@ void transfer_tally_update(ObjectRegistry& os_reg, const float time_now) {
// for each tally -> stats separated
os_reg.view<Components::TransferStatsTally>().each([&os_reg, time_now, &tally_to_remove](const auto ov, Components::TransferStatsTally& tally_comp) {
// for each peer
std::vector<Contact3> to_remove;
std::vector<Contact4> to_remove;
for (auto&& [peer_c, peer] : tally_comp.tally) {
auto& tss = os_reg.get_or_emplace<Components::TransferStatsSeparated>(ov).stats;