mirror of
https://github.com/oxen-io/oxen-storage-server.git
synced 2023-12-13 21:00:26 +01:00
account for sentinel value for swarm id in pk mapping
This commit is contained in:
parent
0163e0bdbf
commit
2f0b0e06f4
2 changed files with 63 additions and 24 deletions
|
@ -404,6 +404,8 @@ void ServiceNode::update_swarms() {
|
|||
// const char* ip = "149.56.148.124";
|
||||
// const uint16_t port = 22023;
|
||||
|
||||
// TODO: this should be changed to lokid
|
||||
|
||||
const uint16_t port = 7777;
|
||||
const char* ip = "0.0.0.0";
|
||||
|
||||
|
@ -417,11 +419,16 @@ void ServiceNode::update_swarms() {
|
|||
}
|
||||
})#";
|
||||
|
||||
make_http_request(
|
||||
ioc_, ip, port, "/json_rpc", req_body,
|
||||
std::bind(&ServiceNode::on_swarm_update, this, std::placeholders::_1));
|
||||
|
||||
/// TODO: make an rpc request to lokid
|
||||
make_http_request(ioc_, ip, port, "/json_rpc", req_body,
|
||||
[this](std::shared_ptr<std::string> res_body) {
|
||||
try {
|
||||
this->on_swarm_update(res_body);
|
||||
} catch (const std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error)
|
||||
<< "Exception caught on swarm update: "
|
||||
<< e.what();
|
||||
}
|
||||
});
|
||||
|
||||
update_timer_.expires_after(std::chrono::seconds(2));
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "service_node.h"
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace loki {
|
||||
|
||||
|
@ -123,23 +124,40 @@ SwarmEvents Swarm::update_swarms(const all_swarms_t& swarms) {
|
|||
swarm_id_t get_swarm_by_pk(const std::vector<SwarmInfo>& all_swarms,
|
||||
const std::string& pk) {
|
||||
|
||||
// TODO: handle errors
|
||||
// TODO: get rid of allocations?
|
||||
if (pk.size() != 66) {
|
||||
throw std::invalid_argument("invalid pub key size");
|
||||
}
|
||||
|
||||
std::string pk0_str = std::string(pk.c_str() + 2, 16);
|
||||
std::string pk1_str = std::string(pk.c_str() + 2 + 16, 16);
|
||||
std::string pk2_str = std::string(pk.c_str() + 2 + 32, 16);
|
||||
std::string pk3_str = std::string(pk.c_str() + 2 + 48, 16);
|
||||
/// Create a buffer for 64 characters plus 4 nulls on 8-byte boundaries
|
||||
char buf[68] = {};
|
||||
|
||||
uint64_t pk0 = std::stoull(pk0_str, 0, 16);
|
||||
uint64_t pk1 = std::stoull(pk1_str, 0, 16);
|
||||
uint64_t pk2 = std::stoull(pk2_str, 0, 16);
|
||||
uint64_t pk3 = std::stoull(pk3_str, 0, 16);
|
||||
/// Note: pk is expected to contain two leading characters
|
||||
/// (05 for the messenger) that do not participate in mapping
|
||||
|
||||
uint64_t res = pk0 ^ pk1 ^ pk2 ^ pk3;
|
||||
memcpy(buf, pk.c_str() + 2, 16);
|
||||
memcpy(buf + 17, pk.c_str() + 2 + 16, 16);
|
||||
memcpy(buf + 34, pk.c_str() + 2 + 32, 16);
|
||||
memcpy(buf + 51, pk.c_str() + 2 + 48, 16);
|
||||
|
||||
swarm_id_t cur_best = 0;
|
||||
uint64_t cur_min = std::numeric_limits<uint64_t>::max();
|
||||
/// Note: if conversion is not possible, we will still
|
||||
/// get a value in res (possibly 0 or UINT64_MAX), which
|
||||
/// we are not handling at the moment
|
||||
uint64_t res = strtoull(buf, nullptr, 16);
|
||||
res ^= strtoull(buf + 17, nullptr, 16);
|
||||
res ^= strtoull(buf + 34, nullptr, 16);
|
||||
res ^= strtoull(buf + 51, nullptr, 16);
|
||||
|
||||
/// We reserve UINT64_MAX as a sentinel swarm id for unassigned snodes
|
||||
constexpr swarm_id_t MAX_ID = std::numeric_limits<uint64_t>::max() - 1;
|
||||
constexpr swarm_id_t SENTINEL_ID = std::numeric_limits<uint64_t>::max();
|
||||
|
||||
swarm_id_t cur_best = SENTINEL_ID;
|
||||
uint64_t cur_min = SENTINEL_ID;
|
||||
|
||||
/// We don't require that all_swarms is sorted, so we find
|
||||
/// the smallest/largest elements in the same loop
|
||||
swarm_id_t leftmost_id = SENTINEL_ID;
|
||||
swarm_id_t rightmost_id = 0;
|
||||
|
||||
for (const auto& si : all_swarms) {
|
||||
|
||||
|
@ -149,16 +167,30 @@ swarm_id_t get_swarm_by_pk(const std::vector<SwarmInfo>& all_swarms,
|
|||
cur_best = si.swarm_id;
|
||||
cur_min = dist;
|
||||
}
|
||||
|
||||
/// Find the letfmost
|
||||
if (si.swarm_id < leftmost_id) {
|
||||
leftmost_id = si.swarm_id;
|
||||
}
|
||||
|
||||
if (si.swarm_id > rightmost_id) {
|
||||
rightmost_id = si.swarm_id;
|
||||
}
|
||||
}
|
||||
|
||||
// handle special case
|
||||
|
||||
if (res > all_swarms[0].swarm_id) {
|
||||
uint64_t dist =
|
||||
std::numeric_limits<uint64_t>::max() - res + all_swarms[0].swarm_id;
|
||||
|
||||
if (res > leftmost_id) {
|
||||
uint64_t dist = (MAX_ID - res) + leftmost_id;
|
||||
if (dist < cur_min) {
|
||||
return all_swarms[0].swarm_id;
|
||||
cur_best = leftmost_id;
|
||||
}
|
||||
} else {
|
||||
// since rightmost is at least as large as leftmost,
|
||||
// res <= rightmost in this branch, so the value will
|
||||
// not overflow
|
||||
uint64_t dist = res + (MAX_ID - rightmost_id);
|
||||
if (dist < cur_min) {
|
||||
cur_best = rightmost_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue