1
1
Fork 0
mirror of https://github.com/oxen-io/lokinet synced 2023-12-14 06:53:00 +01:00

Handle PubIntro relayOrder logic on client-side

This commit is contained in:
Stephen Shelton 2020-02-26 13:27:27 -07:00
parent 61d19179f7
commit 62014de91c
No known key found for this signature in database
GPG key ID: EE4BADACCE8B631C
2 changed files with 49 additions and 27 deletions

View file

@ -57,6 +57,7 @@ namespace llarp
std::vector< std::unique_ptr< IMessage > > &replies) const
{
auto now = ctx->impl->Now();
const auto keyStr = introset.derivedSigningKey.ToHex();
auto &dht = *ctx->impl;
if(!introset.Verify(now))
@ -80,8 +81,9 @@ namespace llarp
const llarp::dht::Key_t addr(introset.derivedSigningKey);
// identify closest 4 routers
auto closestRCs = dht.GetRouter()->nodedb()->FindClosestTo(addr, 4);
if(closestRCs.size() != 4)
static constexpr size_t StorageRedundancy = 4;
auto closestRCs = dht.GetRouter()->nodedb()->FindClosestTo(addr, StorageRedundancy);
if(closestRCs.size() != StorageRedundancy)
{
llarp::LogWarn("Received PublishIntroMessage but only know ",
closestRCs.size(), " nodes");
@ -92,33 +94,31 @@ namespace llarp
const auto &us = dht.OurKey();
// function to identify the closest 4 routers we know of for this introset
auto propagateToClosestFour = [&]() {
// grab 1st & 2nd if we are relayOrder == 0, 3rd & 4th otherwise
const auto &rc0 = (relayOrder == 0 ? closestRCs[0] : closestRCs[2]);
const auto &rc1 = (relayOrder == 0 ? closestRCs[1] : closestRCs[3]);
auto propagateIfNotUs = [&](size_t index) {
assert(index < StorageRedundancy);
const Key_t peer0{rc0.pubkey};
const Key_t peer1{rc1.pubkey};
const auto &rc = closestRCs[index];
const Key_t peer{rc.pubkey};
bool arePeer0 = (peer0 == us);
bool arePeer1 = (peer1 == us);
if(arePeer0 or arePeer1)
if(peer == us)
{
llarp::LogInfo("we are peer ", index,
" so storing instead of propagating");
dht.services()->PutNode(introset);
replies.emplace_back(new GotIntroMessage({introset}, txID));
}
else
{
llarp::LogInfo("propagating to peer ", index);
if(not arePeer0)
dht.PropagateIntroSetTo(From, txID, introset, peer0, false, 0);
if(not arePeer1)
dht.PropagateIntroSetTo(From, txID, introset, peer1, false, 0);
dht.PropagateIntroSetTo(From, txID, introset, peer, false, 0);
}
};
if(relayed)
{
if(relayOrder > 1)
if(relayOrder >= StorageRedundancy)
{
llarp::LogWarn(
"Received PublishIntroMessage with invalid relayOrder: ",
@ -127,7 +127,10 @@ namespace llarp
return true;
}
propagateToClosestFour();
llarp::LogInfo("Relaying PublishIntroMessage for ", keyStr,
", txid=", txID);
propagateIfNotUs(relayOrder);
}
else
{
@ -148,8 +151,14 @@ namespace llarp
}
else
{
// TODO: ensure this can't create a loop (reintroduce depth?)
propagateToClosestFour();
LogWarn(
"!!! Received PubIntro with relayed==false but we aren't"
" candidate, intro derived key: ",
keyStr, ", txid=", txID, ", message from: ", From);
for(size_t i = 0; i < StorageRedundancy; ++i)
{
propagateIfNotUs(i);
}
}
}

View file

@ -452,19 +452,32 @@ namespace llarp
AbstractRouter* r)
{
/// number of routers to publish to
static constexpr size_t PublishRedundancy = 2;
const auto paths =
GetManyPathsWithUniqueEndpoints(this, PublishRedundancy);
static constexpr size_t RelayRedundancy = 2;
/// number of dht locations handled per relay
static constexpr size_t RequestsPerRelay = 2;
/// total number of dht locations that should store this introset
static constexpr size_t StorageRedundancy =
(RelayRedundancy * RequestsPerRelay);
assert(StorageRedundancy == 4);
const auto paths = GetManyPathsWithUniqueEndpoints(this, RelayRedundancy);
if(paths.size() != RelayRedundancy)
return false;
// do publishing for each path selected
size_t published = 0;
for(const auto& path : paths)
{
if(PublishIntroSetVia(introset, r, path, published))
for(size_t i = 0; i < RequestsPerRelay; ++i)
{
published++;
if(PublishIntroSetVia(introset, r, path, published))
published++;
}
}
return published == PublishRedundancy;
return published == StorageRedundancy;
}
struct PublishIntroSetJob : public IServiceLookup