diff --git a/src/Makefile.am b/src/Makefile.am --- a/src/Makefile.am +++ b/src/Makefile.am @@ -385,9 +385,7 @@ seeder/netbase.h \ seeder/protocol.cpp \ seeder/protocol.h \ - seeder/serialize.h \ seeder/strlcpy.h \ - seeder/uint256.h \ seeder/util.cpp \ seeder/util.h @@ -444,7 +442,9 @@ bitcoin_seeder_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) bitcoin_seeder_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -bitcoin_seeder_LDADD = $(LIBBITCOIN_SEEDER) +bitcoin_seeder_LDADD = \ + $(LIBBITCOIN_SEEDER) \ + $(LIBBITCOIN_UTIL) bitcoin_seeder_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) # diff --git a/src/seeder/bitcoin.cpp b/src/seeder/bitcoin.cpp --- a/src/seeder/bitcoin.cpp +++ b/src/seeder/bitcoin.cpp @@ -3,6 +3,7 @@ #include "db.h" #include "netbase.h" #include "serialize.h" +#include "streams.h" #include "uint256.h" #include @@ -166,7 +167,8 @@ CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart)); - int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader()); + int nHeaderSize = GetSerializeSize( + CMessageHeader(), vRecv.GetType(), vRecv.GetVersion()); if (vRecv.end() - pstart < nHeaderSize) { if (vRecv.size() > nHeaderSize) { vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize); @@ -204,7 +206,7 @@ if (nChecksum != hdr.nChecksum) continue; } CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, - vRecv.nType, vRecv.nVersion); + vRecv.GetType(), vRecv.GetVersion()); vRecv.ignore(nMessageSize); if (ProcessMessage(strCommand, vMsg)) return true; // printf("%s: done processing %s\n", ToString(you).c_str(), @@ -215,17 +217,15 @@ public: CNode(const CService &ip, std::vector *vAddrIn) - : you(ip), nHeaderStart(-1), nMessageStart(-1), vAddr(vAddrIn), ban(0), + : vSend(SER_NETWORK, 0), vRecv(SER_NETWORK, 0), you(ip), + nHeaderStart(-1), nMessageStart(-1), vAddr(vAddrIn), ban(0), doneAfter(0), nVersion(0) { - vSend.SetType(SER_NETWORK); - vSend.SetVersion(0); - vRecv.SetType(SER_NETWORK); - vRecv.SetVersion(0); if (time(nullptr) > 1329696000) { vSend.SetVersion(209); vRecv.SetVersion(209); } } + bool Run() { bool res = true; if (!ConnectSocket(you, sock)) return false; diff --git a/src/seeder/db.h b/src/seeder/db.h --- a/src/seeder/db.h +++ b/src/seeder/db.h @@ -5,6 +5,7 @@ #include "protocol.h" #include "sync.h" #include "util.h" +#include "version.h" #include #include @@ -44,8 +45,14 @@ weight = weight * f + (1.0 - f); } - IMPLEMENT_SERIALIZE(READWRITE(weight); READWRITE(count); - READWRITE(reliability);) + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream &s, Operation ser_action) { + READWRITE(weight); + READWRITE(count); + READWRITE(reliability); + } friend class CAddrInfo; }; @@ -165,27 +172,37 @@ friend class CAddrDb; - IMPLEMENT_SERIALIZE(uint8_t version = 4; READWRITE(version); READWRITE(ip); - READWRITE(services); READWRITE(lastTry); - uint8_t tried = ourLastTry != 0; READWRITE(tried); - if (tried) { - READWRITE(ourLastTry); - READWRITE(ignoreTill); - READWRITE(stat2H); - READWRITE(stat8H); - READWRITE(stat1D); - READWRITE(stat1W); - if (version >= 1) - READWRITE(stat1M); - else if (!fWrite) - *((CAddrStat *)(&stat1M)) = stat1W; - READWRITE(total); - READWRITE(success); - READWRITE(clientVersion); - if (version >= 2) READWRITE(clientSubVersion); - if (version >= 3) READWRITE(blocks); - if (version >= 4) READWRITE(ourLastSuccess); - }) + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream &s, Operation ser_action) { + uint8_t version = 4; + READWRITE(version); + READWRITE(ip); + READWRITE(services); + READWRITE(lastTry); + uint8_t tried = ourLastTry != 0; + READWRITE(tried); + if (tried) { + READWRITE(ourLastTry); + READWRITE(ignoreTill); + READWRITE(stat2H); + READWRITE(stat8H); + READWRITE(stat1D); + READWRITE(stat1W); + if (version >= 1) { + READWRITE(stat1M); + } else if (!ser_action.ForRead()) { + *((CAddrStat *)(&stat1M)) = stat1W; + } + READWRITE(total); + READWRITE(success); + READWRITE(clientVersion); + if (version >= 2) READWRITE(clientSubVersion); + if (version >= 3) READWRITE(blocks); + if (version >= 4) READWRITE(ourLastSuccess); + } + } }; class CAddrDbStats { @@ -299,53 +316,57 @@ // assume that only happens at startup, single-threaded) // this way, dumping does not interfere with GetIPs_, which is called from // the DNS thread - IMPLEMENT_SERIALIZE(({ - int nVersion = 0; - READWRITE(nVersion); - LOCK(cs); - if (fWrite) { - CAddrDb *db = const_cast(this); - int n = ourId.size() + unkId.size(); - READWRITE(n); - for (std::deque::const_iterator it = - ourId.begin(); - it != ourId.end(); it++) { - std::map::iterator ci = - db->idToInfo.find(*it); - READWRITE((*ci).second); - } - for (std::set::const_iterator it = - unkId.begin(); - it != unkId.end(); it++) { - std::map::iterator ci = - db->idToInfo.find(*it); - READWRITE((*ci).second); - } - } else { - CAddrDb *db = const_cast(this); - db->nId = 0; - int n; - READWRITE(n); - for (int i = 0; i < n; i++) { - CAddrInfo info; - READWRITE(info); - if (!info.GetBanTime()) { - int id = db->nId++; - db->idToInfo[id] = info; - db->ipToId[info.ip] = id; - if (info.ourLastTry) { - db->ourId.push_back(id); - if (info.IsGood()) - db->goodId.insert(id); - } else { - db->unkId.insert(id); - } - } - } - db->nDirty++; - } - READWRITE(banned); - });) + template void Serialize(Stream &s) const { + LOCK(cs); + + int nVersion = 0; + s << nVersion; + + CAddrDb *db = const_cast(this); + int n = ourId.size() + unkId.size(); + s << n; + for (std::deque::const_iterator it = ourId.begin(); + it != ourId.end(); it++) { + std::map::iterator ci = db->idToInfo.find(*it); + s << (*ci).second; + } + for (std::set::const_iterator it = unkId.begin(); + it != unkId.end(); it++) { + std::map::iterator ci = db->idToInfo.find(*it); + s << (*ci).second; + } + s << banned; + } + + template void Unserialize(Stream &s) { + LOCK(cs); + + int nVersion; + s >> nVersion; + + CAddrDb *db = const_cast(this); + db->nId = 0; + int n; + s >> n; + for (int i = 0; i < n; i++) { + CAddrInfo info; + s >> info; + if (!info.GetBanTime()) { + int id = db->nId++; + db->idToInfo[id] = info; + db->ipToId[info.ip] = id; + if (info.ourLastTry) { + db->ourId.push_back(id); + if (info.IsGood()) db->goodId.insert(id); + } else { + db->unkId.insert(id); + } + } + } + db->nDirty++; + + s >> banned; + } void Add(const CAddress &addr, bool fForce = false) { LOCK(cs); diff --git a/src/seeder/main.cpp b/src/seeder/main.cpp --- a/src/seeder/main.cpp +++ b/src/seeder/main.cpp @@ -1,5 +1,7 @@ #include "bitcoin.h" +#include "clientversion.h" #include "db.h" +#include "streams.h" #include #include @@ -360,7 +362,7 @@ FILE *f = fopen("dnsseed.dat.new", "w+"); if (f) { { - CAutoFile cf(f); + CAutoFile cf(f, SER_DISK, CLIENT_VERSION); cf << db; } rename("dnsseed.dat.new", "dnsseed.dat"); @@ -434,12 +436,9 @@ "seed.bitcoinabc.org", "seed-abc.bitcoinforks.org", "seed.bitprim.org", "seed.deadalnix.me", "seeder.criptolayer.net", ""}; static const std::string testnet_seeds[] = { - "testnet-seed.bitcoinabc.org", - "testnet-seed-abc.bitcoinforks.org", - "testnet-seed.bitprim.org", - "testnet-seed.deadalnix.me", - "testnet-seeder.criptolayer.net", - ""}; + "testnet-seed.bitcoinabc.org", "testnet-seed-abc.bitcoinforks.org", + "testnet-seed.bitprim.org", "testnet-seed.deadalnix.me", + "testnet-seeder.criptolayer.net", ""}; static const std::string *seeds = mainnet_seeds; extern "C" void *ThreadSeeder(void *) { @@ -521,7 +520,7 @@ FILE *f = fopen("dnsseed.dat", "r"); if (f) { printf("Loading dnsseed.dat..."); - CAutoFile cf(f); + CAutoFile cf(f, SER_DISK, CLIENT_VERSION); cf >> db; if (opts.fWipeBan) db.banned.clear(); if (opts.fWipeIgnore) db.ResetIgnores(); diff --git a/src/seeder/netbase.h b/src/seeder/netbase.h --- a/src/seeder/netbase.h +++ b/src/seeder/netbase.h @@ -81,7 +81,12 @@ friend bool operator!=(const CNetAddr &a, const CNetAddr &b); friend bool operator<(const CNetAddr &a, const CNetAddr &b); - IMPLEMENT_SERIALIZE(READWRITE(FLATDATA(ip));) + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream &s, Operation ser_action) { + READWRITE(FLATDATA(ip)); + } }; /** A combination of a network address (CNetAddr) and a (TCP) port */ @@ -117,10 +122,18 @@ CService(const struct in6_addr &ipv6Addr, unsigned short port); CService(const struct sockaddr_in6 &addr); - IMPLEMENT_SERIALIZE(CService *pthis = const_cast(this); - READWRITE(FLATDATA(ip)); - unsigned short portN = htons(port); READWRITE(portN); - if (fRead) pthis->port = ntohs(portN);) + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream &s, Operation ser_action) { + CService *pthis = const_cast(this); + READWRITE(FLATDATA(ip)); + unsigned short portN = htons(port); + READWRITE(portN); + if (ser_action.ForRead()) { + pthis->port = ntohs(portN); + } + } }; enum Network ParseNetwork(std::string net); diff --git a/src/seeder/protocol.h b/src/seeder/protocol.h --- a/src/seeder/protocol.h +++ b/src/seeder/protocol.h @@ -39,10 +39,17 @@ std::string GetCommand() const; bool IsValid() const; - IMPLEMENT_SERIALIZE(READWRITE(FLATDATA(pchMessageStart)); - READWRITE(FLATDATA(pchCommand)); - READWRITE(nMessageSize); - if (nVersion >= 209) READWRITE(nChecksum);) + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream &s, Operation ser_action) { + READWRITE(FLATDATA(pchMessageStart)); + READWRITE(FLATDATA(pchCommand)); + READWRITE(nMessageSize); + if (s.GetVersion() >= 209) { + READWRITE(nChecksum); + } + } // TODO: make private (improves encapsulation) public: @@ -68,14 +75,26 @@ void Init(); - IMPLEMENT_SERIALIZE(CAddress *pthis = const_cast(this); - CService *pip = (CService *)pthis; - if (fRead) pthis->Init(); - if (nType & SER_DISK) READWRITE(nVersion); - if ((nType & SER_DISK) || - (nVersion >= 31402 && !(nType & SER_GETHASH))) - READWRITE(nTime); - READWRITE(nServices); READWRITE(*pip);) + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream &s, Operation ser_action) { + int nVersion = s.GetVersion(); + CAddress *pthis = const_cast(this); + CService *pip = (CService *)pthis; + if (ser_action.ForRead()) { + pthis->Init(); + } + if (s.GetType() & SER_DISK) { + READWRITE(nVersion); + } + if ((s.GetType() & SER_DISK) || + (nVersion >= 31402 && !(s.GetType() & SER_GETHASH))) { + READWRITE(nTime); + } + READWRITE(nServices); + READWRITE(*pip); + } void print() const; @@ -93,7 +112,13 @@ CInv(int typeIn, const uint256 &hashIn); CInv(const std::string &strType, const uint256 &hashIn); - IMPLEMENT_SERIALIZE(READWRITE(type); READWRITE(hash);) + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream &s, Operation ser_action) { + READWRITE(type); + READWRITE(hash); + } friend bool operator<(const CInv &a, const CInv &b); diff --git a/src/seeder/protocol.cpp b/src/seeder/protocol.cpp --- a/src/seeder/protocol.cpp +++ b/src/seeder/protocol.cpp @@ -90,7 +90,7 @@ CInv::CInv() { type = 0; - hash = 0; + hash.SetNull(); } CInv::CInv(int typeIn, const uint256 &hashIn) { diff --git a/src/seeder/serialize.h b/src/seeder/serialize.h deleted file mode 100644 --- a/src/seeder/serialize.h +++ /dev/null @@ -1,1320 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2011 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_SEEDER_SERIALIZE_H -#define BITCOIN_SEEDER_SERIALIZE_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if defined(_MSC_VER) && _MSC_VER < 1300 -#define for if (false); else for -#endif - -#ifdef WIN32 -#include -// This is used to attempt to keep keying material out of swap -// Note that VirtualLock does not provide this as a guarantee on Windows, -// but, in practice, memory that has been VirtualLock'd almost never gets -// written to -// the pagefile except in rare circumstances where memory is extremely low. -#include -#define mlock(p, n) VirtualLock((p), (n)); -#define munlock(p, n) VirtualUnlock((p), (n)); -#else -#include -#include -/* This comes from limits.h if it's not defined there set a sane default */ -#ifndef PAGESIZE -#include -#define PAGESIZE sysconf(_SC_PAGESIZE) -#endif -#define mlock(a, b) \ - mlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))), \ - (((((size_t)(a)) + (b)-1) | ((PAGESIZE)-1)) + 1) - \ - (((size_t)(a)) & (~((PAGESIZE)-1)))) -#define munlock(a, b) \ - munlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))), \ - (((((size_t)(a)) + (b)-1) | ((PAGESIZE)-1)) + 1) - \ - (((size_t)(a)) & (~((PAGESIZE)-1)))) -#endif - -class CScript; -class CDataStream; -class CAutoFile; -static const unsigned int MAX_SIZE = 0x02000000; - -static const int PROTOCOL_VERSION = 60000; - -// Used to bypass the rule against non-const reference to temporary -// where it makes sense with wrappers such as CFlatData or CTxDB -template inline T &REF(const T &val) { - return const_cast(val); -} - -///////////////////////////////////////////////////////////////// -// -// Templates for serializing to anything that looks like a stream, -// i.e. anything that supports .read(char*, int) and .write(char*, int) -// - -enum { - // primary actions - SER_NETWORK = (1 << 0), - SER_DISK = (1 << 1), - SER_GETHASH = (1 << 2), - - // modifiers - SER_SKIPSIG = (1 << 16), - SER_BLOCKHEADERONLY = (1 << 17), -}; - -#define IMPLEMENT_SERIALIZE(statements) \ - unsigned int GetSerializeSize(int nType = 0, \ - int nVersion = PROTOCOL_VERSION) const { \ - CSerActionGetSerializeSize ser_action; \ - const bool fGetSize = true; \ - const bool fWrite = false; \ - const bool fRead = false; \ - unsigned int nSerSize = 0; \ - ser_streamplaceholder s; \ - s.nType = nType; \ - s.nVersion = nVersion; \ - { statements } \ - return nSerSize; \ - } \ - template \ - void Serialize(Stream &s, int nType = 0, int nVersion = PROTOCOL_VERSION) \ - const { \ - CSerActionSerialize ser_action; \ - const bool fGetSize = false; \ - const bool fWrite = true; \ - const bool fRead = false; \ - unsigned int nSerSize = 0; \ - { statements } \ - } \ - template \ - void Unserialize(Stream &s, int nType = 0, \ - int nVersion = PROTOCOL_VERSION) { \ - CSerActionUnserialize ser_action; \ - const bool fGetSize = false; \ - const bool fWrite = false; \ - const bool fRead = true; \ - unsigned int nSerSize = 0; \ - { statements } \ - } - -#define READWRITE(obj) \ - (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action)) - -// -// Basic types -// -#define WRITEDATA(s, obj) s.write((char *)&(obj), sizeof(obj)) -#define READDATA(s, obj) s.read((char *)&(obj), sizeof(obj)) - -inline unsigned int GetSerializeSize(int8_t a, int, int = 0) { - return sizeof(a); -} -inline unsigned int GetSerializeSize(uint8_t a, int, int = 0) { - return sizeof(a); -} -inline unsigned int GetSerializeSize(int16_t a, int, int = 0) { - return sizeof(a); -} -inline unsigned int GetSerializeSize(uint16_t a, int, int = 0) { - return sizeof(a); -} -inline unsigned int GetSerializeSize(int32_t a, int, int = 0) { - return sizeof(a); -} -inline unsigned int GetSerializeSize(uint32_t a, int, int = 0) { - return sizeof(a); -} -inline unsigned int GetSerializeSize(int64_t a, int, int = 0) { - return sizeof(a); -} -inline unsigned int GetSerializeSize(uint64_t a, int, int = 0) { - return sizeof(a); -} -inline unsigned int GetSerializeSize(float a, int, int = 0) { - return sizeof(a); -} -inline unsigned int GetSerializeSize(double a, int, int = 0) { - return sizeof(a); -} - -template -inline void Serialize(Stream &s, int8_t a, int, int = 0) { - WRITEDATA(s, a); -} -template -inline void Serialize(Stream &s, uint8_t a, int, int = 0) { - WRITEDATA(s, a); -} -template -inline void Serialize(Stream &s, int16_t a, int, int = 0) { - WRITEDATA(s, a); -} -template -inline void Serialize(Stream &s, uint16_t a, int, int = 0) { - WRITEDATA(s, a); -} -template -inline void Serialize(Stream &s, int32_t a, int, int = 0) { - WRITEDATA(s, a); -} -template -inline void Serialize(Stream &s, uint32_t a, int, int = 0) { - WRITEDATA(s, a); -} -template -inline void Serialize(Stream &s, int64_t a, int, int = 0) { - WRITEDATA(s, a); -} -template -inline void Serialize(Stream &s, uint64_t a, int, int = 0) { - WRITEDATA(s, a); -} -template -inline void Serialize(Stream &s, float a, int, int = 0) { - WRITEDATA(s, a); -} -template -inline void Serialize(Stream &s, double a, int, int = 0) { - WRITEDATA(s, a); -} - -template -inline void Unserialize(Stream &s, int8_t &a, int, int = 0) { - READDATA(s, a); -} -template -inline void Unserialize(Stream &s, uint8_t &a, int, int = 0) { - READDATA(s, a); -} -template -inline void Unserialize(Stream &s, int16_t &a, int, int = 0) { - READDATA(s, a); -} -template -inline void Unserialize(Stream &s, uint16_t &a, int, int = 0) { - READDATA(s, a); -} -template -inline void Unserialize(Stream &s, int32_t &a, int, int = 0) { - READDATA(s, a); -} -template -inline void Unserialize(Stream &s, uint32_t &a, int, int = 0) { - READDATA(s, a); -} -template -inline void Unserialize(Stream &s, int64_t &a, int, int = 0) { - READDATA(s, a); -} -template -inline void Unserialize(Stream &s, uint64_t &a, int, int = 0) { - READDATA(s, a); -} -template -inline void Unserialize(Stream &s, float &a, int, int = 0) { - READDATA(s, a); -} -template -inline void Unserialize(Stream &s, double &a, int, int = 0) { - READDATA(s, a); -} - -inline unsigned int GetSerializeSize(bool a, int, int = 0) { - return sizeof(char); -} -template -inline void Serialize(Stream &s, bool a, int, int = 0) { - char f = a; - WRITEDATA(s, f); -} -template -inline void Unserialize(Stream &s, bool &a, int, int = 0) { - char f; - READDATA(s, f); - a = f; -} - -// -// Compact size -// size < 253 -- 1 byte -// size <= USHRT_MAX -- 3 bytes (253 + 2 bytes) -// size <= UINT_MAX -- 5 bytes (254 + 4 bytes) -// size > UINT_MAX -- 9 bytes (255 + 8 bytes) -// -inline unsigned int GetSizeOfCompactSize(uint64_t nSize) { - if (nSize < 253) - return sizeof(uint8_t); - else if (nSize <= USHRT_MAX) - return sizeof(uint8_t) + sizeof(uint16_t); - else if (nSize <= UINT_MAX) - return sizeof(uint8_t) + sizeof(uint32_t); - else - return sizeof(uint8_t) + sizeof(uint64_t); -} - -template void WriteCompactSize(Stream &os, uint64_t nSize) { - if (nSize < 253) { - uint8_t chSize = nSize; - WRITEDATA(os, chSize); - } else if (nSize <= USHRT_MAX) { - uint8_t chSize = 253; - uint16_t xSize = nSize; - WRITEDATA(os, chSize); - WRITEDATA(os, xSize); - } else if (nSize <= UINT_MAX) { - uint8_t chSize = 254; - uint32_t xSize = nSize; - WRITEDATA(os, chSize); - WRITEDATA(os, xSize); - } else { - uint8_t chSize = 255; - uint64_t xSize = nSize; - WRITEDATA(os, chSize); - WRITEDATA(os, xSize); - } - return; -} - -template uint64_t ReadCompactSize(Stream &is) { - uint8_t chSize; - READDATA(is, chSize); - uint64_t nSizeRet = 0; - if (chSize < 253) { - nSizeRet = chSize; - } else if (chSize == 253) { - uint16_t xSize; - READDATA(is, xSize); - nSizeRet = xSize; - } else if (chSize == 254) { - uint32_t xSize; - READDATA(is, xSize); - nSizeRet = xSize; - } else { - uint64_t xSize; - READDATA(is, xSize); - nSizeRet = xSize; - } - if (nSizeRet > uint64_t(MAX_SIZE)) { - throw std::ios_base::failure("ReadCompactSize() : size too large"); - } - return nSizeRet; -} - -// -// Wrapper for serializing arrays and POD -// There's a clever template way to make arrays serialize normally, but MSVC6 -// doesn't support it -// -#define FLATDATA(obj) \ - REF(CFlatData((char *)&(obj), (char *)&(obj) + sizeof(obj))) -class CFlatData { -protected: - char *pbegin; - char *pend; - -public: - CFlatData(void *pbeginIn, void *pendIn) - : pbegin((char *)pbeginIn), pend((char *)pendIn) {} - char *begin() { return pbegin; } - const char *begin() const { return pbegin; } - char *end() { return pend; } - const char *end() const { return pend; } - - unsigned int GetSerializeSize(int, int = 0) const { return pend - pbegin; } - - template void Serialize(Stream &s, int, int = 0) const { - s.write(pbegin, pend - pbegin); - } - - template void Unserialize(Stream &s, int, int = 0) { - s.read(pbegin, pend - pbegin); - } -}; - -// -// string stored as a fixed length field -// -template class CFixedFieldString { -protected: - const std::string *pcstr; - std::string *pstr; - -public: - explicit CFixedFieldString(const std::string &str) - : pcstr(&str), pstr(nullptr) {} - explicit CFixedFieldString(std::string &str) : pcstr(&str), pstr(&str) {} - - unsigned int GetSerializeSize(int, int = 0) const { return LEN; } - - template void Serialize(Stream &s, int, int = 0) const { - char pszBuf[LEN]; - strncpy(pszBuf, pcstr->c_str(), LEN); - s.write(pszBuf, LEN); - } - - template void Unserialize(Stream &s, int, int = 0) { - if (pstr == nullptr) - throw std::ios_base::failure("CFixedFieldString::Unserialize : " - "trying to unserialize to const " - "string"); - char pszBuf[LEN + 1]; - s.read(pszBuf, LEN); - pszBuf[LEN] = '\0'; - *pstr = pszBuf; - } -}; - -// -// Forward declarations -// - -// string -template -unsigned int GetSerializeSize(const std::basic_string &str, int, int = 0); -template -void Serialize(Stream &os, const std::basic_string &str, int, int = 0); -template -void Unserialize(Stream &is, std::basic_string &str, int, int = 0); - -// 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 = 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 = 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 = PROTOCOL_VERSION); - -// others derived from vector -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 = 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 = 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 = 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 = 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 = 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); - -// -// If none of the specialized versions above matched, default to calling member -// function. -// "int nType" is changed to "long nType" to keep from getting an ambiguous -// overload error. -// The compiler will only cast int to long if none of the other templates -// matched. -// Thanks to Boost serialization for this idea. -// -template -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 = PROTOCOL_VERSION) { - a.Serialize(os, (int)nType, nVersion); -} - -template -inline void Unserialize(Stream &is, T &a, long nType, - int nVersion = PROTOCOL_VERSION) { - a.Unserialize(is, (int)nType, nVersion); -} - -// -// string -// -template -unsigned int GetSerializeSize(const std::basic_string &str, int, int) { - return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]); -} - -template -void Serialize(Stream &os, const std::basic_string &str, int, int) { - WriteCompactSize(os, str.size()); - if (!str.empty()) os.write((char *)&str[0], str.size() * sizeof(str[0])); -} - -template -void Unserialize(Stream &is, std::basic_string &str, int, int) { - unsigned int nSize = ReadCompactSize(is); - str.resize(nSize); - if (nSize != 0) is.read((char *)&str[0], nSize * sizeof(str[0])); -} - -// -// vector -// -template -unsigned int GetSerializeSize_impl(const std::vector &v, int nType, - int nVersion, const boost::true_type &) { - return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T)); -} - -template -unsigned int GetSerializeSize_impl(const std::vector &v, int nType, - int nVersion, const boost::false_type &) { - unsigned int nSize = GetSizeOfCompactSize(v.size()); - for (typename std::vector::const_iterator vi = v.begin(); - vi != v.end(); ++vi) - nSize += GetSerializeSize((*vi), nType, nVersion); - return nSize; -} - -template -inline unsigned int GetSerializeSize(const std::vector &v, int nType, - int nVersion) { - return GetSerializeSize_impl(v, nType, nVersion, - boost::is_fundamental()); -} - -template -void Serialize_impl(Stream &os, const std::vector &v, int nType, - int nVersion, const boost::true_type &) { - WriteCompactSize(os, v.size()); - if (!v.empty()) os.write((char *)&v[0], v.size() * sizeof(T)); -} - -template -void Serialize_impl(Stream &os, const std::vector &v, int nType, - int nVersion, const boost::false_type &) { - WriteCompactSize(os, v.size()); - for (typename std::vector::const_iterator vi = v.begin(); - vi != v.end(); ++vi) - ::Serialize(os, (*vi), nType, nVersion); -} - -template -inline void Serialize(Stream &os, const std::vector &v, int nType, - int nVersion) { - Serialize_impl(os, v, nType, nVersion, boost::is_fundamental()); -} - -template -void Unserialize_impl(Stream &is, std::vector &v, int nType, int nVersion, - const boost::true_type &) { - // unsigned int nSize = ReadCompactSize(is); - // v.resize(nSize); - // is.read((char*)&v[0], nSize * sizeof(T)); - - // Limit size per read so bogus size value won't cause out of memory - v.clear(); - unsigned int nSize = ReadCompactSize(is); - unsigned int i = 0; - while (i < nSize) { - unsigned int blk = - std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); - v.resize(i + blk); - is.read((char *)&v[i], blk * sizeof(T)); - i += blk; - } -} - -template -void Unserialize_impl(Stream &is, std::vector &v, int nType, int nVersion, - const boost::false_type &) { - // unsigned int nSize = ReadCompactSize(is); - // v.resize(nSize); - // for (std::vector::iterator vi = v.begin(); vi != v.end(); ++vi) - // Unserialize(is, (*vi), nType, nVersion); - - v.clear(); - unsigned int nSize = ReadCompactSize(is); - unsigned int i = 0; - unsigned int nMid = 0; - while (nMid < nSize) { - nMid += 5000000 / sizeof(T); - if (nMid > nSize) nMid = nSize; - v.resize(nMid); - for (; i < nMid; i++) - Unserialize(is, v[i], nType, nVersion); - } -} - -template -inline void Unserialize(Stream &is, std::vector &v, int nType, - int nVersion) { - Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental()); -} - -// -// others derived from vector -// -inline unsigned int GetSerializeSize(const CScript &v, int nType, - int nVersion) { - return GetSerializeSize((const std::vector &)v, nType, nVersion); -} - -template -void Serialize(Stream &os, const CScript &v, int nType, int nVersion) { - Serialize(os, (const std::vector &)v, nType, nVersion); -} - -template -void Unserialize(Stream &is, CScript &v, int nType, int nVersion) { - Unserialize(is, (std::vector &)v, nType, nVersion); -} - -// -// pair -// -template -unsigned int GetSerializeSize(const std::pair &item, int nType, - int nVersion) { - return GetSerializeSize(item.first, nType, nVersion) + - GetSerializeSize(item.second, nType, nVersion); -} - -template -void Serialize(Stream &os, const std::pair &item, int nType, - int nVersion) { - Serialize(os, item.first, nType, nVersion); - Serialize(os, item.second, nType, nVersion); -} - -template -void Unserialize(Stream &is, std::pair &item, int nType, int nVersion) { - Unserialize(is, item.first, nType, nVersion); - Unserialize(is, item.second, nType, nVersion); -} - -// -// 3 tuple -// -template -unsigned int GetSerializeSize(const boost::tuple &item, int nType, - int nVersion) { - unsigned int nSize = 0; - nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion); - nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion); - nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion); - return nSize; -} - -template -void Serialize(Stream &os, const boost::tuple &item, int nType, - int nVersion) { - Serialize(os, boost::get<0>(item), nType, nVersion); - Serialize(os, boost::get<1>(item), nType, nVersion); - Serialize(os, boost::get<2>(item), nType, nVersion); -} - -template -void Unserialize(Stream &is, boost::tuple &item, int nType, - int nVersion) { - Unserialize(is, boost::get<0>(item), nType, nVersion); - Unserialize(is, boost::get<1>(item), nType, nVersion); - Unserialize(is, boost::get<2>(item), nType, nVersion); -} - -// -// 4 tuple -// -template -unsigned int GetSerializeSize(const boost::tuple &item, - int nType, int nVersion) { - unsigned int nSize = 0; - nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion); - nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion); - nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion); - nSize += GetSerializeSize(boost::get<3>(item), nType, nVersion); - return nSize; -} - -template -void Serialize(Stream &os, const boost::tuple &item, int nType, - int nVersion) { - Serialize(os, boost::get<0>(item), nType, nVersion); - Serialize(os, boost::get<1>(item), nType, nVersion); - Serialize(os, boost::get<2>(item), nType, nVersion); - Serialize(os, boost::get<3>(item), nType, nVersion); -} - -template -void Unserialize(Stream &is, boost::tuple &item, int nType, - int nVersion) { - Unserialize(is, boost::get<0>(item), nType, nVersion); - Unserialize(is, boost::get<1>(item), nType, nVersion); - Unserialize(is, boost::get<2>(item), nType, nVersion); - Unserialize(is, boost::get<3>(item), nType, nVersion); -} - -// -// map -// -template -unsigned int GetSerializeSize(const std::map &m, int nType, - int nVersion) { - unsigned int nSize = GetSizeOfCompactSize(m.size()); - for (typename std::map::const_iterator mi = m.begin(); - mi != m.end(); ++mi) - nSize += GetSerializeSize((*mi), nType, nVersion); - return nSize; -} - -template -void Serialize(Stream &os, const std::map &m, int nType, - int nVersion) { - WriteCompactSize(os, m.size()); - for (typename std::map::const_iterator mi = m.begin(); - mi != m.end(); ++mi) - Serialize(os, (*mi), nType, nVersion); -} - -template -void Unserialize(Stream &is, std::map &m, int nType, - int nVersion) { - m.clear(); - unsigned int nSize = ReadCompactSize(is); - typename std::map::iterator mi = m.begin(); - for (unsigned int i = 0; i < nSize; i++) { - std::pair item; - Unserialize(is, item, nType, nVersion); - mi = m.insert(mi, item); - } -} - -// -// set -// -template -unsigned int GetSerializeSize(const std::set &m, int nType, - int nVersion) { - unsigned int nSize = GetSizeOfCompactSize(m.size()); - for (typename std::set::const_iterator it = m.begin(); - it != m.end(); ++it) - nSize += GetSerializeSize((*it), nType, nVersion); - return nSize; -} - -template -void Serialize(Stream &os, const std::set &m, int nType, - int nVersion) { - WriteCompactSize(os, m.size()); - for (typename std::set::const_iterator it = m.begin(); - it != m.end(); ++it) - Serialize(os, (*it), nType, nVersion); -} - -template -void Unserialize(Stream &is, std::set &m, int nType, int nVersion) { - m.clear(); - unsigned int nSize = ReadCompactSize(is); - typename std::set::iterator it = m.begin(); - for (unsigned int i = 0; i < nSize; i++) { - K key; - Unserialize(is, key, nType, nVersion); - it = m.insert(it, key); - } -} - -// -// Support for IMPLEMENT_SERIALIZE and READWRITE macro -// -class CSerActionGetSerializeSize {}; -class CSerActionSerialize {}; -class CSerActionUnserialize {}; - -template -inline unsigned int SerReadWrite(Stream &s, const T &obj, int nType, - int nVersion, - CSerActionGetSerializeSize ser_action) { - return ::GetSerializeSize(obj, nType, nVersion); -} - -template -inline unsigned int SerReadWrite(Stream &s, const T &obj, int nType, - int nVersion, CSerActionSerialize ser_action) { - ::Serialize(s, obj, nType, nVersion); - return 0; -} - -template -inline unsigned int SerReadWrite(Stream &s, T &obj, int nType, int nVersion, - CSerActionUnserialize ser_action) { - ::Unserialize(s, obj, nType, nVersion); - return 0; -} - -struct ser_streamplaceholder { - int nType; - int nVersion; -}; - -// -// Allocator that locks its contents from being paged -// out of memory and clears its contents before deletion. -// -template struct secure_allocator : public std::allocator { - // MSVC8 default copy constructor is broken - typedef std::allocator base; - typedef typename base::size_type size_type; - typedef typename base::difference_type difference_type; - typedef typename base::pointer pointer; - typedef typename base::const_pointer const_pointer; - typedef typename base::reference reference; - typedef typename base::const_reference const_reference; - typedef typename base::value_type value_type; - secure_allocator() throw() {} - secure_allocator(const secure_allocator &a) throw() : base(a) {} - template - secure_allocator(const secure_allocator &a) throw() : base(a) {} - ~secure_allocator() throw() {} - template struct rebind { - typedef secure_allocator<_Other> other; - }; - - T *allocate(std::size_t n, const void *hint = 0) { - T *p; - p = std::allocator::allocate(n, hint); - if (p != nullptr) mlock(p, sizeof(T) * n); - return p; - } - - void deallocate(T *p, std::size_t n) { - if (p != nullptr) { - memset(p, 0, sizeof(T) * n); - munlock(p, sizeof(T) * n); - } - std::allocator::deallocate(p, n); - } -}; - -// -// Double ended buffer combining vector and stream-like interfaces. -// >> and << read and write unformatted data using the above serialization -// templates. -// Fills with data in linear time; some stringstream implementations take N^2 -// time. -// -class CDataStream { -protected: - typedef std::vector> vector_type; - vector_type vch; - unsigned int nReadPos; - short state; - short exceptmask; - -public: - int nType; - int nVersion; - - typedef vector_type::allocator_type allocator_type; - typedef vector_type::size_type size_type; - typedef vector_type::difference_type difference_type; - typedef vector_type::reference reference; - typedef vector_type::const_reference const_reference; - typedef vector_type::value_type value_type; - typedef vector_type::iterator iterator; - typedef vector_type::const_iterator const_iterator; - typedef vector_type::reverse_iterator reverse_iterator; - - 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 = 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 = PROTOCOL_VERSION) - : vch(pbegin, pend) { - Init(nTypeIn, nVersionIn); - } -#endif - - 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 = PROTOCOL_VERSION) - : vch(vchIn.begin(), vchIn.end()) { - Init(nTypeIn, nVersionIn); - } - - 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 = PROTOCOL_VERSION) { - nReadPos = 0; - nType = nTypeIn; - nVersion = nVersionIn; - state = 0; - exceptmask = std::ios::badbit | std::ios::failbit; - } - - CDataStream &operator+=(const CDataStream &b) { - vch.insert(vch.end(), b.begin(), b.end()); - return *this; - } - - friend CDataStream operator+(const CDataStream &a, const CDataStream &b) { - CDataStream ret = a; - ret += b; - return (ret); - } - - std::string str() const { return (std::string(begin(), end())); } - - // - // Vector subset - // - const_iterator begin() const { return vch.begin() + nReadPos; } - iterator begin() { return vch.begin() + nReadPos; } - const_iterator end() const { return vch.end(); } - iterator end() { return vch.end(); } - size_type size() const { return vch.size() - nReadPos; } - bool empty() const { return vch.size() == nReadPos; } - void resize(size_type n, value_type c = 0) { vch.resize(n + nReadPos, c); } - void reserve(size_type n) { vch.reserve(n + nReadPos); } - const_reference operator[](size_type pos) const { - return vch[pos + nReadPos]; - } - reference operator[](size_type pos) { return vch[pos + nReadPos]; } - void clear() { - vch.clear(); - nReadPos = 0; - } - iterator insert(iterator it, const char &x = char()) { - return vch.insert(it, x); - } - void insert(iterator it, size_type n, const char &x) { - vch.insert(it, n, x); - } - - void insert(iterator it, std::vector::const_iterator first, - std::vector::const_iterator last) { - if (it == vch.begin() + nReadPos && last - first <= nReadPos) { - // special case for inserting at the front when there's room - nReadPos -= (last - first); - memcpy(&vch[nReadPos], &first[0], last - first); - } else - vch.insert(it, first, last); - } - -#if !defined(_MSC_VER) || _MSC_VER >= 1300 - void insert(iterator it, const char *first, const char *last) { - if (it == vch.begin() + nReadPos && last - first <= nReadPos) { - // special case for inserting at the front when there's room - nReadPos -= (last - first); - memcpy(&vch[nReadPos], &first[0], last - first); - } else - vch.insert(it, first, last); - } -#endif - - iterator erase(iterator it) { - if (it == vch.begin() + nReadPos) { - // special case for erasing from the front - if (++nReadPos >= vch.size()) { - // whenever we reach the end, we take the opportunity to clear - // the buffer - nReadPos = 0; - return vch.erase(vch.begin(), vch.end()); - } - return vch.begin() + nReadPos; - } else - return vch.erase(it); - } - - iterator erase(iterator first, iterator last) { - if (first == vch.begin() + nReadPos) { - // special case for erasing from the front - if (last == vch.end()) { - nReadPos = 0; - return vch.erase(vch.begin(), vch.end()); - } else { - nReadPos = (last - vch.begin()); - return last; - } - } else - return vch.erase(first, last); - } - - inline void Compact() { - vch.erase(vch.begin(), vch.begin() + nReadPos); - nReadPos = 0; - } - - bool Rewind(size_type n) { - // Rewind by n characters if the buffer hasn't been compacted yet - if (n > nReadPos) return false; - nReadPos -= n; - return true; - } - - // - // Stream subset - // - void setstate(short bits, const char *psz) { - state |= bits; - if (state & exceptmask) throw std::ios_base::failure(psz); - } - - bool eof() const { return size() == 0; } - bool fail() const { return state & (std::ios::badbit | std::ios::failbit); } - bool good() const { return !eof() && (state == 0); } - void clear(short n) { state = n; } // name conflict with vector clear() - short exceptions() { return exceptmask; } - short exceptions(short mask) { - short prev = exceptmask; - exceptmask = mask; - setstate(0, "CDataStream"); - return prev; - } - CDataStream *rdbuf() { return this; } - int in_avail() { return size(); } - - void SetType(int n) { nType = n; } - int GetType() { return nType; } - void SetVersion(int n) { nVersion = n; } - int GetVersion() { return nVersion; } - void ReadVersion() { *this >> nVersion; } - void WriteVersion() { *this << nVersion; } - - CDataStream &read(char *pch, int nSize) { - // Read from the beginning of the buffer - assert(nSize >= 0); - unsigned int nReadPosNext = nReadPos + nSize; - if (nReadPosNext >= vch.size()) { - if (nReadPosNext > vch.size()) { - setstate(std::ios::failbit, - "CDataStream::read() : end of data"); - memset(pch, 0, nSize); - nSize = vch.size() - nReadPos; - } - memcpy(pch, &vch[nReadPos], nSize); - nReadPos = 0; - vch.clear(); - return (*this); - } - memcpy(pch, &vch[nReadPos], nSize); - nReadPos = nReadPosNext; - return (*this); - } - - CDataStream &ignore(int nSize) { - // Ignore from the beginning of the buffer - assert(nSize >= 0); - unsigned int nReadPosNext = nReadPos + nSize; - if (nReadPosNext >= vch.size()) { - if (nReadPosNext > vch.size()) { - setstate(std::ios::failbit, - "CDataStream::ignore() : end of data"); - nSize = vch.size() - nReadPos; - } - nReadPos = 0; - vch.clear(); - return (*this); - } - nReadPos = nReadPosNext; - return (*this); - } - - CDataStream &write(const char *pch, int nSize) { - // Write to the end of the buffer - assert(nSize >= 0); - vch.insert(vch.end(), pch, pch + nSize); - return (*this); - } - - template - void Serialize(Stream &s, int nType = 0, - int nVersion = PROTOCOL_VERSION) const { - // Special case: stream << stream concatenates like stream += stream - if (!vch.empty()) s.write((char *)&vch[0], vch.size() * sizeof(vch[0])); - } - - template unsigned int GetSerializeSize(const T &obj) { - // Tells the size of the object if serialized to this stream - return ::GetSerializeSize(obj, nType, nVersion); - } - - template CDataStream &operator<<(const T &obj) { - // Serialize to this stream - ::Serialize(*this, obj, nType, nVersion); - return (*this); - } - - template CDataStream &operator>>(T &obj) { - // Unserialize from this stream - ::Unserialize(*this, obj, nType, nVersion); - return (*this); - } -}; - -#ifdef TESTCDATASTREAM -// VC6sp6 -// CDataStream: -// n=1000 0 seconds -// n=2000 0 seconds -// n=4000 0 seconds -// n=8000 0 seconds -// n=16000 0 seconds -// n=32000 0 seconds -// n=64000 1 seconds -// n=128000 1 seconds -// n=256000 2 seconds -// n=512000 4 seconds -// n=1024000 8 seconds -// n=2048000 16 seconds -// n=4096000 32 seconds -// stringstream: -// n=1000 1 seconds -// n=2000 1 seconds -// n=4000 13 seconds -// n=8000 87 seconds -// n=16000 400 seconds -// n=32000 1660 seconds -// n=64000 6749 seconds -// n=128000 27241 seconds -// n=256000 109804 seconds -#include -int main(int argc, char *argv[]) { - vector vch(0xcc, 250); - printf("CDataStream:\n"); - for (int n = 1000; n <= 4500000; n *= 2) { - CDataStream ss; - time_t nStart = time(nullptr); - for (int i = 0; i < n; i++) - ss.write((char *)&vch[0], vch.size()); - printf("n=%-10d %d seconds\n", n, time(nullptr) - nStart); - } - printf("stringstream:\n"); - for (int n = 1000; n <= 4500000; n *= 2) { - stringstream ss; - time_t nStart = time(nullptr); - for (int i = 0; i < n; i++) - ss.write((char *)&vch[0], vch.size()); - printf("n=%-10d %d seconds\n", n, time(nullptr) - nStart); - } -} -#endif - -// -// Automatic closing wrapper for FILE* -// - Will automatically close the file when it goes out of scope if not null. -// - If you're returning the file pointer, return file.release(). -// - If you need to close the file early, use file.fclose() instead of -// fclose(file). -// -class CAutoFile { -protected: - FILE *file; - short state; - short exceptmask; - -public: - int nType; - int nVersion; - - typedef FILE element_type; - - CAutoFile(FILE *filenew = nullptr, int nTypeIn = SER_DISK, - int nVersionIn = PROTOCOL_VERSION) { - file = filenew; - nType = nTypeIn; - nVersion = nVersionIn; - state = 0; - exceptmask = std::ios::badbit | std::ios::failbit; - } - - ~CAutoFile() { fclose(); } - - void fclose() { - if (file != nullptr && file != stdin && file != stdout && - file != stderr) - ::fclose(file); - file = nullptr; - } - - FILE *release() { - FILE *ret = file; - file = nullptr; - return ret; - } - operator FILE *() { return file; } - FILE *operator->() { return file; } - FILE &operator*() { return *file; } - FILE **operator&() { return &file; } - FILE *operator=(FILE *pnew) { return file = pnew; } - bool operator!() { return (file == nullptr); } - - // - // Stream subset - // - void setstate(short bits, const char *psz) { - state |= bits; - if (state & exceptmask) throw std::ios_base::failure(psz); - } - - bool fail() const { return state & (std::ios::badbit | std::ios::failbit); } - bool good() const { return state == 0; } - void clear(short n = 0) { state = n; } - short exceptions() { return exceptmask; } - short exceptions(short mask) { - short prev = exceptmask; - exceptmask = mask; - setstate(0, "CAutoFile"); - return prev; - } - - void SetType(int n) { nType = n; } - int GetType() { return nType; } - void SetVersion(int n) { nVersion = n; } - int GetVersion() { return nVersion; } - void ReadVersion() { *this >> nVersion; } - void WriteVersion() { *this << nVersion; } - - CAutoFile &read(char *pch, int nSize) { - if (!file) - throw std::ios_base::failure( - "CAutoFile::read : file handle is nullptr"); - if (fread(pch, 1, nSize, file) != nSize) - setstate(std::ios::failbit, feof(file) - ? "CAutoFile::read : end of file" - : "CAutoFile::read : fread failed"); - return (*this); - } - - CAutoFile &write(const char *pch, int nSize) { - if (!file) - throw std::ios_base::failure( - "CAutoFile::write : file handle is nullptr"); - if (fwrite(pch, 1, nSize, file) != nSize) - setstate(std::ios::failbit, "CAutoFile::write : write failed"); - return (*this); - } - - template unsigned int GetSerializeSize(const T &obj) { - // Tells the size of the object if serialized to this stream - return ::GetSerializeSize(obj, nType, nVersion); - } - - template CAutoFile &operator<<(const T &obj) { - // Serialize to this stream - if (!file) - throw std::ios_base::failure( - "CAutoFile::operator<< : file handle is nullptr"); - ::Serialize(*this, obj, nType, nVersion); - return (*this); - } - - template CAutoFile &operator>>(T &obj) { - // Unserialize from this stream - if (!file) - throw std::ios_base::failure( - "CAutoFile::operator>> : file handle is nullptr"); - ::Unserialize(*this, obj, nType, nVersion); - return (*this); - } -}; - -#endif diff --git a/src/seeder/uint256.h b/src/seeder/uint256.h deleted file mode 100644 --- a/src/seeder/uint256.h +++ /dev/null @@ -1,825 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2011 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_SEEDER_UINT256_H -#define BITCOIN_SEEDER_UINT256_H - -#include "serialize.h" - -#include -#include -#include -#include - -#if defined(_MSC_VER) && _MSC_VER < 1300 -#define for if (false); else for -#endif - -inline int Testuint256AdHoc(std::vector vArg); - -// We have to keep a separate base class without constructors -// so the compiler will let us use it in a union -template class base_uint { -protected: - enum { WIDTH = BITS / 32 }; - unsigned int pn[WIDTH]; - -public: - bool operator!() const { - for (int i = 0; i < WIDTH; i++) - if (pn[i] != 0) return false; - return true; - } - - const base_uint operator~() const { - base_uint ret; - for (int i = 0; i < WIDTH; i++) - ret.pn[i] = ~pn[i]; - return ret; - } - - const base_uint operator-() const { - base_uint ret; - for (int i = 0; i < WIDTH; i++) - ret.pn[i] = ~pn[i]; - ret++; - return ret; - } - - base_uint &operator=(uint64_t b) { - pn[0] = (unsigned int)b; - pn[1] = (unsigned int)(b >> 32); - for (int i = 2; i < WIDTH; i++) - pn[i] = 0; - return *this; - } - - base_uint &operator^=(const base_uint &b) { - for (int i = 0; i < WIDTH; i++) - pn[i] ^= b.pn[i]; - return *this; - } - - base_uint &operator&=(const base_uint &b) { - for (int i = 0; i < WIDTH; i++) - pn[i] &= b.pn[i]; - return *this; - } - - base_uint &operator|=(const base_uint &b) { - for (int i = 0; i < WIDTH; i++) - pn[i] |= b.pn[i]; - return *this; - } - - base_uint &operator^=(uint64_t b) { - pn[0] ^= (unsigned int)b; - pn[1] ^= (unsigned int)(b >> 32); - return *this; - } - - base_uint &operator&=(uint64_t b) { - pn[0] &= (unsigned int)b; - pn[1] &= (unsigned int)(b >> 32); - return *this; - } - - base_uint &operator|=(uint64_t b) { - pn[0] |= (unsigned int)b; - pn[1] |= (unsigned int)(b >> 32); - return *this; - } - - base_uint &operator<<=(unsigned int shift) { - base_uint a(*this); - for (int i = 0; i < WIDTH; i++) - pn[i] = 0; - int k = shift / 32; - shift = shift % 32; - for (int i = 0; i < WIDTH; i++) { - if (i + k + 1 < WIDTH && shift != 0) - pn[i + k + 1] |= (a.pn[i] >> (32 - shift)); - if (i + k < WIDTH) pn[i + k] |= (a.pn[i] << shift); - } - return *this; - } - - base_uint &operator>>=(unsigned int shift) { - base_uint a(*this); - for (int i = 0; i < WIDTH; i++) - pn[i] = 0; - int k = shift / 32; - shift = shift % 32; - for (int i = 0; i < WIDTH; i++) { - if (i - k - 1 >= 0 && shift != 0) - pn[i - k - 1] |= (a.pn[i] << (32 - shift)); - if (i - k >= 0) pn[i - k] |= (a.pn[i] >> shift); - } - return *this; - } - - base_uint &operator+=(const base_uint &b) { - uint64_t carry = 0; - for (int i = 0; i < WIDTH; i++) { - uint64_t n = carry + pn[i] + b.pn[i]; - pn[i] = n & 0xffffffff; - carry = n >> 32; - } - return *this; - } - - base_uint &operator-=(const base_uint &b) { - *this += -b; - return *this; - } - - base_uint &operator+=(uint64_t b64) { - base_uint b; - b = b64; - *this += b; - return *this; - } - - base_uint &operator-=(uint64_t b64) { - base_uint b; - b = b64; - *this += -b; - return *this; - } - - base_uint &operator++() { - // prefix operator - int i = 0; - while (++pn[i] == 0 && i < WIDTH - 1) - i++; - return *this; - } - - const base_uint operator++(int) { - // postfix operator - const base_uint ret = *this; - ++(*this); - return ret; - } - - base_uint &operator--() { - // prefix operator - int i = 0; - while (--pn[i] == -1 && i < WIDTH - 1) - i++; - return *this; - } - - const base_uint operator--(int) { - // postfix operator - const base_uint ret = *this; - --(*this); - return ret; - } - - friend inline bool operator<(const base_uint &a, const base_uint &b) { - for (int i = base_uint::WIDTH - 1; i >= 0; i--) { - if (a.pn[i] < b.pn[i]) - return true; - else if (a.pn[i] > b.pn[i]) - return false; - } - return false; - } - - friend inline bool operator<=(const base_uint &a, const base_uint &b) { - for (int i = base_uint::WIDTH - 1; i >= 0; i--) { - if (a.pn[i] < b.pn[i]) - return true; - else if (a.pn[i] > b.pn[i]) - return false; - } - return true; - } - - friend inline bool operator>(const base_uint &a, const base_uint &b) { - for (int i = base_uint::WIDTH - 1; i >= 0; i--) { - if (a.pn[i] > b.pn[i]) - return true; - else if (a.pn[i] < b.pn[i]) - return false; - } - return false; - } - - friend inline bool operator>=(const base_uint &a, const base_uint &b) { - for (int i = base_uint::WIDTH - 1; i >= 0; i--) { - if (a.pn[i] > b.pn[i]) - return true; - else if (a.pn[i] < b.pn[i]) - return false; - } - return true; - } - - friend inline bool operator==(const base_uint &a, const base_uint &b) { - for (int i = 0; i < base_uint::WIDTH; i++) - if (a.pn[i] != b.pn[i]) return false; - return true; - } - - friend inline bool operator==(const base_uint &a, uint64_t b) { - if (a.pn[0] != (unsigned int)b) return false; - if (a.pn[1] != (unsigned int)(b >> 32)) return false; - for (int i = 2; i < base_uint::WIDTH; i++) - if (a.pn[i] != 0) return false; - return true; - } - - friend inline bool operator!=(const base_uint &a, const base_uint &b) { - return (!(a == b)); - } - - friend inline bool operator!=(const base_uint &a, uint64_t b) { - return (!(a == b)); - } - - std::string GetHex() const { - char psz[sizeof(pn) * 2 + 1]; - for (int i = 0; i < sizeof(pn); i++) - sprintf(psz + i * 2, "%02x", ((uint8_t *)pn)[sizeof(pn) - i - 1]); - return std::string(psz, psz + sizeof(pn) * 2); - } - - void SetHex(const char *psz) { - for (int i = 0; i < WIDTH; i++) - pn[i] = 0; - - // skip leading spaces - while (isspace(*psz)) - psz++; - - // skip 0x - if (psz[0] == '0' && tolower(psz[1]) == 'x') psz += 2; - - // hex string to uint - static char phexdigit[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, - 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - const char *pbegin = psz; - while (phexdigit[(uint8_t)*psz] || *psz == '0') - psz++; - psz--; - uint8_t *p1 = (uint8_t *)pn; - uint8_t *pend = p1 + WIDTH * 4; - while (psz >= pbegin && p1 < pend) { - *p1 = phexdigit[(uint8_t)*psz--]; - if (psz >= pbegin) { - *p1 |= (phexdigit[(uint8_t)*psz--] << 4); - p1++; - } - } - } - - void SetHex(const std::string &str) { SetHex(str.c_str()); } - - std::string ToString() const { return (GetHex()); } - - uint8_t *begin() { return (uint8_t *)&pn[0]; } - - uint8_t *end() { return (uint8_t *)&pn[WIDTH]; } - - unsigned int size() { return sizeof(pn); } - - unsigned int GetSerializeSize(int nType = 0, - int nVersion = PROTOCOL_VERSION) const { - return sizeof(pn); - } - - template - 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 = PROTOCOL_VERSION) { - s.read((char *)pn, sizeof(pn)); - } - - friend class uint160; - friend class uint256; - friend inline int Testuint256AdHoc(std::vector vArg); -}; - -typedef base_uint<160> base_uint160; -typedef base_uint<256> base_uint256; - -// -// uint160 and uint256 could be implemented as templates, but to keep -// compile errors and debugging cleaner, they're copy and pasted. -// - -////////////////////////////////////////////////////////////////////////////// -// -// uint160 -// - -class uint160 : public base_uint160 { -public: - typedef base_uint160 basetype; - - uint160() { - for (int i = 0; i < WIDTH; i++) - pn[i] = 0; - } - - uint160(const basetype &b) { - for (int i = 0; i < WIDTH; i++) - pn[i] = b.pn[i]; - } - - uint160 &operator=(const basetype &b) { - for (int i = 0; i < WIDTH; i++) - pn[i] = b.pn[i]; - return *this; - } - - uint160(uint64_t b) { - pn[0] = (unsigned int)b; - pn[1] = (unsigned int)(b >> 32); - for (int i = 2; i < WIDTH; i++) - pn[i] = 0; - } - - uint160 &operator=(uint64_t b) { - pn[0] = (unsigned int)b; - pn[1] = (unsigned int)(b >> 32); - for (int i = 2; i < WIDTH; i++) - pn[i] = 0; - return *this; - } - - explicit uint160(const std::string &str) { SetHex(str); } - - explicit uint160(const std::vector &vch) { - if (vch.size() == sizeof(pn)) - memcpy(pn, &vch[0], sizeof(pn)); - else - *this = 0; - } -}; - -inline bool operator==(const uint160 &a, uint64_t b) { - return (base_uint160)a == b; -} -inline bool operator!=(const uint160 &a, uint64_t b) { - return (base_uint160)a != b; -} -inline const uint160 operator<<(const base_uint160 &a, unsigned int shift) { - return uint160(a) <<= shift; -} -inline const uint160 operator>>(const base_uint160 &a, unsigned int shift) { - return uint160(a) >>= shift; -} -inline const uint160 operator<<(const uint160 &a, unsigned int shift) { - return uint160(a) <<= shift; -} -inline const uint160 operator>>(const uint160 &a, unsigned int shift) { - return uint160(a) >>= shift; -} - -inline const uint160 operator^(const base_uint160 &a, const base_uint160 &b) { - return uint160(a) ^= b; -} -inline const uint160 operator&(const base_uint160 &a, const base_uint160 &b) { - return uint160(a) &= b; -} -inline const uint160 operator|(const base_uint160 &a, const base_uint160 &b) { - return uint160(a) |= b; -} -inline const uint160 operator+(const base_uint160 &a, const base_uint160 &b) { - return uint160(a) += b; -} -inline const uint160 operator-(const base_uint160 &a, const base_uint160 &b) { - return uint160(a) -= b; -} - -inline bool operator<(const base_uint160 &a, const uint160 &b) { - return (base_uint160)a < (base_uint160)b; -} -inline bool operator<=(const base_uint160 &a, const uint160 &b) { - return (base_uint160)a <= (base_uint160)b; -} -inline bool operator>(const base_uint160 &a, const uint160 &b) { - return (base_uint160)a > (base_uint160)b; -} -inline bool operator>=(const base_uint160 &a, const uint160 &b) { - return (base_uint160)a >= (base_uint160)b; -} -inline bool operator==(const base_uint160 &a, const uint160 &b) { - return (base_uint160)a == (base_uint160)b; -} -inline bool operator!=(const base_uint160 &a, const uint160 &b) { - return (base_uint160)a != (base_uint160)b; -} -inline const uint160 operator^(const base_uint160 &a, const uint160 &b) { - return (base_uint160)a ^ (base_uint160)b; -} -inline const uint160 operator&(const base_uint160 &a, const uint160 &b) { - return (base_uint160)a & (base_uint160)b; -} -inline const uint160 operator|(const base_uint160 &a, const uint160 &b) { - return (base_uint160)a | (base_uint160)b; -} -inline const uint160 operator+(const base_uint160 &a, const uint160 &b) { - return (base_uint160)a + (base_uint160)b; -} -inline const uint160 operator-(const base_uint160 &a, const uint160 &b) { - return (base_uint160)a - (base_uint160)b; -} - -inline bool operator<(const uint160 &a, const base_uint160 &b) { - return (base_uint160)a < (base_uint160)b; -} -inline bool operator<=(const uint160 &a, const base_uint160 &b) { - return (base_uint160)a <= (base_uint160)b; -} -inline bool operator>(const uint160 &a, const base_uint160 &b) { - return (base_uint160)a > (base_uint160)b; -} -inline bool operator>=(const uint160 &a, const base_uint160 &b) { - return (base_uint160)a >= (base_uint160)b; -} -inline bool operator==(const uint160 &a, const base_uint160 &b) { - return (base_uint160)a == (base_uint160)b; -} -inline bool operator!=(const uint160 &a, const base_uint160 &b) { - return (base_uint160)a != (base_uint160)b; -} -inline const uint160 operator^(const uint160 &a, const base_uint160 &b) { - return (base_uint160)a ^ (base_uint160)b; -} -inline const uint160 operator&(const uint160 &a, const base_uint160 &b) { - return (base_uint160)a & (base_uint160)b; -} -inline const uint160 operator|(const uint160 &a, const base_uint160 &b) { - return (base_uint160)a | (base_uint160)b; -} -inline const uint160 operator+(const uint160 &a, const base_uint160 &b) { - return (base_uint160)a + (base_uint160)b; -} -inline const uint160 operator-(const uint160 &a, const base_uint160 &b) { - return (base_uint160)a - (base_uint160)b; -} - -inline bool operator<(const uint160 &a, const uint160 &b) { - return (base_uint160)a < (base_uint160)b; -} -inline bool operator<=(const uint160 &a, const uint160 &b) { - return (base_uint160)a <= (base_uint160)b; -} -inline bool operator>(const uint160 &a, const uint160 &b) { - return (base_uint160)a > (base_uint160)b; -} -inline bool operator>=(const uint160 &a, const uint160 &b) { - return (base_uint160)a >= (base_uint160)b; -} -inline bool operator==(const uint160 &a, const uint160 &b) { - return (base_uint160)a == (base_uint160)b; -} -inline bool operator!=(const uint160 &a, const uint160 &b) { - return (base_uint160)a != (base_uint160)b; -} -inline const uint160 operator^(const uint160 &a, const uint160 &b) { - return (base_uint160)a ^ (base_uint160)b; -} -inline const uint160 operator&(const uint160 &a, const uint160 &b) { - return (base_uint160)a & (base_uint160)b; -} -inline const uint160 operator|(const uint160 &a, const uint160 &b) { - return (base_uint160)a | (base_uint160)b; -} -inline const uint160 operator+(const uint160 &a, const uint160 &b) { - return (base_uint160)a + (base_uint160)b; -} -inline const uint160 operator-(const uint160 &a, const uint160 &b) { - return (base_uint160)a - (base_uint160)b; -} - -////////////////////////////////////////////////////////////////////////////// -// -// uint256 -// - -class uint256 : public base_uint256 { -public: - typedef base_uint256 basetype; - - uint256() { - for (int i = 0; i < WIDTH; i++) - pn[i] = 0; - } - - uint256(const basetype &b) { - for (int i = 0; i < WIDTH; i++) - pn[i] = b.pn[i]; - } - - uint256 &operator=(const basetype &b) { - for (int i = 0; i < WIDTH; i++) - pn[i] = b.pn[i]; - return *this; - } - - uint256(uint64_t b) { - pn[0] = (unsigned int)b; - pn[1] = (unsigned int)(b >> 32); - for (int i = 2; i < WIDTH; i++) - pn[i] = 0; - } - - uint256 &operator=(uint64_t b) { - pn[0] = (unsigned int)b; - pn[1] = (unsigned int)(b >> 32); - for (int i = 2; i < WIDTH; i++) - pn[i] = 0; - return *this; - } - - explicit uint256(const std::string &str) { SetHex(str); } - - explicit uint256(const std::vector &vch) { - if (vch.size() == sizeof(pn)) - memcpy(pn, &vch[0], sizeof(pn)); - else - *this = 0; - } -}; - -inline bool operator==(const uint256 &a, uint64_t b) { - return (base_uint256)a == b; -} -inline bool operator!=(const uint256 &a, uint64_t b) { - return (base_uint256)a != b; -} -inline const uint256 operator<<(const base_uint256 &a, unsigned int shift) { - return uint256(a) <<= shift; -} -inline const uint256 operator>>(const base_uint256 &a, unsigned int shift) { - return uint256(a) >>= shift; -} -inline const uint256 operator<<(const uint256 &a, unsigned int shift) { - return uint256(a) <<= shift; -} -inline const uint256 operator>>(const uint256 &a, unsigned int shift) { - return uint256(a) >>= shift; -} - -inline const uint256 operator^(const base_uint256 &a, const base_uint256 &b) { - return uint256(a) ^= b; -} -inline const uint256 operator&(const base_uint256 &a, const base_uint256 &b) { - return uint256(a) &= b; -} -inline const uint256 operator|(const base_uint256 &a, const base_uint256 &b) { - return uint256(a) |= b; -} -inline const uint256 operator+(const base_uint256 &a, const base_uint256 &b) { - return uint256(a) += b; -} -inline const uint256 operator-(const base_uint256 &a, const base_uint256 &b) { - return uint256(a) -= b; -} - -inline bool operator<(const base_uint256 &a, const uint256 &b) { - return (base_uint256)a < (base_uint256)b; -} -inline bool operator<=(const base_uint256 &a, const uint256 &b) { - return (base_uint256)a <= (base_uint256)b; -} -inline bool operator>(const base_uint256 &a, const uint256 &b) { - return (base_uint256)a > (base_uint256)b; -} -inline bool operator>=(const base_uint256 &a, const uint256 &b) { - return (base_uint256)a >= (base_uint256)b; -} -inline bool operator==(const base_uint256 &a, const uint256 &b) { - return (base_uint256)a == (base_uint256)b; -} -inline bool operator!=(const base_uint256 &a, const uint256 &b) { - return (base_uint256)a != (base_uint256)b; -} -inline const uint256 operator^(const base_uint256 &a, const uint256 &b) { - return (base_uint256)a ^ (base_uint256)b; -} -inline const uint256 operator&(const base_uint256 &a, const uint256 &b) { - return (base_uint256)a & (base_uint256)b; -} -inline const uint256 operator|(const base_uint256 &a, const uint256 &b) { - return (base_uint256)a | (base_uint256)b; -} -inline const uint256 operator+(const base_uint256 &a, const uint256 &b) { - return (base_uint256)a + (base_uint256)b; -} -inline const uint256 operator-(const base_uint256 &a, const uint256 &b) { - return (base_uint256)a - (base_uint256)b; -} - -inline bool operator<(const uint256 &a, const base_uint256 &b) { - return (base_uint256)a < (base_uint256)b; -} -inline bool operator<=(const uint256 &a, const base_uint256 &b) { - return (base_uint256)a <= (base_uint256)b; -} -inline bool operator>(const uint256 &a, const base_uint256 &b) { - return (base_uint256)a > (base_uint256)b; -} -inline bool operator>=(const uint256 &a, const base_uint256 &b) { - return (base_uint256)a >= (base_uint256)b; -} -inline bool operator==(const uint256 &a, const base_uint256 &b) { - return (base_uint256)a == (base_uint256)b; -} -inline bool operator!=(const uint256 &a, const base_uint256 &b) { - return (base_uint256)a != (base_uint256)b; -} -inline const uint256 operator^(const uint256 &a, const base_uint256 &b) { - return (base_uint256)a ^ (base_uint256)b; -} -inline const uint256 operator&(const uint256 &a, const base_uint256 &b) { - return (base_uint256)a & (base_uint256)b; -} -inline const uint256 operator|(const uint256 &a, const base_uint256 &b) { - return (base_uint256)a | (base_uint256)b; -} -inline const uint256 operator+(const uint256 &a, const base_uint256 &b) { - return (base_uint256)a + (base_uint256)b; -} -inline const uint256 operator-(const uint256 &a, const base_uint256 &b) { - return (base_uint256)a - (base_uint256)b; -} - -inline bool operator<(const uint256 &a, const uint256 &b) { - return (base_uint256)a < (base_uint256)b; -} -inline bool operator<=(const uint256 &a, const uint256 &b) { - return (base_uint256)a <= (base_uint256)b; -} -inline bool operator>(const uint256 &a, const uint256 &b) { - return (base_uint256)a > (base_uint256)b; -} -inline bool operator>=(const uint256 &a, const uint256 &b) { - return (base_uint256)a >= (base_uint256)b; -} -inline bool operator==(const uint256 &a, const uint256 &b) { - return (base_uint256)a == (base_uint256)b; -} -inline bool operator!=(const uint256 &a, const uint256 &b) { - return (base_uint256)a != (base_uint256)b; -} -inline const uint256 operator^(const uint256 &a, const uint256 &b) { - return (base_uint256)a ^ (base_uint256)b; -} -inline const uint256 operator&(const uint256 &a, const uint256 &b) { - return (base_uint256)a & (base_uint256)b; -} -inline const uint256 operator|(const uint256 &a, const uint256 &b) { - return (base_uint256)a | (base_uint256)b; -} -inline const uint256 operator+(const uint256 &a, const uint256 &b) { - return (base_uint256)a + (base_uint256)b; -} -inline const uint256 operator-(const uint256 &a, const uint256 &b) { - return (base_uint256)a - (base_uint256)b; -} - -inline int Testuint256AdHoc(std::vector vArg) { - uint256 g(0); - - printf("%s\n", g.ToString().c_str()); - g--; - printf("g--\n"); - printf("%s\n", g.ToString().c_str()); - g--; - printf("g--\n"); - printf("%s\n", g.ToString().c_str()); - g++; - printf("g++\n"); - printf("%s\n", g.ToString().c_str()); - g++; - printf("g++\n"); - printf("%s\n", g.ToString().c_str()); - g++; - printf("g++\n"); - printf("%s\n", g.ToString().c_str()); - g++; - printf("g++\n"); - printf("%s\n", g.ToString().c_str()); - - uint256 a(7); - printf("a=7\n"); - printf("%s\n", a.ToString().c_str()); - - uint256 b; - printf("b undefined\n"); - printf("%s\n", b.ToString().c_str()); - int c = 3; - - a = c; - a.pn[3] = 15; - printf("%s\n", a.ToString().c_str()); - uint256 k(c); - - a = 5; - a.pn[3] = 15; - printf("%s\n", a.ToString().c_str()); - b = 1; - b <<= 52; - - a |= b; - - a ^= 0x500; - - printf("a %s\n", a.ToString().c_str()); - - a = a | b | (uint256)0x1000; - - printf("a %s\n", a.ToString().c_str()); - printf("b %s\n", b.ToString().c_str()); - - a = 0xfffffffe; - a.pn[4] = 9; - - printf("%s\n", a.ToString().c_str()); - a++; - printf("%s\n", a.ToString().c_str()); - a++; - printf("%s\n", a.ToString().c_str()); - a++; - printf("%s\n", a.ToString().c_str()); - a++; - printf("%s\n", a.ToString().c_str()); - - a--; - printf("%s\n", a.ToString().c_str()); - a--; - printf("%s\n", a.ToString().c_str()); - a--; - printf("%s\n", a.ToString().c_str()); - uint256 d = a--; - printf("%s\n", d.ToString().c_str()); - printf("%s\n", a.ToString().c_str()); - a--; - printf("%s\n", a.ToString().c_str()); - a--; - printf("%s\n", a.ToString().c_str()); - - d = a; - - printf("%s\n", d.ToString().c_str()); - for (int i = uint256::WIDTH - 1; i >= 0; i--) - printf("%08x", d.pn[i]); - printf("\n"); - - uint256 neg = d; - neg = ~neg; - printf("%s\n", neg.ToString().c_str()); - - uint256 e = uint256("0xABCDEF123abcdef12345678909832180000011111111"); - printf("\n"); - printf("%s\n", e.ToString().c_str()); - - printf("\n"); - uint256 x1 = uint256("0xABCDEF123abcdef12345678909832180000011111111"); - uint256 x2; - printf("%s\n", x1.ToString().c_str()); - for (int i = 0; i < 270; i += 4) { - x2 = x1 << i; - printf("%s\n", x2.ToString().c_str()); - } - - printf("\n"); - printf("%s\n", x1.ToString().c_str()); - for (int i = 0; i < 270; i += 4) { - x2 = x1; - x2 >>= i; - printf("%s\n", x2.ToString().c_str()); - } - - for (int i = 0; i < 100; i++) { - uint256 k = (~uint256(0) >> i); - printf("%s\n", k.ToString().c_str()); - } - - for (int i = 0; i < 100; i++) { - uint256 k = (~uint256(0) << i); - printf("%s\n", k.ToString().c_str()); - } - - return (0); -} - -#endif