diff --git a/CMakeLists.txt b/CMakeLists.txt index f66994b5b..5253b9572 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,6 @@ 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) @@ -64,6 +63,8 @@ option(WITH_BOOTSTRAP "build lokinet-bootstrap tool" ${DEFAULT_WITH_BOOTSTRAP}) option(WITH_PEERSTATS "build with experimental peerstats db support" OFF) option(STRIP_SYMBOLS "strip off all debug symbols into an external archive for all executables built" OFF) +set(BOOTSTRAP_FALLBACK_MAINNET "${PROJECT_SOURCE_DIR}/contrib/bootstrap/mainnet.signed" CACHE PATH "Fallback bootstrap path (mainnet)") +set(BOOTSTRAP_FALLBACK_TESTNET "${PROJECT_SOURCE_DIR}/contrib/bootstrap/testnet.signed" CACHE PATH "Fallback bootstrap path (testnet)") include(cmake/enable_lto.cmake) diff --git a/contrib/bootstrap/testnet.signed b/contrib/bootstrap/testnet.signed index 9ad107115..366c5c5a0 100644 --- a/contrib/bootstrap/testnet.signed +++ b/contrib/bootstrap/testnet.signed @@ -1 +1 @@ -d1:ald1:ci2e1:d3:iwp1:e32:9ãxÚsX«l%ìû€ê<,sØ›”•©÷ïå_1:i21:::ffff:144.76.164.2021:pi1666e1:vi0eee1:i5:gamma1:k32:ÞÊðòm=o›„ZÐ1ÿßmcŒ%»¸ÿû¾™SĹ1:p32:!EÏâéz˜ý:Š‹úý… /0¡Ú„ Ãݪ„µNçB1:rli0ei0ei8ei3ee1:ui1614788310454e1:vi0e1:xle1:z64:Œ¤u G¿”D“=Œxµ¢{ïÌ51þ`í߀ùEâw m)q2Øg¯±˜øš ï³À)˜TÑP•´ò³ö—Á1e \ No newline at end of file +ld1:ald1:ci2e1:d3:iwp1:e32:9ãxÚsX«l%ìû€ê<,sØ›”•©÷ïå_1:i21:::ffff:144.76.164.2021:pi1666e1:vi0eee1:i5:gamma1:k32:ÞÊðòm=o›„ZÐ1ÿßmcŒ%»¸ÿû¾™SĹ1:p32:!EÏâéz˜ý:Š‹úý… /0¡Ú„ Ãݪ„µNçB1:rli0ei0ei8ei3ee1:ui1614788310454e1:vi0e1:xle1:z64:Œ¤u G¿”D“=Œxµ¢{ïÌ51þ`í߀ùEâw m)q2Øg¯±˜øš ï³À)˜TÑP•´ò³ö—Á1ee diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index b4a8cab18..a42c76bb1 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -235,10 +235,24 @@ 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() +set(BOOTSTRAP_FALLBACKS) +foreach(bs IN ITEMS MAINNET TESTNET) + if(BOOTSTRAP_FALLBACK_${bs}) + message(STATUS "Building with ${bs} fallback boostrap path \"${BOOTSTRAP_FALLBACK_${bs}}\"") + file(READ "${BOOTSTRAP_FALLBACK_${bs}}" bs_data HEX) + if(bs STREQUAL TESTNET) + set(network "gamma") + elseif(bs STREQUAL MAINNET) + set(network "lokinet") + else() + string(TOLOWER "${bs}" network) + endif() + string(REGEX REPLACE "([0-9a-f][0-9a-f])" "\\\\x\\1" bs_data "${bs_data}") + set(BOOTSTRAP_FALLBACKS "${BOOTSTRAP_FALLBACKS}{\"${network}\"s, \"${bs_data}\"sv},\n") + endif() +endforeach() +configure_file("bootstrap-fallbacks.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/bootstrap-fallbacks.cpp" @ONLY) +target_sources(lokinet-amalgum PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/bootstrap-fallbacks.cpp") if(WITH_PEERSTATS_BACKEND) target_compile_definitions(lokinet-amalgum PRIVATE -DLOKINET_PEERSTATS_BACKEND) diff --git a/llarp/bootstrap-fallbacks.cpp.in b/llarp/bootstrap-fallbacks.cpp.in new file mode 100644 index 000000000..5c81ea716 --- /dev/null +++ b/llarp/bootstrap-fallbacks.cpp.in @@ -0,0 +1,25 @@ +#include +#include "llarp/bootstrap.hpp" + +namespace llarp +{ + using namespace std::literals; + + std::unordered_map + load_bootstrap_fallbacks() + { + std::unordered_map fallbacks; + using init_list = std::initializer_list>; + // clang-format off + for (const auto& [network, bootstrap] : init_list{ +@BOOTSTRAP_FALLBACKS@ + }) + // clang-format on + { + llarp_buffer_t buf{bootstrap.data(), bootstrap.size()}; + auto& bsl = fallbacks[network]; + bsl.BDecode(&buf); + } + return fallbacks; + } +} // namespace llarp diff --git a/llarp/bootstrap.hpp b/llarp/bootstrap.hpp index ba126c03a..c4a4b7d3f 100644 --- a/llarp/bootstrap.hpp +++ b/llarp/bootstrap.hpp @@ -2,6 +2,7 @@ #include "router_contact.hpp" #include +#include #include "llarp/util/fs.hpp" namespace llarp @@ -20,4 +21,8 @@ namespace llarp void Clear(); }; + + std::unordered_map + load_bootstrap_fallbacks(); + } // namespace llarp diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 8d207c38e..975c6074b 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -665,21 +665,14 @@ namespace llarp // if our conf had no bootstrap files specified, try the default location of // /bootstrap.signed. If this isn't present, leave a useful error message + // TODO: use constant + fs::path defaultBootstrapFile = conf.router.m_dataDir / "bootstrap.signed"; if (configRouters.empty() and conf.bootstrap.routers.empty()) { - // TODO: use constant - fs::path defaultBootstrapFile = conf.router.m_dataDir / "bootstrap.signed"; if (fs::exists(defaultBootstrapFile)) { configRouters.push_back(defaultBootstrapFile); } - else if (not conf.bootstrap.seednode) - { - LogError("No bootstrap files specified in config file, and the default"); - LogError("bootstrap file ", defaultBootstrapFile, " does not exist."); - LogError("Please provide a bootstrap file (e.g. run 'lokinet-bootstrap)'"); - throw std::runtime_error("No bootstrap files available."); - } } BootstrapList b_list; @@ -708,7 +701,7 @@ namespace llarp { if (rc.IsObsoleteBootstrap()) { - LogWarn("ignoring obsolete boostrap RC: ", RouterID(rc.pubkey)); + log::warning(logcat, "ignoring obsolete boostrap RC: {}", RouterID(rc.pubkey)); continue; } if (not rc.Verify(Now())) @@ -722,29 +715,29 @@ namespace llarp 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) { - if (not bootstrap_fallback.empty()) + auto fallbacks = llarp::load_bootstrap_fallbacks(); + if (auto itr = fallbacks.find(_rc.netID.ToString()); itr != fallbacks.end()) { - b_list.clear(); - b_list.AddFromFile(bootstrap_fallback); + b_list = itr->second; verifyRCs(); } - if (bootstrapRCList.empty()) // empty after trying fallback, if set - throw std::runtime_error{"we have no bootstrap nodes"}; + if (bootstrapRCList.empty() + and not conf.bootstrap.seednode) // empty after trying fallback, if set + { + log::error( + logcat, + "No bootstrap routers were loaded. The default bootstrap file {} does not exist, and " + "loading fallback bootstrap RCs failed.", + defaultBootstrapFile); + throw std::runtime_error("No bootstrap nodes available."); + } } if (conf.bootstrap.seednode) - { LogInfo("we are a seed node"); - } else LogInfo("Loaded ", bootstrapRCList.size(), " bootstrap routers");