Fallback bootstrap router build parameter

Adds a fallback bootstrap file path parameter to CMake, specify
-DBOOTSTRAP_SYSTEM_PATH="/path/to/file" to use.

Adds a list of (currently 1) obsolete bootstrap RouterIDs to check
bootstrap RCs against.  Will not use bootstrap RCs if they're on that
list.

Log an error periodically if we appear to be an active service node but
have fewer than a set number (5) known peers.

Bumps oxen-logging version for literal _format.
pull/1996/head
Thomas Winget 2 years ago committed by Jason Rhinelander
parent 20281ccc60
commit cc1bcf86fa
No known key found for this signature in database
GPG Key ID: C4992CE7A88D4262

@ -39,6 +39,7 @@ set(RELEASE_MOTTO "Our Lord And Savior" CACHE STRING "Release motto")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
set(BOOTSTRAP_SYSTEM_PATH "" CACHE PATH "Fallback bootstrap path")
set(DEFAULT_WITH_BOOTSTRAP ON)
if(APPLE)
set(DEFAULT_WITH_BOOTSTRAP OFF)

@ -235,6 +235,10 @@ add_library(lokinet-amalgum
service/tag.cpp
)
if(BOOTSTRAP_SYSTEM_PATH)
message(STATUS "Building with fallback boostrap path \"${BOOTSTRAP_SYSTEM_PATH}\"")
target_compile_definitions(lokinet-amalgum PRIVATE "BOOTSTRAP_FALLBACK=\"${BOOTSTRAP_SYSTEM_PATH}\"")
endif()
if(WITH_PEERSTATS_BACKEND)
target_compile_definitions(lokinet-amalgum PRIVATE -DLOKINET_PEERSTATS_BACKEND)

@ -36,4 +36,35 @@ namespace llarp
{
return BEncodeWriteList(begin(), end(), buf);
}
void
BootstrapList::AddFromFile(fs::path fpath)
{
bool isListFile = false;
{
std::ifstream inf(fpath.c_str(), std::ios::binary);
if (inf.is_open())
{
const char ch = inf.get();
isListFile = ch == 'l';
}
}
if (isListFile)
{
if (not BDecodeReadFile(fpath, *this))
{
throw std::runtime_error{fmt::format("failed to read bootstrap list file '{}'", fpath)};
}
}
else
{
RouterContact rc;
if (not rc.Read(fpath))
{
throw std::runtime_error{
fmt::format("failed to decode bootstrap RC, file='{}', rc={}", fpath, rc)};
}
this->insert(rc);
}
}
} // namespace llarp

@ -2,6 +2,7 @@
#include "router_contact.hpp"
#include <set>
#include "llarp/util/fs.hpp"
namespace llarp
{
@ -13,6 +14,9 @@ namespace llarp
bool
BEncode(llarp_buffer_t* buf) const;
void
AddFromFile(fs::path fpath);
void
Clear();
};

