31 nCreateTime(
json[
"ban_created"].getInt<int64_t>()),
32 nBanUntil(
json[
"banned_until"].getInt<int64_t>()) {}
54 for (
const auto &it : bans) {
55 const auto &address = it.first;
56 const auto &ban_entry = it.second;
73 for (
const auto &ban_entry_json : bans_json.
getValues()) {
78 "Dropping entry with unknown version (%s) from ban list\n",
85 LogPrintf(
"Dropping entry with unparseable address or subnet (%s) "
90 bans.insert_or_assign(subnet,
CBanEntry{ban_entry_json});
94class DbNotFoundError :
public std::exception {
95 using std::exception::exception;
98template <
typename Stream,
typename Data>
99bool SerializeDB(
const CChainParams &chainParams, Stream &stream,
104 hashwriter << chainParams.
DiskMagic() << data;
105 stream << hashwriter.GetHash();
106 }
catch (
const std::exception &e) {
107 LogError(
"%s: Serialize or I/O error - %s\n", __func__, e.what());
114template <
typename Data>
116 const fs::path &path,
const Data &data) {
125 if (fileout.IsNull()) {
128 LogError(
"%s: Failed to open file %s\n", __func__,
134 if (!SerializeDB(chainParams, fileout, data)) {
142 LogError(
"%s: Failed to flush file %s\n", __func__,
151 LogError(
"%s: Rename-into-place failed\n", __func__);
158template <
typename Stream,
typename Data>
159void DeserializeDB(
const CChainParams &chainParams, Stream &stream, Data &&data,
160 bool fCheckSum =
true) {
163 uint8_t pchMsgTmp[4];
164 verifier >> pchMsgTmp;
166 if (memcmp(pchMsgTmp, std::begin(chainParams.
DiskMagic()),
167 sizeof(pchMsgTmp))) {
168 throw std::runtime_error{
"Invalid network magic number"};
178 if (hashTmp != verifier.GetHash()) {
179 throw std::runtime_error{
"Checksum mismatch, data corrupted"};
184template <
typename Data>
189 if (filein.IsNull()) {
190 throw DbNotFoundError{};
193 DeserializeDB(chainParams, filein, data);
199 : m_banlist_dat(ban_list_path +
".dat"),
200 m_banlist_json(ban_list_path +
".json"), chainParams(_chainParams) {}
203 std::vector<std::string> errors;
209 for (
const auto &err : errors) {
227 }
catch (
const std::exception &) {
228 LogPrintf(
"Missing or invalid file %s\n",
237 std::map<std::string, util::SettingsValue> settings;
238 std::vector<std::string> errors;
241 for (
const auto &err : errors) {
242 LogPrintf(
"Cannot load banlist %s: %s\n",
249 BanMapFromJson(settings[
JSON_KEY], banSet);
250 }
catch (
const std::runtime_error &e) {
251 LogPrintf(
"Cannot parse banlist %s: %s\n",
262 return SerializeFileDB(chainParams,
"peers", pathAddr, addr);
267 DeserializeDB(chainParams, ssPeers, addr,
false);
273 auto check_addrman = std::clamp<int32_t>(
277 std::make_unique<AddrMan>(asmap,
false,
283 DeserializeFileDB(chainparams, path_addr, *addrman);
284 LogPrintf(
"Loaded %i addresses from peers.dat %dms\n", addrman->size(),
286 }
catch (
const DbNotFoundError &) {
288 addrman = std::make_unique<AddrMan>(
291 LogPrintf(
"Creating peers.dat because the file was not found (%s)\n",
297 strprintf(
_(
"Failed to rename invalid peers.dat file. "
298 "Please move or delete it and try again."))};
301 addrman = std::make_unique<AddrMan>(
304 LogPrintf(
"Creating new peers.dat because the file version was not "
305 "compatible (%s). Original backed up to peers.dat.bak\n",
308 }
catch (
const std::exception &e) {
310 _(
"Invalid or corrupt peers.dat (%s). If you believe this is a "
311 "bug, please report it to %s. As a workaround, you can move the "
312 "file (%s) out of the way (rename, move, or delete) to have a "
313 "new one created on the next start."),
314 e.what(), PACKAGE_BUGREPORT,
321 return {std::move(addrman)};
326 const std::vector<CAddress> &anchors) {
328 "Flush %d outbound block-relay-only peer addresses to anchors.dat",
330 SerializeFileDB(chainParams,
"anchors", anchors_db_path,
336 std::vector<CAddress> anchors;
338 DeserializeFileDB(chainParams, anchors_db_path,
340 LogPrintf(
"Loaded %i addresses from %s\n", anchors.size(),
342 }
catch (
const std::exception &) {
346 fs::remove(anchors_db_path);
std::vector< CAddress > ReadAnchors(const CChainParams &chainParams, const fs::path &anchors_db_path)
Read the anchor IP address database (anchors.dat)
void ReadFromStream(const CChainParams &chainParams, AddrMan &addr, DataStream &ssPeers)
Only used by tests.
util::Result< std::unique_ptr< AddrMan > > LoadAddrman(const CChainParams &chainparams, const std::vector< bool > &asmap, const ArgsManager &args)
Returns an error string on failure.
bool DumpPeerAddresses(const CChainParams &chainParams, const ArgsManager &args, const AddrMan &addr)
static const char * BANMAN_JSON_ADDR_KEY
void DumpAnchors(const CChainParams &chainParams, const fs::path &anchors_db_path, const std::vector< CAddress > &anchors)
Dump the anchor IP address database (anchors.dat)
static const char * BANMAN_JSON_VERSION_KEY
static constexpr int32_t DEFAULT_ADDRMAN_CONSISTENCY_CHECKS
Default for -checkaddrman.
Stochastic address manager.
fs::path GetDataDirNet() const
Get data directory path with appended network identifier.
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
Non-refcounted RAII wrapper for FILE*.
static constexpr SerParams V1_DISK
static constexpr SerParams V2_DISK
bool Write(const banmap_t &banSet)
bool Read(banmap_t &banSet, bool &dirty)
Read the banlist from disk.
const fs::path m_banlist_dat
CBanDB(fs::path ban_list_path, const CChainParams &_chainParams)
static constexpr const char * JSON_KEY
JSON key under which the data is stored in the json database.
const fs::path m_banlist_json
const CChainParams & chainParams
static const int CURRENT_VERSION
UniValue ToJson() const
Generate a JSON representation of this ban entry.
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
const CMessageHeader::MessageMagic & DiskMagic() const
Double ended buffer combining vector and stream-like interfaces.
Reads data from an underlying stream, while hashing the read data.
Writes data to an underlying source stream, while hashing the written data.
I rand() noexcept
Generate a random integer in its entire (non-negative) range.
void push_back(UniValue val)
const std::vector< UniValue > & getValues() const
void pushKV(std::string key, UniValue val)
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
bool RenameOver(fs::path src, fs::path dest)
bool FileCommit(FILE *file)
Ensure file contents are fully committed to disk, using a platform-specific feature analogous to fsyn...
char const * json() noexcept
Template to generate JSON data.
static auto quoted(const std::string &s)
static bool exists(const path &p)
static std::string PathToString(const path &path)
Convert path object to byte string.
FILE * fopen(const fs::path &p, const char *mode)
bool ReadSettings(const fs::path &path, std::map< std::string, SettingsValue > &values, std::vector< std::string > &errors)
Read settings file.
bool WriteSettings(const fs::path &path, const std::map< std::string, SettingsValue > &values, std::vector< std::string > &errors)
Write settings file.
std::map< CSubNet, CBanEntry > banmap_t
bool LookupSubNet(const std::string &strSubnet, CSubNet &ret, DNSLookupFn dns_lookup_function)
Parse and resolve a specified subnet string into the appropriate internal representation.
static auto WithParams(const Params ¶ms, T &&t)
Return a wrapper around t that (de)serializes it with specified parameter params.
int64_t GetTimeMillis()
Returns the system time (not mockable)
#define LOG_TIME_SECONDS(end_msg)
bilingual_str _(const char *psz)
Translation function.