From 5fee401fe14aa6459428a26a82f764db70a6a0b9 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 4 Jan 2012 23:39:45 +0100 Subject: CAddrMan: stochastic address manager Design goals: * Only keep a limited number of addresses around, so that addr.dat does not grow without bound. * Keep the address tables in-memory, and occasionally write the table to addr.dat. * Make sure no (localized) attacker can fill the entire table with his nodes/addresses. See comments in addrman.h for more detailed information. --- src/db.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 23 deletions(-) (limited to 'src/db.cpp') diff --git a/src/db.cpp b/src/db.cpp index ea6d46a6e5..645f725153 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -621,44 +621,65 @@ bool CAddrDB::WriteAddress(const CAddress& addr) return Write(make_pair(string("addr"), addr.GetKey()), addr); } +bool CAddrDB::WriteAddrman(const CAddrMan& addrman) +{ + return Write(string("addrman"), addrman); +} + bool CAddrDB::EraseAddress(const CAddress& addr) { return Erase(make_pair(string("addr"), addr.GetKey())); } -bool CAddrDB::LoadAddresses() +bool CAddrDB::LoadAddresses(bool &fUpdate) { - CRITICAL_BLOCK(cs_mapAddresses) + bool fAddrMan = false; + if (Read(string("addrman"), addrman)) { - // Get cursor - Dbc* pcursor = GetCursor(); - if (!pcursor) + printf("Loaded %i addresses\n", addrman.size()); + fAddrMan = true; + } + + vector vAddr; + + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + return false; + + loop + { + // Read next record + CDataStream ssKey; + CDataStream ssValue; + int ret = ReadAtCursor(pcursor, ssKey, ssValue); + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) return false; - loop + // Unserialize + string strType; + ssKey >> strType; + if (strType == "addr") { - // Read next record - CDataStream ssKey; - CDataStream ssValue; - int ret = ReadAtCursor(pcursor, ssKey, ssValue); - if (ret == DB_NOTFOUND) - break; - else if (ret != 0) - return false; - - // Unserialize - string strType; - ssKey >> strType; - if (strType == "addr") + if (fAddrMan) + fUpdate = true; + else { CAddress addr; ssValue >> addr; - mapAddresses.insert(make_pair(addr.GetKey(), addr)); + vAddr.push_back(addr); } + } - pcursor->close(); + } + pcursor->close(); - printf("Loaded %d addresses\n", mapAddresses.size()); + if (!fAddrMan) + { + addrman.Add(vAddr, CNetAddr("0.0.0.0")); + printf("Loaded %i addresses\n", addrman.size()); } return true; @@ -666,7 +687,11 @@ bool CAddrDB::LoadAddresses() bool LoadAddresses() { - return CAddrDB("cr+").LoadAddresses(); + bool fUpdate = false; + bool fRet = CAddrDB("cr+").LoadAddresses(fUpdate); + if (fUpdate) + CDB::Rewrite("addr.dat", "\004addr"); + return fRet; } -- cgit v1.2.3