@ -666,32 +666,7 @@ namespace llarp
BootstrapList b_list;
for (const auto& router : configRouters)
{
bool isListFile = false;
{
std::ifstream inf(router.c_str(), std::ios::binary);
if (inf.is_open())
{
const char ch = inf.get();
isListFile = ch == 'l';
}
}
if (isListFile)
{
if (not BDecodeReadFile(router, b_list))
{
throw std::runtime_error{fmt::format("failed to read bootstrap list file '{}'", router)};
}
}
else
{
RouterContact rc;
if (not rc.Read(router))
{
throw std::runtime_error{
fmt::format("failed to decode bootstrap RC, file='{}', rc={}", router, rc)};
}
b_list.insert(rc);
}
b_list.AddFromFile(router);
}
for (const auto& rc : conf.bootstrap.routers)
@ -699,19 +674,52 @@ namespace llarp
b_list.emplace(rc);
}
for (auto& rc : b_list)
// in case someone has an old bootstrap file and is trying to use a bootstrap
// that no longer exists
for (auto rc_itr = b_list.begin(); rc_itr != b_list.end();)
{
if (not rc.Verify(Now()))
if (rc_itr->IsObsoleteBootstrap())
b_list.erase(rc_itr);
else
rc_itr++;
}
auto verifyRCs = [&]() {
for (auto& rc : b_list)
{
LogWarn("ignoring invalid RC: ", RouterID(rc.pubkey));
continue;
if (rc.IsObsoleteBootstrap())
{
LogWarn("ignoring obsolete boostrap RC: ", RouterID(rc.pubkey));
continue;
}
if (not rc.Verify(Now()))
{
log::warning(logcat, "ignoring invalid RC: {}", RouterID(rc.pubkey));
continue;
}
bootstrapRCList.emplace(std::move(rc));
}
bootstrapRCList.emplace(std::move(rc));
}
};
verifyRCs();
#ifdef BOOTSTRAP_FALLBACK
constexpr std::string_view bootstrap_fallback = BOOTSTRAP_FALLBACK;
#else
constexpr std::string_view bootstrap_fallback{};
#endif // BOOTSTRAP_FALLBACK
if (bootstrapRCList.empty() and not conf.bootstrap.seednode)
{
throw std::runtime_error{"we have no bootstrap nodes"};
if (not bootstrap_fallback.empty())
{
b_list.clear();
b_list.AddFromFile(bootstrap_fallback);
verifyRCs();
}
if (bootstrapRCList.empty()) // empty after trying fallback, if set
throw std::runtime_error{"we have no bootstrap nodes"};
}
if (conf.bootstrap.seednode)
@ -1038,14 +1046,27 @@ namespace llarp
connectToNum = strictConnect;
}
if (auto dereg = LooksDeregistered(); (dereg or decom) and now >= m_NextDecommissionWarn)
if (now >= m_NextDecommissionWarn)
{
// complain about being deregistered
constexpr auto DecommissionWarnInterval = 5min;
LogError(
"We are running as a service node but we seem to be ",
dereg ? "deregistered" : "decommissioned");
m_NextDecommissionWarn = now + DecommissionWarnInterval;
if (auto dereg = LooksDeregistered(); dereg or decom)
{
// complain about being deregistered
LogError(
"We are running as a service node but we seem to be ",
dereg ? "deregistered" : "decommissioned");
m_NextDecommissionWarn = now + DecommissionWarnInterval;
}
else if (isSvcNode)
{
constexpr int KnownPeerWarningThreshold = 5;
if (nodedb()->NumLoaded() < KnownPeerWarningThreshold)
log::error(
logcat,
"We appear to be an active service node, but have fewer than {} known peers.",
KnownPeerWarningThreshold);
m_NextDecommissionWarn = now + DecommissionWarnInterval;
}
}
// if we need more sessions to routers and we are not a service node kicked from the network

@ -533,6 +533,20 @@ namespace llarp
return false;
}
static constexpr std::array obsolete_bootstraps = {
"7a16ac0b85290bcf69b2f3b52456d7e989ac8913b4afbb980614e249a3723218"sv};
bool
RouterContact::IsObsoleteBootstrap() const
{
for (const auto& k : obsolete_bootstraps)
{
if (pubkey.ToHex() == k)
return true;
}
return false;
}
bool
RouterContact::Write(const fs::path& fname) const
{

@ -205,6 +205,9 @@ namespace llarp
bool
FromOurNetwork() const;
bool
IsObsoleteBootstrap() const;
private:
bool
DecodeVersion_0(llarp_buffer_t* buf);

@ -3,6 +3,8 @@
#include <string>
#include <chrono>
#include "oxen/log/format.hpp"
using byte_t = uint8_t;
using llarp_proto_version_t = std::uint8_t;
@ -10,6 +12,7 @@ namespace llarp
{
using Duration_t = std::chrono::milliseconds;
using namespace std::literals;
using namespace oxen::log::literals;
/// convert to milliseconds
uint64_t

Loading…
Cancel
Save