diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ff4641e --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +dnsseed: dns.o bitcoin.cpp netbase.cpp protocol.cpp db.cpp main.cpp bitcoin.h netbase.h protocol.h db.h serialize.h uint256.h util.h + g++ -pthread -lssl -O3 -ggdb3 -march=nocona -Wno-invalid-offsetof -o dnsseed bitcoin.cpp netbase.cpp protocol.cpp db.cpp main.cpp dns.o + +dns.o: dns.c + gcc -std=c99 -O3 -g0 -march=nocona dns.c -c -o dns.o + diff --git a/bitcoin.cpp b/bitcoin.cpp new file mode 100644 index 0000000..2a16026 --- /dev/null +++ b/bitcoin.cpp @@ -0,0 +1,285 @@ +#include + +#include "db.h" +#include "netbase.h" +#include "protocol.h" +#include "serialize.h" +#include "uint256.h" + +#define BITCOIN_SEED_NONCE 0x0539a019ca550825 +#define REQUIRE_HEIGHT 140700 +#define MIN_VERSION 40000 + +using namespace std; + +class CNode { + SOCKET sock; + CDataStream vSend; + CDataStream vRecv; + unsigned int nHeaderStart; + unsigned int nMessageStart; + int nVersion; + int nRecvVersion; + string strSubVer; + int nStartingHeight; + vector *vAddr; + int ban; + int64 doneAfter; + CAddress you; + + void BeginMessage(const char *pszCommand) { + if (nHeaderStart != -1) AbortMessage(); + nHeaderStart = vSend.size(); + vSend << CMessageHeader(pszCommand, 0); + nMessageStart = vSend.size(); + printf("%s: SEND %s\n", you.ToString().c_str(), pszCommand); + } + + void AbortMessage() { + if (nHeaderStart == -1) return; + vSend.resize(nHeaderStart); + nHeaderStart = -1; + nMessageStart = -1; + } + + void EndMessage() { + if (nHeaderStart == -1) return; + unsigned int nSize = vSend.size() - nMessageStart; + memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); + if (vSend.GetVersion() >= 209) { + uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end()); + unsigned int nChecksum = 0; + memcpy(&nChecksum, &hash, sizeof(nChecksum)); + assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum)); + memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum)); + } + nHeaderStart = -1; + nMessageStart = -1; + } + + void Send() { + if (sock == INVALID_SOCKET) return; + if (vSend.empty()) return; + int nBytes = send(sock, &vSend[0], vSend.size(), 0); + if (nBytes > 0) { + vSend.erase(vSend.begin(), vSend.begin() + nBytes); + } else { + close(sock); + sock = INVALID_SOCKET; + } + } + + void PushVersion() { + int64 nTime = time(NULL); + uint64 nLocalNonce = BITCOIN_SEED_NONCE; + int64 nLocalServices = 0; + CAddress me(CIPPort("0.0.0.0")); + BeginMessage("version"); + int nBestHeight = REQUIRE_HEIGHT; + string ver = "/bitcoin-seeder:0.01/"; + vSend << PROTOCOL_VERSION << nLocalServices << nTime << you << me << nLocalNonce << ver << nBestHeight; + EndMessage(); + } + + void GotVersion() { + if (nVersion < MIN_VERSION) { + printf("%s: BAD (version %i is below %i)\n", you.ToString().c_str(), nVersion, MIN_VERSION); + ban = 1000000; + return; + } + printf("%s: version %i\n", you.ToString().c_str(), nVersion); + BeginMessage("getaddr"); + EndMessage(); + doneAfter = time(NULL) + 10; + } + + bool ProcessMessage(string strCommand, CDataStream& vRecv) { + printf("%s: RECV %s\n", you.ToString().c_str(), strCommand.c_str()); + if (strCommand == "version") { + int64 nTime; + CAddress addrMe; + CAddress addrFrom; + uint64 nNonce = 1; + vRecv >> nVersion >> you.nServices >> nTime >> addrMe; + if (nVersion == 10300) nVersion = 300; + if (nVersion >= 106 && !vRecv.empty()) + vRecv >> addrFrom >> nNonce; + if (nVersion >= 106 && !vRecv.empty()) + vRecv >> strSubVer; + if (nVersion >= 209 && !vRecv.empty()) + vRecv >> nStartingHeight; + + if (!(you.nServices & NODE_NETWORK)) { + printf("%s: BAD (no NODE_NETWORK)\n", you.ToString().c_str()); + ban = 1000000; + return true; + } + + if (nVersion >= 209) { + BeginMessage("verack"); + EndMessage(); + } + vSend.SetVersion(min(nVersion, PROTOCOL_VERSION)); + if (nVersion < 209) { + this->vRecv.SetVersion(min(nVersion, PROTOCOL_VERSION)); + GotVersion(); + } + return false; + } + + if (strCommand == "verack") { + this->vRecv.SetVersion(min(nVersion, PROTOCOL_VERSION)); + GotVersion(); + return false; + } + + if (strCommand == "addr") { + vector vAddrNew; + vRecv >> vAddrNew; + printf("%s: got %i addresses\n", you.ToString().c_str(), (int)vAddrNew.size()); + int64 now = time(NULL); + vector::iterator it = vAddrNew.begin(); + if (doneAfter == 0 || doneAfter > now + 1) doneAfter = now + 1; + while (it != vAddrNew.end()) { + CAddress &addr = *it; +// printf("%s: got address %s\n", you.ToString().c_str(), addr.ToString().c_str(), (int)(vAddr->size())); + it++; + if (!addr.IsIPv4()) + continue; + if (addr.nTime <= 100000000 || addr.nTime > now + 600) + addr.nTime = now - 5 * 86400; + vAddr->push_back(addr); +// printf("%s: added address %s (#%i)\n", you.ToString().c_str(), addr.ToString().c_str(), (int)(vAddr->size())); + if (vAddr->size() > 1000) {doneAfter = 1; return true; } + } + return false; + } + + return false; + } + + bool ProcessMessages() { + if (vRecv.empty()) return false; + do { + CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart)); + int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader()); + if (vRecv.end() - pstart < nHeaderSize) { + if (vRecv.size() > nHeaderSize) { + vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize); + } + break; + } + vRecv.erase(vRecv.begin(), pstart); + vector vHeaderSave(vRecv.begin(), vRecv.begin() + nHeaderSize); + CMessageHeader hdr; + vRecv >> hdr; + if (!hdr.IsValid()) { + printf("%s: BAD (invalid header)\n", you.ToString().c_str()); + ban = 100000; return true; + } + string strCommand = hdr.GetCommand(); + unsigned int nMessageSize = hdr.nMessageSize; + if (nMessageSize > MAX_SIZE) { + printf("%s: BAD (message too large)\n", you.ToString().c_str()); + ban = 100000; + return true; + } + if (nMessageSize > vRecv.size()) { + vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end()); + break; + } + if (vRecv.GetVersion() >= 209) { + uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize); + unsigned int nChecksum = 0; + memcpy(&nChecksum, &hash, sizeof(nChecksum)); + if (nChecksum != hdr.nChecksum) continue; + } + CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion); + vRecv.ignore(nMessageSize); + if (ProcessMessage(strCommand, vMsg)) + return true; + printf("%s: done processing %s\n", you.ToString().c_str(), strCommand.c_str()); + } while(1); + return false; + } + +public: + CNode(const CIPPort& ip, vector& vAddrIn) : you(ip), nHeaderStart(-1), nMessageStart(-1), vAddr(&vAddrIn) { + vSend.SetType(SER_NETWORK); + vSend.SetVersion(0); + vRecv.SetType(SER_NETWORK); + vRecv.SetVersion(0); + if (time(NULL) > 1329696000) { + vSend.SetVersion(209); + vRecv.SetVersion(209); + } + } + bool Run() { + bool res = true; + if (!you.ConnectSocket(sock)) return false; + PushVersion(); + Send(); + int64 now; + while (now = time(NULL), ban == 0 && (doneAfter == 0 || doneAfter > now) && sock != INVALID_SOCKET) { + char pchBuf[0x10000]; + fd_set set; + FD_ZERO(&set); + FD_SET(sock,&set); + struct timeval wa; + if (doneAfter) { + wa.tv_sec = doneAfter - now; + wa.tv_usec = 0; + } else { + wa.tv_sec = 10; + wa.tv_usec = 0; + } + int ret = select(sock+1, &set, NULL, &set, &wa); + if (ret != 1) { + if (!doneAfter) res = false; + break; + } + int nBytes = recv(sock, pchBuf, sizeof(pchBuf), 0); + int nPos = vRecv.size(); + if (nBytes > 0) { + vRecv.resize(nPos + nBytes); + memcpy(&vRecv[nPos], pchBuf, nBytes); + } else if (nBytes == 0) { + Sleep(127); + } else { + break; + } + ProcessMessages(); + Send(); + } + close(sock); + sock = INVALID_SOCKET; + return (ban == 0) && res; + } + + int GetBan() { + return ban; + } +}; + +bool TestNode(const CIPPort &cip, int &ban, vector& vAddr) { + CNode node(cip, vAddr); + bool ret = node.Run(); + if (!ret) { + ban = node.GetBan(); + } else { + ban = 0; + } + printf("%s: %s!!!\n", cip.ToString().c_str(), ret ? "GOOD" : "BAD"); + return ret; +} + +/* +int main(void) { + CIPPort ip("bitcoin.sipa.be", 8333, true); + vector vAddr; + vAddr.clear(); + int ban = 0; + bool ret = TestNode(ip, ban, vAddr); + printf("ret=%s ban=%i vAddr.size()=%i\n", ret ? "good" : "bad", ban, (int)vAddr.size()); +} +*/ diff --git a/bitcoin.h b/bitcoin.h new file mode 100644 index 0000000..4f6f766 --- /dev/null +++ b/bitcoin.h @@ -0,0 +1,8 @@ +#ifndef _BITCOIN_H_ +#define _BITCOIN_H_ 1 + +#include "protocol.h" + +bool TestNode(const CIPPort &cip, int &ban, std::vector& vAddr); + +#endif diff --git a/db.cpp b/db.cpp index 9765676..faa78d8 100644 --- a/db.cpp +++ b/db.cpp @@ -18,17 +18,30 @@ void CAddrInfo::Update(bool good) { } bool CAddrDb::Get_(CIPPort &ip) { - int tot = unkId.size() + ourId.size(); - if (tot == 0) return false; - int rnd = rand() % tot; - if (tot < unkId.size()) { - set::iterator it = unkId.begin(); - return *it; - } else { - int ret = ourId.front(); - ourId.pop_front(); - return ret; - } + int cont = 0; + do { + cont = 0; + int tot = unkId.size() + ourId.size(); + if (tot == 0) return false; + int rnd = rand() % tot; + if (rnd < unkId.size()) { + set::iterator it = unkId.begin(); + ip = idToInfo[*it].ip; + unkId.erase(it); + printf("From UNK: %s\n", ip.ToString().c_str()); + } else { + int ret = ourId.front(); + ourId.pop_front(); + if (unkId.size() > 0 && time(NULL) - idToInfo[ret].ourLastTry < MIN_RETRY) { + ourId.push_back(ret); + cont=1; + continue; + } + ip = idToInfo[ret].ip; + printf("From OUR: %s (size = %i)\n", ip.ToString().c_str(), (int)ourId.size()); + } + } while(cont); + return true; } int CAddrDb::Lookup_(const CIPPort &ip) { @@ -38,7 +51,9 @@ int CAddrDb::Lookup_(const CIPPort &ip) { } void CAddrDb::Good_(const CIPPort &addr) { + printf("%s: good!\n", addr.ToString().c_str()); int id = Lookup_(addr); + printf("%s: good (id=%i)!\n", addr.ToString().c_str(), id); if (id == -1) return; unkId.erase(id); banned.erase(addr); @@ -94,7 +109,7 @@ void CAddrDb::Add_(const CAddress &addr) { CIPPort ipp(addr); if (banned.count(ipp)) { time_t bantime = banned[ipp]; - if (bantime < time(NULL)) + if (bantime < time(NULL) && addr.nTime > bantime) banned.erase(ipp); else return; @@ -119,8 +134,8 @@ void CAddrDb::Add_(const CAddress &addr) { int id = nId++; idToInfo[id] = ai; ipToId[ipp] = id; + printf("%s: added as id %i\n", ipp.ToString().c_str(), ipToId[ipp]); unkId.insert(id); - printf("%s: added\n", addr.ToString().c_str()); } void CAddrDb::GetIPs_(set& ips, int max, bool fOnlyIPv4) { diff --git a/db.h b/db.h index ebfe88b..929bae8 100644 --- a/db.h +++ b/db.h @@ -11,6 +11,7 @@ #include "util.h" #define TAU 86400.0 +#define MIN_RETRY 1000 class CAddrInfo { private: @@ -26,7 +27,7 @@ private: int success; public: bool IsGood() { - return (weight > 0.5 & reliability/weight > 0.8 && timing/weight < 86400 && count/weight > 1.0) && ip.GetPort() == 8333; + return (weight > 0 && reliability/weight > 0.8 && timing/weight < 86400) && ip.GetPort() == 8333; } bool IsTerrible() { return (weight > 0.5 & reliability/weight < 0.2 && timing/weight < 86400 && count/weight > 2.0); @@ -65,6 +66,10 @@ protected: void GetIPs_(std::set& ips, int max, bool fOnlyIPv4); public: + void Stats() { + CRITICAL_BLOCK(cs) + printf("**** %i good, %lu our, %i unk, %i banned; %i known ips\n", (int)goodId.size(), (unsigned long)ourId.size(), (int)unkId.size(), (int)banned.size(), (int)ipToId.size()); + } void Add(const CAddress &addr) { CRITICAL_BLOCK(cs) Add_(addr); diff --git a/dns.c b/dns.c index 26d47d9..09fe31f 100644 --- a/dns.c +++ b/dns.c @@ -18,6 +18,8 @@ char *host = "seedtest.bitcoin.sipa.be"; char *ns = "vps.sipa.be"; char *mbox = "sipa.ulyssis.org"; +extern int GetIPList(struct in_addr *addr, int max, int ipv4only); + typedef enum { CLASS_IN = 1, QCLASS_ANY = 255 @@ -300,16 +302,18 @@ ssize_t static dnshandle(const unsigned char *inbuf, size_t insize, unsigned cha // A records if ((typ == TYPE_A || typ == QTYPE_ANY) && (cls == CLASS_IN || cls == QCLASS_ANY)) { - uint32_t ip = 0x01101102; - do { - int ret = write_record_a(&outpos, outend - auth_size, "", offset, CLASS_IN, datattl, (const struct in_addr*)(&ip)); + struct in_addr addr[20]; + int naddr = GetIPList(addr, 20, 1); + int n = 0; + while (n < naddr) { + int ret = write_record_a(&outpos, outend - auth_size, "", offset, CLASS_IN, datattl, &addr[n]); // printf("wrote A record: %i\n", ret); if (!ret) { - ip += 0x01101102; + n++; outbuf[7]++; } else break; - } while(1); + } } // Authority section @@ -360,8 +364,3 @@ int dnsserver(void) { } while(1); return 0; } - -int main(void) { - dnsserver(); - return 0; -} diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..314aafe --- /dev/null +++ b/main.cpp @@ -0,0 +1,69 @@ +#include + +#include "bitcoin.h" +#include "db.h" + +using namespace std; + +extern "C" { +// #include "dns.h" +} + +CAddrDb db; + +extern "C" void* ThreadCrawler(void* data) { + do { + db.Stats(); + CIPPort ip; + if (!db.Get(ip)) { + Sleep(5000); + continue; + } + int ban = 0; + vector addr; + bool ret = TestNode(ip,ban,addr); + db.Add(addr); + if (ret) { + db.Good(ip); + } else { + db.Bad(ip, ban); + } + } while(1); +} + +extern "C" int GetIPList(struct in_addr *addr, int max, int ipv4only) { + set ips; + db.GetIPs(ips, max, ipv4only); + int n = 0; + for (set::iterator it = ips.begin(); it != ips.end(); it++) { + if ((*it).GetInAddr(&addr[n])) + n++; + } + return n; +} + +extern "C" int dnsserver(void); + +extern "C" void* ThreadDNS(void*) { + dnsserver(); +} + +#define NTHREADS 100 + +int main(void) { + vector ips; + LookupHost("dnsseed.bluematt.me", ips); + for (vector::iterator it = ips.begin(); it != ips.end(); it++) { + db.Add(CIPPort(*it, 8333)); + } + pthread_t thread[NTHREADS]; + for (int i=0; i \ - void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const \ + void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const \ { \ CSerActionSerialize ser_action; \ const bool fGetSize = false; \ @@ -115,7 +113,7 @@ enum {statements} \ } \ template \ - void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) \ + void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) \ { \ CSerActionUnserialize ser_action; \ const bool fGetSize = false; \ @@ -362,43 +360,43 @@ template void Unserialize(Stream& is, std::basic_st // vector template unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::true_type&); template unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::false_type&); -template inline unsigned int GetSerializeSize(const std::vector& v, int nType, int nVersion=VERSION); +template inline unsigned int GetSerializeSize(const std::vector& v, int nType, int nVersion=PROTOCOL_VERSION); template void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::true_type&); template void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::false_type&); -template inline void Serialize(Stream& os, const std::vector& v, int nType, int nVersion=VERSION); +template inline void Serialize(Stream& os, const std::vector& v, int nType, int nVersion=PROTOCOL_VERSION); template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::true_type&); template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::false_type&); -template inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion=VERSION); +template inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion=PROTOCOL_VERSION); // others derived from vector -extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=VERSION); -template void Serialize(Stream& os, const CScript& v, int nType, int nVersion=VERSION); -template void Unserialize(Stream& is, CScript& v, int nType, int nVersion=VERSION); +extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=PROTOCOL_VERSION); +template void Serialize(Stream& os, const CScript& v, int nType, int nVersion=PROTOCOL_VERSION); +template void Unserialize(Stream& is, CScript& v, int nType, int nVersion=PROTOCOL_VERSION); // pair -template unsigned int GetSerializeSize(const std::pair& item, int nType, int nVersion=VERSION); -template void Serialize(Stream& os, const std::pair& item, int nType, int nVersion=VERSION); -template void Unserialize(Stream& is, std::pair& item, int nType, int nVersion=VERSION); +template unsigned int GetSerializeSize(const std::pair& item, int nType, int nVersion=PROTOCOL_VERSION); +template void Serialize(Stream& os, const std::pair& item, int nType, int nVersion=PROTOCOL_VERSION); +template void Unserialize(Stream& is, std::pair& item, int nType, int nVersion=PROTOCOL_VERSION); // 3 tuple -template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion=VERSION); -template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion=VERSION); -template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion=VERSION); +template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); +template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); +template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); // 4 tuple -template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion=VERSION); -template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion=VERSION); -template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion=VERSION); +template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); +template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); +template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); // map -template unsigned int GetSerializeSize(const std::map& m, int nType, int nVersion=VERSION); -template void Serialize(Stream& os, const std::map& m, int nType, int nVersion=VERSION); -template void Unserialize(Stream& is, std::map& m, int nType, int nVersion=VERSION); +template unsigned int GetSerializeSize(const std::map& m, int nType, int nVersion=PROTOCOL_VERSION); +template void Serialize(Stream& os, const std::map& m, int nType, int nVersion=PROTOCOL_VERSION); +template void Unserialize(Stream& is, std::map& m, int nType, int nVersion=PROTOCOL_VERSION); // set -template unsigned int GetSerializeSize(const std::set& m, int nType, int nVersion=VERSION); -template void Serialize(Stream& os, const std::set& m, int nType, int nVersion=VERSION); -template void Unserialize(Stream& is, std::set& m, int nType, int nVersion=VERSION); +template unsigned int GetSerializeSize(const std::set& m, int nType, int nVersion=PROTOCOL_VERSION); +template void Serialize(Stream& os, const std::set& m, int nType, int nVersion=PROTOCOL_VERSION); +template void Unserialize(Stream& is, std::set& m, int nType, int nVersion=PROTOCOL_VERSION); @@ -411,19 +409,19 @@ template void Unserializ // Thanks to Boost serialization for this idea. // template -inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=VERSION) +inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=PROTOCOL_VERSION) { return a.GetSerializeSize((int)nType, nVersion); } template -inline void Serialize(Stream& os, const T& a, long nType, int nVersion=VERSION) +inline void Serialize(Stream& os, const T& a, long nType, int nVersion=PROTOCOL_VERSION) { a.Serialize(os, (int)nType, nVersion); } template -inline void Unserialize(Stream& is, T& a, long nType, int nVersion=VERSION) +inline void Unserialize(Stream& is, T& a, long nType, int nVersion=PROTOCOL_VERSION) { a.Unserialize(is, (int)nType, nVersion); } @@ -857,39 +855,39 @@ public: typedef vector_type::const_iterator const_iterator; typedef vector_type::reverse_iterator reverse_iterator; - explicit CDataStream(int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) + explicit CDataStream(int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) { Init(nTypeIn, nVersionIn); } - CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(pbegin, pend) + CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(pbegin, pend) { Init(nTypeIn, nVersionIn); } #if !defined(_MSC_VER) || _MSC_VER >= 1300 - CDataStream(const char* pbegin, const char* pend, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(pbegin, pend) + CDataStream(const char* pbegin, const char* pend, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(pbegin, pend) { Init(nTypeIn, nVersionIn); } #endif - CDataStream(const vector_type& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end()) + CDataStream(const vector_type& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(vchIn.begin(), vchIn.end()) { Init(nTypeIn, nVersionIn); } - CDataStream(const std::vector& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end()) + CDataStream(const std::vector& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(vchIn.begin(), vchIn.end()) { Init(nTypeIn, nVersionIn); } - CDataStream(const std::vector& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]) + CDataStream(const std::vector& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]) { Init(nTypeIn, nVersionIn); } - void Init(int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) + void Init(int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) { nReadPos = 0; nType = nTypeIn; @@ -1103,7 +1101,7 @@ public: } template - void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const + void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const { // Special case: stream << stream concatenates like stream += stream if (!vch.empty()) @@ -1212,7 +1210,7 @@ public: typedef FILE element_type; - CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=VERSION) + CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=PROTOCOL_VERSION) { file = filenew; nType = nTypeIn; diff --git a/uint256.h b/uint256.h index 3e20201..b613282 100644 --- a/uint256.h +++ b/uint256.h @@ -364,19 +364,19 @@ public: } - unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const + unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const { return sizeof(pn); } template - void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const + void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const { s.write((char*)pn, sizeof(pn)); } template - void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) + void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) { s.read((char*)pn, sizeof(pn)); } diff --git a/util.h b/util.h index 633b85d..1a14d99 100644 --- a/util.h +++ b/util.h @@ -3,6 +3,9 @@ #include #include +#include + +#include "uint256.h" #define loop for (;;) #define BEGIN(a) ((char*)&(a)) @@ -64,4 +67,21 @@ public: #define CRITICAL_BLOCK(cs) \ if (CCriticalBlock criticalblock = CCriticalBlock(cs)) +template inline uint256 Hash(const T1 pbegin, const T1 pend) +{ + static unsigned char pblank[1]; + uint256 hash1; + SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + +void static inline Sleep(int nMilliSec) { + struct timespec wa; + wa.tv_sec = nMilliSec/1000; + wa.tv_nsec = (nMilliSec % 1000) * 1000000; + nanosleep(&wa, NULL); +} + #endif