From 57c77fe4d318a156d98606ee74f0064b22c31631 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 3 Jul 2015 09:26:51 +0200 Subject: [PATCH 1/4] banlist: update set dirty to be more fine grained - move the SetBannedSetDirty(false) call from DumpData() into DumpBanlist() - ensure we only set false, if the write succeeded --- src/net.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 87c4f0af0..b13177fe2 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1455,10 +1455,7 @@ void DumpData() DumpAddresses(); if (CNode::BannedSetIsDirty()) - { DumpBanlist(); - CNode::SetBannedSetDirty(false); - } } void static ProcessOneShot() @@ -2484,14 +2481,14 @@ bool CBanDB::Read(banmap_t& banSet) void DumpBanlist() { int64_t nStart = GetTimeMillis(); - - CNode::SweepBanned(); //clean unused entries (if bantime has expired) + CNode::SweepBanned(); // clean unused entries (if bantime has expired) CBanDB bandb; banmap_t banmap; CNode::GetBanned(banmap); - bandb.Write(banmap); + if (bandb.Write(banmap)) + CNode::SetBannedSetDirty(false); LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", - banmap.size(), GetTimeMillis() - nStart); + banmap.size(), GetTimeMillis() - nStart); } From ce479aaadaab296f0d06808fe230c4b13523cc28 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 3 Jul 2015 09:44:49 +0200 Subject: [PATCH 2/4] banlist: better handling of banlist in StartNode() - only start working on/with banlist data, if reading in the banlist from disk didn't fail - as CNode::setBannedIsDirty is false (default) when reading fails, we don't need to explicitly set it to false to prevent writing banlist.dat in that case either --- src/net.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index b13177fe2..6d39ccecd 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1909,15 +1909,16 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) //try to read stored banlist CBanDB bandb; banmap_t banmap; - if (!bandb.Read(banmap)) + if (bandb.Read(banmap)) { + CNode::SetBanned(banmap); // thread save setter + CNode::SetBannedSetDirty(false); // no need to write down, just read data + CNode::SweepBanned(); // sweep out unused entries + + LogPrint("net", "Loaded %d banned node ips/subnets from banlist.dat %dms\n", + banmap.size(), GetTimeMillis() - nStart); + } else LogPrintf("Invalid or missing banlist.dat; recreating\n"); - CNode::SetBanned(banmap); //thread save setter - CNode::SetBannedSetDirty(false); //no need to write down just read or nonexistent data - CNode::SweepBanned(); //sweap out unused entries - - LogPrintf("Loaded %i addresses from peers.dat %dms\n", - addrman.size(), GetTimeMillis() - nStart); fAddressesInitialized = true; if (semOutbound == NULL) { From 2977c243efc9f122328de1bcfe12364498e0e2b6 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 3 Jul 2015 09:46:17 +0200 Subject: [PATCH 3/4] banlist: add more banlist infos to log / add GUI signal - to match the peers.dat handling also supply a debug.log entry for how many entries were loaded from banlist.dat and how long it took - add a GUI init message for loading the banlist (same as with peers.dat) - move the same message for peers.dat upwards in the code, to be able to reuse the timing variable nStart and also just log, if our read from peers.dat didn't fail --- src/net.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 6d39ccecd..88a8edebc 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -35,7 +35,7 @@ #include #include -// Dump addresses to peers.dat every 15 minutes (900s) +// Dump addresses to peers.dat and banlist.dat every 15 minutes (900s) #define DUMP_ADDRESSES_INTERVAL 900 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL) @@ -555,11 +555,13 @@ void CNode::SweepBanned() banmap_t::iterator it = setBanned.begin(); while(it != setBanned.end()) { + CSubNet subNet = (*it).first; CBanEntry banEntry = (*it).second; if(now > banEntry.nBanUntil) { setBanned.erase(it++); setBannedIsDirty = true; + LogPrint("net", "%s: Removed banned node ip/subnet from banlist.dat: %s\n", __func__, subNet.ToString()); } else ++it; @@ -1898,15 +1900,19 @@ void static Discover(boost::thread_group& threadGroup) void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) { uiInterface.InitMessage(_("Loading addresses...")); - // Load addresses for peers.dat + // Load addresses from peers.dat int64_t nStart = GetTimeMillis(); { CAddrDB adb; - if (!adb.Read(addrman)) + if (adb.Read(addrman)) + LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman.size(), GetTimeMillis() - nStart); + else LogPrintf("Invalid or missing peers.dat; recreating\n"); } - //try to read stored banlist + uiInterface.InitMessage(_("Loading banlist...")); + // Load addresses from banlist.dat + nStart = GetTimeMillis(); CBanDB bandb; banmap_t banmap; if (bandb.Read(banmap)) { @@ -1923,7 +1929,7 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) if (semOutbound == NULL) { // initialize semaphore - int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections); + int nMaxOutbound = std::min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections); semOutbound = new CSemaphore(nMaxOutbound); } From e8600c924d58f3ef0450fc269998452e5b17aecb Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 3 Jul 2015 10:46:08 +0200 Subject: [PATCH 4/4] banlist (bugfix): allow CNode::SweepBanned() to run on interval - allows CNode::SweepBanned() to run, even if !CNode::BannedSetIsDirty(), because if nBanUntil is over we want the ban to be disabled for these nodes --- src/net.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 88a8edebc..15ddaac63 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1455,9 +1455,7 @@ void DumpAddresses() void DumpData() { DumpAddresses(); - - if (CNode::BannedSetIsDirty()) - DumpBanlist(); + DumpBanlist(); } void static ProcessOneShot() @@ -2474,22 +2472,26 @@ bool CBanDB::Read(banmap_t& banSet) // ... verify the network matches ours if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) return error("%s: Invalid network magic number", __func__); - + // de-serialize address data into one CAddrMan object ssBanlist >> banSet; } catch (const std::exception& e) { return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } - + return true; } void DumpBanlist() { - int64_t nStart = GetTimeMillis(); CNode::SweepBanned(); // clean unused entries (if bantime has expired) + if (!CNode::BannedSetIsDirty()) + return; + + int64_t nStart = GetTimeMillis(); + CBanDB bandb; banmap_t banmap; CNode::GetBanned(banmap);