Changeset View
Changeset View
Standalone View
Standalone View
src/seeder/db.h
Show First 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | public: | ||||
template <typename Stream, typename Operation> | template <typename Stream, typename Operation> | ||||
inline void SerializationOp(Stream &s, Operation ser_action) { | inline void SerializationOp(Stream &s, Operation ser_action) { | ||||
READWRITE(weight); | READWRITE(weight); | ||||
READWRITE(count); | READWRITE(count); | ||||
READWRITE(reliability); | READWRITE(reliability); | ||||
} | } | ||||
friend class CAddrInfo; | friend class SeederAddrInfo; | ||||
}; | }; | ||||
class CAddrReport { | class CAddrReport { | ||||
public: | public: | ||||
CService ip; | CService ip; | ||||
int clientVersion; | int clientVersion; | ||||
int blocks; | int blocks; | ||||
double uptime[5]; | double uptime[5]; | ||||
std::string clientSubVersion; | std::string clientSubVersion; | ||||
int64_t lastSuccess; | int64_t lastSuccess; | ||||
bool fGood; | bool fGood; | ||||
uint64_t services; | uint64_t services; | ||||
}; | }; | ||||
class CAddrInfo { | class SeederAddrInfo { | ||||
private: | private: | ||||
CService ip; | CService ip; | ||||
uint64_t services; | uint64_t services; | ||||
int64_t lastTry; | int64_t lastTry; | ||||
int64_t ourLastTry; | int64_t ourLastTry; | ||||
int64_t ourLastSuccess; | int64_t ourLastSuccess; | ||||
int64_t ignoreTill; | int64_t ignoreTill; | ||||
CAddrStat stat2H; | CAddrStat stat2H; | ||||
CAddrStat stat8H; | CAddrStat stat8H; | ||||
CAddrStat stat1D; | CAddrStat stat1D; | ||||
CAddrStat stat1W; | CAddrStat stat1W; | ||||
CAddrStat stat1M; | CAddrStat stat1M; | ||||
int clientVersion; | int clientVersion; | ||||
int blocks; | int blocks; | ||||
int total; | int total; | ||||
int success; | int success; | ||||
std::string clientSubVersion; | std::string clientSubVersion; | ||||
public: | public: | ||||
CAddrInfo() | SeederAddrInfo() | ||||
: services(0), lastTry(0), ourLastTry(0), ourLastSuccess(0), | : services(0), lastTry(0), ourLastTry(0), ourLastSuccess(0), | ||||
ignoreTill(0), clientVersion(0), blocks(0), total(0), success(0) {} | ignoreTill(0), clientVersion(0), blocks(0), total(0), success(0) {} | ||||
CAddrReport GetReport() const { | CAddrReport GetReport() const { | ||||
CAddrReport ret; | CAddrReport ret; | ||||
ret.ip = ip; | ret.ip = ip; | ||||
ret.clientVersion = clientVersion; | ret.clientVersion = clientVersion; | ||||
ret.clientSubVersion = clientSubVersion; | ret.clientSubVersion = clientSubVersion; | ||||
▲ Show 20 Lines • Show All 169 Lines • ▼ Show 20 Lines | |||||
* (d) good nodes (c) non-good nodes | * (d) good nodes (c) non-good nodes | ||||
*/ | */ | ||||
class CAddrDb { | class CAddrDb { | ||||
private: | private: | ||||
mutable RecursiveMutex cs; | mutable RecursiveMutex cs; | ||||
// number of address id's | // number of address id's | ||||
int nId; | int nId; | ||||
// map address id to address info (b,c,d,e) | // map address id to address info (b,c,d,e) | ||||
std::map<int, CAddrInfo> idToInfo; | std::map<int, SeederAddrInfo> idToInfo; | ||||
// map ip to id (b,c,d,e) | // map ip to id (b,c,d,e) | ||||
std::map<CService, int> ipToId; | std::map<CService, int> ipToId; | ||||
// sequence of tried nodes, in order we have tried connecting to them (c,d) | // sequence of tried nodes, in order we have tried connecting to them (c,d) | ||||
std::deque<int> ourId; | std::deque<int> ourId; | ||||
// set of nodes not yet tried (b) | // set of nodes not yet tried (b) | ||||
std::set<int> unkId; | std::set<int> unkId; | ||||
// set of good nodes (d, good e) | // set of good nodes (d, good e) | ||||
std::set<int> goodId; | std::set<int> goodId; | ||||
Show All 31 Lines | void GetStats(CAddrDbStats &stats) const { | ||||
if (ourId.size() > 0) { | if (ourId.size() > 0) { | ||||
stats.nAge = time(nullptr) - idToInfo.at(ourId.at(0)).ourLastTry; | stats.nAge = time(nullptr) - idToInfo.at(ourId.at(0)).ourLastTry; | ||||
} else { | } else { | ||||
stats.nAge = 0; | stats.nAge = 0; | ||||
} | } | ||||
} | } | ||||
void ResetIgnores() { | void ResetIgnores() { | ||||
for (std::map<int, CAddrInfo>::iterator it = idToInfo.begin(); | for (std::map<int, SeederAddrInfo>::iterator it = idToInfo.begin(); | ||||
it != idToInfo.end(); it++) { | it != idToInfo.end(); it++) { | ||||
(*it).second.ignoreTill = 0; | (*it).second.ignoreTill = 0; | ||||
} | } | ||||
} | } | ||||
std::vector<CAddrReport> GetAll() { | std::vector<CAddrReport> GetAll() { | ||||
std::vector<CAddrReport> ret; | std::vector<CAddrReport> ret; | ||||
LOCK(cs); | LOCK(cs); | ||||
for (std::deque<int>::const_iterator it = ourId.begin(); | for (std::deque<int>::const_iterator it = ourId.begin(); | ||||
it != ourId.end(); it++) { | it != ourId.end(); it++) { | ||||
const CAddrInfo &info = idToInfo[*it]; | const SeederAddrInfo &info = idToInfo[*it]; | ||||
if (info.success > 0) { | if (info.success > 0) { | ||||
ret.push_back(info.GetReport()); | ret.push_back(info.GetReport()); | ||||
} | } | ||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
// serialization code | // serialization code | ||||
// format: | // format: | ||||
// nVersion (0 for now) | // nVersion (0 for now) | ||||
// n (number of ips in (b,c,d)) | // n (number of ips in (b,c,d)) | ||||
// CAddrInfo[n] | // SeederAddrInfo[n] | ||||
// banned | // banned | ||||
// acquires a shared lock (this does not suffice for read mode, but we | // acquires a shared lock (this does not suffice for read mode, but we | ||||
// assume that only happens at startup, single-threaded) this way, dumping | // assume that only happens at startup, single-threaded) this way, dumping | ||||
// does not interfere with GetIPs_, which is called from the DNS thread | // does not interfere with GetIPs_, which is called from the DNS thread | ||||
template <typename Stream> void Serialize(Stream &s) const { | template <typename Stream> void Serialize(Stream &s) const { | ||||
LOCK(cs); | LOCK(cs); | ||||
int nVersion = 0; | int nVersion = 0; | ||||
s << nVersion; | s << nVersion; | ||||
CAddrDb *db = const_cast<CAddrDb *>(this); | CAddrDb *db = const_cast<CAddrDb *>(this); | ||||
int n = ourId.size() + unkId.size(); | int n = ourId.size() + unkId.size(); | ||||
s << n; | s << n; | ||||
for (std::deque<int>::const_iterator it = ourId.begin(); | for (std::deque<int>::const_iterator it = ourId.begin(); | ||||
it != ourId.end(); it++) { | it != ourId.end(); it++) { | ||||
std::map<int, CAddrInfo>::iterator ci = db->idToInfo.find(*it); | std::map<int, SeederAddrInfo>::iterator ci = db->idToInfo.find(*it); | ||||
s << (*ci).second; | s << (*ci).second; | ||||
} | } | ||||
for (std::set<int>::const_iterator it = unkId.begin(); | for (std::set<int>::const_iterator it = unkId.begin(); | ||||
it != unkId.end(); it++) { | it != unkId.end(); it++) { | ||||
std::map<int, CAddrInfo>::iterator ci = db->idToInfo.find(*it); | std::map<int, SeederAddrInfo>::iterator ci = db->idToInfo.find(*it); | ||||
s << (*ci).second; | s << (*ci).second; | ||||
} | } | ||||
s << banned; | s << banned; | ||||
} | } | ||||
template <typename Stream> void Unserialize(Stream &s) { | template <typename Stream> void Unserialize(Stream &s) { | ||||
LOCK(cs); | LOCK(cs); | ||||
int nVersion; | int nVersion; | ||||
s >> nVersion; | s >> nVersion; | ||||
CAddrDb *db = const_cast<CAddrDb *>(this); | CAddrDb *db = const_cast<CAddrDb *>(this); | ||||
db->nId = 0; | db->nId = 0; | ||||
int n; | int n; | ||||
s >> n; | s >> n; | ||||
for (int i = 0; i < n; i++) { | for (int i = 0; i < n; i++) { | ||||
CAddrInfo info; | SeederAddrInfo info; | ||||
s >> info; | s >> info; | ||||
if (!info.GetBanTime()) { | if (!info.GetBanTime()) { | ||||
int id = db->nId++; | int id = db->nId++; | ||||
db->idToInfo[id] = info; | db->idToInfo[id] = info; | ||||
db->ipToId[info.ip] = id; | db->ipToId[info.ip] = id; | ||||
if (info.ourLastTry) { | if (info.ourLastTry) { | ||||
db->ourId.push_back(id); | db->ourId.push_back(id); | ||||
if (info.IsReliable()) { | if (info.IsReliable()) { | ||||
▲ Show 20 Lines • Show All 56 Lines • Show Last 20 Lines |