From 5d3064bc44e0b608a428e230f384bd3f846dedca Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 15 Dec 2014 10:05:51 +0100 Subject: [PATCH 01/12] Temporarily add SetNull/IsNull/GetCheapHash to base_uint Also add a stub for arith_uint256 and its conversion functions, for now completely based on uint256. Eases step-by-step migration to blob. --- src/arith_uint256.h | 19 +++++++++++++++++++ src/uint256.h | 20 ++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 src/arith_uint256.h diff --git a/src/arith_uint256.h b/src/arith_uint256.h new file mode 100644 index 0000000000000..3bb384ca8aedd --- /dev/null +++ b/src/arith_uint256.h @@ -0,0 +1,19 @@ +#ifndef BITCOIN_ARITH_UINT256_H +#define BITCOIN_ARITH_UINT256_H + +// Temporary for migration to opaque uint160/256 +#include "uint256.h" + +class arith_uint256 : public uint256 { +public: + arith_uint256() {} + arith_uint256(const base_uint<256>& b) : uint256(b) {} + arith_uint256(uint64_t b) : uint256(b) {} + explicit arith_uint256(const std::string& str) : uint256(str) {} + explicit arith_uint256(const std::vector& vch) : uint256(vch) {} +}; + +#define ArithToUint256(x) (x) +#define UintToArith256(x) (x) + +#endif // BITCOIN_UINT256_H diff --git a/src/uint256.h b/src/uint256.h index 139270ac49849..8189b27cb3c88 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -283,6 +283,23 @@ class base_uint { s.read((char*)pn, sizeof(pn)); } + + // Temporary for migration to opaque uint160/256 + uint64_t GetCheapHash() const + { + return GetLow64(); + } + void SetNull() + { + memset(pn, 0, sizeof(pn)); + } + bool IsNull() const + { + for (int i = 0; i < WIDTH; i++) + if (pn[i] != 0) + return false; + return true; + } }; /** 160-bit unsigned big integer. */ @@ -330,4 +347,7 @@ class uint256 : public base_uint<256> { uint64_t GetHash(const uint256& salt) const; }; +// Temporary for migration to opaque uint160/256 +inline uint256 uint256S(const std::string &x) { return uint256(x); } + #endif // BITCOIN_UINT256_H From 4f1524966a99c83db8c0c9f1ff74789253a1171e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 15 Dec 2014 09:11:16 +0100 Subject: [PATCH 02/12] Replace direct use of 0 with SetNull and IsNull Replace x=0 with .SetNull(), x==0 with IsNull(), x!=0 with !IsNull(). Replace uses of uint256(0) with uint256(). --- src/bitcoin-tx.cpp | 4 ++-- src/chain.h | 8 ++++---- src/chainparams.cpp | 2 +- src/coins.cpp | 6 +++--- src/coins.h | 2 +- src/core_write.cpp | 2 +- src/key.cpp | 4 ++-- src/main.cpp | 22 +++++++++++----------- src/merkleblock.cpp | 18 +++++++++--------- src/net.cpp | 2 +- src/primitives/block.cpp | 4 ++-- src/primitives/block.h | 4 ++-- src/primitives/transaction.cpp | 2 +- src/primitives/transaction.h | 4 ++-- src/protocol.cpp | 2 +- src/pubkey.h | 2 +- src/rest.cpp | 2 +- src/rpcblockchain.cpp | 2 +- src/rpcrawtransaction.cpp | 6 +++--- src/rpcwallet.cpp | 4 ++-- src/script/standard.h | 2 +- src/test/pmt_tests.cpp | 6 +++--- src/test/script_P2SH_tests.cpp | 2 +- src/test/sigopcount_tests.cpp | 2 +- src/txdb.cpp | 6 +++--- src/wallet.cpp | 10 +++++----- src/wallet.h | 2 +- src/walletdb.cpp | 4 ++-- 28 files changed, 68 insertions(+), 68 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 05a85810ec239..f095551c48e93 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -315,7 +315,7 @@ static bool findSighashFlags(int& flags, const string& flagStr) uint256 ParseHashUO(map& o, string strKey) { if (!o.count(strKey)) - return 0; + return uint256(); return ParseHashUV(o[strKey], strKey); } @@ -485,7 +485,7 @@ static void MutateTx(CMutableTransaction& tx, const string& command, static void OutputTxJSON(const CTransaction& tx) { UniValue entry(UniValue::VOBJ); - TxToUniv(tx, 0, entry); + TxToUniv(tx, uint256(), entry); string jsonOutput = entry.write(4); fprintf(stdout, "%s\n", jsonOutput.c_str()); diff --git a/src/chain.h b/src/chain.h index b459c975f8237..d7741762c758b 100644 --- a/src/chain.h +++ b/src/chain.h @@ -150,14 +150,14 @@ class CBlockIndex nFile = 0; nDataPos = 0; nUndoPos = 0; - nChainWork = 0; + nChainWork = uint256(); nTx = 0; nChainTx = 0; nStatus = 0; nSequenceId = 0; nVersion = 0; - hashMerkleRoot = 0; + hashMerkleRoot = uint256(); nTime = 0; nBits = 0; nNonce = 0; @@ -282,11 +282,11 @@ class CDiskBlockIndex : public CBlockIndex uint256 hashPrev; CDiskBlockIndex() { - hashPrev = 0; + hashPrev = uint256(); } explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) { - hashPrev = (pprev ? pprev->GetBlockHash() : 0); + hashPrev = (pprev ? pprev->GetBlockHash() : uint256()); } ADD_SERIALIZE_METHODS; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index f4bc6e1d7031d..7e76a0bfa2df7 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -141,7 +141,7 @@ class CMainParams : public CChainParams { txNew.vout[0].nValue = 50 * COIN; txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; genesis.vtx.push_back(txNew); - genesis.hashPrevBlock = 0; + genesis.hashPrevBlock.SetNull(); genesis.hashMerkleRoot = genesis.BuildMerkleTree(); genesis.nVersion = 1; genesis.nTime = 1231006505; diff --git a/src/coins.cpp b/src/coins.cpp index f4599ff39df0e..ef4f96fdeecf5 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -42,7 +42,7 @@ bool CCoins::Spend(uint32_t nPos) bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; } bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; } -uint256 CCoinsView::GetBestBlock() const { return uint256(0); } +uint256 CCoinsView::GetBestBlock() const { return uint256(); } bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; } bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; } @@ -57,7 +57,7 @@ bool CCoinsViewBacked::GetStats(CCoinsStats &stats) const { return base->GetStat CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {} -CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false), hashBlock(0) { } +CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false) { } CCoinsViewCache::~CCoinsViewCache() { @@ -128,7 +128,7 @@ bool CCoinsViewCache::HaveCoins(const uint256 &txid) const { } uint256 CCoinsViewCache::GetBestBlock() const { - if (hashBlock == uint256(0)) + if (hashBlock.IsNull()) hashBlock = base->GetBestBlock(); return hashBlock; } diff --git a/src/coins.h b/src/coins.h index 4f1afb00de2c0..fe2eaa08e523e 100644 --- a/src/coins.h +++ b/src/coins.h @@ -297,7 +297,7 @@ struct CCoinsStats uint256 hashSerialized; CAmount nTotalAmount; - CCoinsStats() : nHeight(0), hashBlock(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), hashSerialized(0), nTotalAmount(0) {} + CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), nTotalAmount(0) {} }; diff --git a/src/core_write.cpp b/src/core_write.cpp index b6fd7fe87738b..c3babec2fc0a1 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -127,7 +127,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry) } entry.pushKV("vout", vout); - if (hashBlock != 0) + if (!hashBlock.IsNull()) entry.pushKV("blockhash", hashBlock.GetHex()); entry.pushKV("hex", EncodeHexTx(tx)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction". diff --git a/src/key.cpp b/src/key.cpp index f09536fbbe2eb..50ccb09213c6c 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -84,7 +84,7 @@ bool CKey::Sign(const uint256 &hash, std::vector& vchSig, uint32_ nonce += test_case; int nSigLen = 72; int ret = secp256k1_ecdsa_sign((const unsigned char*)&hash, (unsigned char*)&vchSig[0], &nSigLen, begin(), (unsigned char*)&nonce); - nonce = 0; + nonce = uint256(); if (ret) { vchSig.resize(nSigLen); return true; @@ -116,7 +116,7 @@ bool CKey::SignCompact(const uint256 &hash, std::vector& vchSig) uint256 nonce; prng.Generate((unsigned char*)&nonce, 32); int ret = secp256k1_ecdsa_sign_compact((const unsigned char*)&hash, &vchSig[1], begin(), (unsigned char*)&nonce, &rec); - nonce = 0; + nonce = uint256(); if (ret) break; } while(true); diff --git a/src/main.cpp b/src/main.cpp index 4fcb4f093ae7a..c392138ff38c4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -261,7 +261,7 @@ struct CNodeState { nMisbehavior = 0; fShouldBan = false; pindexBestKnownBlock = NULL; - hashLastUnknownBlock = uint256(0); + hashLastUnknownBlock.SetNull(); pindexLastCommonBlock = NULL; fSyncStarted = false; nStallingSince = 0; @@ -349,12 +349,12 @@ void ProcessBlockAvailability(NodeId nodeid) { CNodeState *state = State(nodeid); assert(state != NULL); - if (state->hashLastUnknownBlock != 0) { + if (!state->hashLastUnknownBlock.IsNull()) { BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock); if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0) { if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork) state->pindexBestKnownBlock = itOld->second; - state->hashLastUnknownBlock = uint256(0); + state->hashLastUnknownBlock.SetNull(); } } } @@ -1712,7 +1712,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return false; // verify that the view's current state corresponds to the previous block - uint256 hashPrevBlock = pindex->pprev == NULL ? uint256(0) : pindex->pprev->GetBlockHash(); + uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash(); assert(hashPrevBlock == view.GetBestBlock()); // Special case for the genesis block, skipping connection of its transactions @@ -2835,7 +2835,7 @@ boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char CBlockIndex * InsertBlockIndex(uint256 hash) { - if (hash == 0) + if (hash.IsNull()) return NULL; // Return existing @@ -3369,7 +3369,7 @@ void static ProcessGetData(CNode* pfrom) vector vInv; vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash())); pfrom->PushMessage("inv", vInv); - pfrom->hashContinue = 0; + pfrom->hashContinue.SetNull(); } } } @@ -3604,7 +3604,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Use deterministic randomness to send to the same nodes for 24 hours // at a time so the setAddrKnowns of the chosen nodes prevent repeats static uint256 hashSalt; - if (hashSalt == 0) + if (hashSalt.IsNull()) hashSalt = GetRandHash(); uint64_t hashAddr = addr.GetHash(); uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)); @@ -3738,7 +3738,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (pindex) pindex = chainActive.Next(pindex); int nLimit = 500; - LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop==uint256(0) ? "end" : hashStop.ToString(), nLimit, pfrom->id); + LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom->id); for (; pindex; pindex = chainActive.Next(pindex)) { if (pindex->GetBlockHash() == hashStop) @@ -3954,7 +3954,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue // from there instead. LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight); - pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256(0)); + pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256()); } } @@ -4452,7 +4452,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) nSyncStarted++; CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader; LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight); - pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256(0)); + pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256()); } } @@ -4483,7 +4483,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) { // 1/4 of tx invs blast to all immediately static uint256 hashSalt; - if (hashSalt == 0) + if (hashSalt.IsNull()) hashSalt = GetRandHash(); uint256 hashRand = inv.hash ^ hashSalt; hashRand = Hash(BEGIN(hashRand), END(hashRand)); diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index f9006d46d5989..b51b002b954f7 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -76,7 +76,7 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns if (nBitsUsed >= vBits.size()) { // overflowed the bits array - failure fBad = true; - return 0; + return uint256(); } bool fParentOfMatch = vBits[nBitsUsed++]; if (height==0 || !fParentOfMatch) { @@ -84,7 +84,7 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns if (nHashUsed >= vHash.size()) { // overflowed the hash array - failure fBad = true; - return 0; + return uint256(); } const uint256 &hash = vHash[nHashUsed++]; if (height==0 && fParentOfMatch) // in case of height 0, we have a matched txid @@ -128,16 +128,16 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector &vMatch) { vMatch.clear(); // An empty set will not work if (nTransactions == 0) - return 0; + return uint256(); // check for excessively high numbers of transactions if (nTransactions > MAX_BLOCK_SIZE / 60) // 60 is the lower bound for the size of a serialized CTransaction - return 0; + return uint256(); // there can never be more hashes provided than one for every txid if (vHash.size() > nTransactions) - return 0; + return uint256(); // there must be at least one bit per node in the partial tree, and at least one node per hash if (vBits.size() < vHash.size()) - return 0; + return uint256(); // calculate height of tree int nHeight = 0; while (CalcTreeWidth(nHeight) > 1) @@ -147,12 +147,12 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector &vMatch) { uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch); // verify that no problems occured during the tree traversal if (fBad) - return 0; + return uint256(); // verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence) if ((nBitsUsed+7)/8 != (vBits.size()+7)/8) - return 0; + return uint256(); // verify that all hashes were consumed if (nHashUsed != vHash.size()) - return 0; + return uint256(); return hashMerkleRoot; } diff --git a/src/net.cpp b/src/net.cpp index 6401ecbf83e06..0548468714216 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1949,7 +1949,7 @@ CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fIn nRefCount = 0; nSendSize = 0; nSendOffset = 0; - hashContinue = 0; + hashContinue = uint256(); nStartingHeight = -1; fGetAddr = false; fRelayTxes = false; diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 2b6a302ee97ea..3b4a360395fbb 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -74,7 +74,7 @@ uint256 CBlock::BuildMerkleTree(bool* fMutated) const if (fMutated) { *fMutated = mutated; } - return (vMerkleTree.empty() ? 0 : vMerkleTree.back()); + return (vMerkleTree.empty() ? uint256() : vMerkleTree.back()); } std::vector CBlock::GetMerkleBranch(int nIndex) const @@ -96,7 +96,7 @@ std::vector CBlock::GetMerkleBranch(int nIndex) const uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector& vMerkleBranch, int nIndex) { if (nIndex == -1) - return 0; + return uint256(); for (std::vector::const_iterator it(vMerkleBranch.begin()); it != vMerkleBranch.end(); ++it) { if (nIndex & 1) diff --git a/src/primitives/block.h b/src/primitives/block.h index 1449882bd05aa..53fcd104ad1e9 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -53,8 +53,8 @@ class CBlockHeader void SetNull() { nVersion = CBlockHeader::CURRENT_VERSION; - hashPrevBlock = 0; - hashMerkleRoot = 0; + hashPrevBlock.SetNull(); + hashMerkleRoot.SetNull(); nTime = 0; nBits = 0; nNonce = 0; diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 230aedd896b69..848d4d3e60cc2 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -72,7 +72,7 @@ void CTransaction::UpdateHash() const *const_cast(&hash) = SerializeHash(*this); } -CTransaction::CTransaction() : hash(0), nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { } +CTransaction::CTransaction() : nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { } CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) { UpdateHash(); diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index da35012300058..1b5a47e0da9d7 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -28,8 +28,8 @@ class COutPoint READWRITE(FLATDATA(*this)); } - void SetNull() { hash = 0; n = (uint32_t) -1; } - bool IsNull() const { return (hash == 0 && n == (uint32_t) -1); } + void SetNull() { hash.SetNull(); n = (uint32_t) -1; } + bool IsNull() const { return (hash.IsNull() && n == (uint32_t) -1); } friend bool operator<(const COutPoint& a, const COutPoint& b) { diff --git a/src/protocol.cpp b/src/protocol.cpp index 71c6bd152bbe9..2dfded43bea35 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -96,7 +96,7 @@ void CAddress::Init() CInv::CInv() { type = 0; - hash = 0; + hash.SetNull(); } CInv::CInv(int typeIn, const uint256& hashIn) diff --git a/src/pubkey.h b/src/pubkey.h index 69b73a4e1ce68..b0768d4f476f7 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -27,7 +27,7 @@ class CKeyID : public uint160 { public: - CKeyID() : uint160(0) {} + CKeyID() : uint160() {} CKeyID(const uint160& in) : uint160(in) {} }; diff --git a/src/rest.cpp b/src/rest.cpp index 4702f0d707019..1ee1d5291269b 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -240,7 +240,7 @@ static bool rest_tx(AcceptedConnection* conn, throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); CTransaction tx; - uint256 hashBlock = 0; + uint256 hashBlock = uint256(); if (!GetTransaction(hash, tx, hashBlock, true)) throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found"); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 71fb7c8233a24..4705c07b8c028 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -70,7 +70,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDe if(txDetails) { Object objTx; - TxToJSON(tx, uint256(0), objTx); + TxToJSON(tx, uint256(), objTx); txs.push_back(objTx); } else diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index b87a8baac3c57..10dc2ca93e997 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -89,7 +89,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) } entry.push_back(Pair("vout", vout)); - if (hashBlock != 0) { + if (!hashBlock.IsNull()) { entry.push_back(Pair("blockhash", hashBlock.GetHex())); BlockMap::iterator mi = mapBlockIndex.find(hashBlock); if (mi != mapBlockIndex.end() && (*mi).second) { @@ -178,7 +178,7 @@ Value getrawtransaction(const Array& params, bool fHelp) fVerbose = (params[1].get_int() != 0); CTransaction tx; - uint256 hashBlock = 0; + uint256 hashBlock; if (!GetTransaction(hash, tx, hashBlock, true)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); @@ -438,7 +438,7 @@ Value decoderawtransaction(const Array& params, bool fHelp) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); Object result; - TxToJSON(tx, 0, result); + TxToJSON(tx, uint256(), result); return result; } diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index af7e8221cc789..21f6bcae3d726 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1477,7 +1477,7 @@ Value listsinceblock(const Array& params, bool fHelp) if (params.size() > 0) { - uint256 blockId = 0; + uint256 blockId; blockId.SetHex(params[0].get_str()); BlockMap::iterator it = mapBlockIndex.find(blockId); @@ -1510,7 +1510,7 @@ Value listsinceblock(const Array& params, bool fHelp) } CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms]; - uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : 0; + uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256(); Object ret; ret.push_back(Pair("transactions", transactions)); diff --git a/src/script/standard.h b/src/script/standard.h index 1d29ef57aa8cf..dbeeace4d9b7f 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -20,7 +20,7 @@ class CScript; class CScriptID : public uint160 { public: - CScriptID() : uint160(0) {} + CScriptID() : uint160() {} CScriptID(const CScript& in); CScriptID(const uint160& in) : uint160(in) {} }; diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index 56e05416646c0..af3d90f2eb142 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1) // calculate actual merkle root and height uint256 merkleRoot1 = block.BuildMerkleTree(); - std::vector vTxid(nTx, 0); + std::vector vTxid(nTx, uint256()); for (unsigned int j=0; j vTxid2; - BOOST_CHECK(tree.ExtractMatches(vTxid) == 0); + BOOST_CHECK(tree.ExtractMatches(vTxid).IsNull()); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index 63553556ec02c..77e70022df9cb 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -210,7 +210,7 @@ BOOST_AUTO_TEST_CASE(set) BOOST_AUTO_TEST_CASE(is) { // Test CScript::IsPayToScriptHash() - uint160 dummy(0); + uint160 dummy; CScript p2sh; p2sh << OP_HASH160 << ToByteVector(dummy) << OP_EQUAL; BOOST_CHECK(p2sh.IsPayToScriptHash()); diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index 3326601492aeb..3c8264d89d1f6 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount) BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 0U); BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 0U); - uint160 dummy(0); + uint160 dummy; s1 << OP_1 << ToByteVector(dummy) << ToByteVector(dummy) << OP_2 << OP_CHECKMULTISIG; BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 2U); s1 << OP_IF << OP_CHECKSIG << OP_ENDIF; diff --git a/src/txdb.cpp b/src/txdb.cpp index 5096ab19a5d61..4467cdce70760 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -39,7 +39,7 @@ bool CCoinsViewDB::HaveCoins(const uint256 &txid) const { uint256 CCoinsViewDB::GetBestBlock() const { uint256 hashBestChain; if (!db.Read('B', hashBestChain)) - return uint256(0); + return uint256(); return hashBestChain; } @@ -56,7 +56,7 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { CCoinsMap::iterator itOld = it++; mapCoins.erase(itOld); } - if (hashBlock != uint256(0)) + if (!hashBlock.IsNull()) BatchWriteHashBestChain(batch, hashBlock); LogPrint("coindb", "Committing %u changed transactions (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count); @@ -179,7 +179,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts() boost::scoped_ptr pcursor(NewIterator()); CDataStream ssKeySet(SER_DISK, CLIENT_VERSION); - ssKeySet << make_pair('b', uint256(0)); + ssKeySet << make_pair('b', uint256()); pcursor->Seek(ssKeySet.str()); // Load mapBlockIndex diff --git a/src/wallet.cpp b/src/wallet.cpp index 4920cb21fc030..6c5af3bdc7dcc 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -579,7 +579,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet) wtx.nOrderPos = IncOrderPosNext(); wtx.nTimeSmart = wtx.nTimeReceived; - if (wtxIn.hashBlock != 0) + if (!wtxIn.hashBlock.IsNull()) { if (mapBlockIndex.count(wtxIn.hashBlock)) { @@ -630,7 +630,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet) if (!fInsertedNew) { // Merge - if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock) + if (!wtxIn.hashBlock.IsNull() && wtxIn.hashBlock != wtx.hashBlock) { wtx.hashBlock = wtxIn.hashBlock; fUpdated = true; @@ -795,7 +795,7 @@ int CWalletTx::GetRequestCount() const if (IsCoinBase()) { // Generated block - if (hashBlock != 0) + if (!hashBlock.IsNull()) { map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); if (mi != pwallet->mapRequestCount.end()) @@ -811,7 +811,7 @@ int CWalletTx::GetRequestCount() const nRequests = (*mi).second; // How about the block it's in? - if (nRequests == 0 && hashBlock != 0) + if (nRequests == 0 && !hashBlock.IsNull()) { map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); if (mi != pwallet->mapRequestCount.end()) @@ -2317,7 +2317,7 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block) int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const { - if (hashBlock == 0 || nIndex == -1) + if (hashBlock.IsNull() || nIndex == -1) return 0; AssertLockHeld(cs_main); diff --git a/src/wallet.h b/src/wallet.h index 4d95d0ae2e777..1d0dc97c6cffd 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -519,7 +519,7 @@ class CMerkleTx : public CTransaction void Init() { - hashBlock = 0; + hashBlock = uint256(); nIndex = -1; fMerkleVerified = false; } diff --git a/src/walletdb.cpp b/src/walletdb.cpp index 4fd7eb512b92d..0ec83e7b32328 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -439,7 +439,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } CKey key; CPrivKey pkey; - uint256 hash = 0; + uint256 hash; if (strType == "key") { @@ -464,7 +464,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, bool fSkipCheck = false; - if (hash != 0) + if (!hash.IsNull()) { // hash pubkey/privkey to accelerate wallet load std::vector vchKey; From 807658549c61d1fb0da3138ea0ca749ecba61723 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 15 Dec 2014 09:12:11 +0100 Subject: [PATCH 03/12] Replace GetLow64 with GetCheapHash --- src/addrman.cpp | 8 ++++---- src/main.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 1982db52ae33c..1e08ae772ea0b 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -15,12 +15,12 @@ int CAddrInfo::GetTriedBucket(const std::vector& nKey) const CDataStream ss1(SER_GETHASH, 0); std::vector vchKey = GetKey(); ss1 << nKey << vchKey; - uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetLow64(); + uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetCheapHash(); CDataStream ss2(SER_GETHASH, 0); std::vector vchGroupKey = GetGroup(); ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP); - uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetLow64(); + uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetCheapHash(); return hash2 % ADDRMAN_TRIED_BUCKET_COUNT; } @@ -30,11 +30,11 @@ int CAddrInfo::GetNewBucket(const std::vector& nKey, const CNetAd std::vector vchGroupKey = GetGroup(); std::vector vchSourceGroupKey = src.GetGroup(); ss1 << nKey << vchGroupKey << vchSourceGroupKey; - uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetLow64(); + uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetCheapHash(); CDataStream ss2(SER_GETHASH, 0); ss2 << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP); - uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetLow64(); + uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetCheapHash(); return hash2 % ADDRMAN_NEW_BUCKET_COUNT; } diff --git a/src/main.h b/src/main.h index 9049f5bb7d403..1e00114768dc8 100644 --- a/src/main.h +++ b/src/main.h @@ -106,7 +106,7 @@ static const unsigned char REJECT_CHECKPOINT = 0x43; struct BlockHasher { - size_t operator()(const uint256& hash) const { return hash.GetLow64(); } + size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); } }; extern CScript COINBASE_FLAGS; From 2eae3157f65197109d7745ea3926d086de812f7b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 15 Dec 2014 09:17:25 +0100 Subject: [PATCH 04/12] Replace uint256(1) with static constant SignatureHash and its test function SignatureHashOld return uint256(1) as a special error signaling value. Return a local static constant with the same value instead. --- src/script/interpreter.cpp | 5 +++-- src/test/sighash_tests.cpp | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 80a32e78f9040..7f8b371d605d3 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1030,16 +1030,17 @@ class CTransactionSignatureSerializer { uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) { + static const uint256 one("0000000000000000000000000000000000000000000000000000000000000001"); if (nIn >= txTo.vin.size()) { // nIn out of range - return 1; + return one; } // Check for invalid use of SIGHASH_SINGLE if ((nHashType & 0x1f) == SIGHASH_SINGLE) { if (nIn >= txTo.vout.size()) { // nOut out of range - return 1; + return one; } } diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index a9d2f9e8cadb4..036f70ec0f6f5 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -24,10 +24,11 @@ extern Array read_json(const std::string& jsondata); // Old script.cpp SignatureHash function uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) { + static const uint256 one("0000000000000000000000000000000000000000000000000000000000000001"); if (nIn >= txTo.vin.size()) { printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); - return 1; + return one; } CMutableTransaction txTmp(txTo); @@ -58,7 +59,7 @@ uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, un if (nOut >= txTmp.vout.size()) { printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut); - return 1; + return one; } txTmp.vout.resize(nOut+1); for (unsigned int i = 0; i < nOut; i++) From 34cdc41128eee5da0be9c5e17b3c24b1f91a1957 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 16 Dec 2014 14:50:05 +0100 Subject: [PATCH 05/12] String conversions uint256 -> uint256S If uint256() constructor takes a string, uint256(0) will become dangerous when uint256 does not take integers anymore (it will go through std::string(const char*) making a NULL string, and the explicit keyword is no help). --- src/bitcoin-tx.cpp | 2 +- src/chainparams.cpp | 38 +++++++++++----------- src/main.cpp | 4 +-- src/qt/coincontroldialog.cpp | 8 ++--- src/rpcblockchain.cpp | 8 ++--- src/rpcwallet.cpp | 2 +- src/script/interpreter.cpp | 2 +- src/test/Checkpoints_tests.cpp | 4 +-- src/test/bloom_tests.cpp | 58 +++++++++++++++++----------------- src/test/sighash_tests.cpp | 2 +- src/test/transaction_tests.cpp | 4 +-- 11 files changed, 66 insertions(+), 66 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index f095551c48e93..e9dac9ffb95a9 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -191,7 +191,7 @@ static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput) string strTxid = strInput.substr(0, pos); if ((strTxid.size() != 64) || !IsHex(strTxid)) throw runtime_error("invalid TX input txid"); - uint256 txid(strTxid); + uint256 txid(uint256S(strTxid)); static const unsigned int minTxOutSz = 9; static const unsigned int maxVout = MAX_BLOCK_SIZE / minTxOutSz; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 7e76a0bfa2df7..844640061e88d 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -54,19 +54,19 @@ static void convertSeed6(std::vector &vSeedsOut, const SeedSpec6 *data */ static Checkpoints::MapCheckpoints mapCheckpoints = boost::assign::map_list_of - ( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) - ( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) - ( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")) - (105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")) - (134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")) - (168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")) - (193000, uint256("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")) - (210000, uint256("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")) - (216116, uint256("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")) - (225430, uint256("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")) - (250000, uint256("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")) - (279000, uint256("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")) - (295000, uint256("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983")) + ( 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) + ( 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) + ( 74000, uint256S("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")) + (105000, uint256S("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")) + (134444, uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")) + (168000, uint256S("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")) + (193000, uint256S("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")) + (210000, uint256S("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")) + (216116, uint256S("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")) + (225430, uint256S("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")) + (250000, uint256S("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")) + (279000, uint256S("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")) + (295000, uint256S("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983")) ; static const Checkpoints::CCheckpointData data = { &mapCheckpoints, @@ -78,7 +78,7 @@ static const Checkpoints::CCheckpointData data = { static Checkpoints::MapCheckpoints mapCheckpointsTestnet = boost::assign::map_list_of - ( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")) + ( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")) ; static const Checkpoints::CCheckpointData dataTestnet = { &mapCheckpointsTestnet, @@ -89,7 +89,7 @@ static const Checkpoints::CCheckpointData dataTestnet = { static Checkpoints::MapCheckpoints mapCheckpointsRegtest = boost::assign::map_list_of - ( 0, uint256("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")) + ( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")) ; static const Checkpoints::CCheckpointData dataRegtest = { &mapCheckpointsRegtest, @@ -149,8 +149,8 @@ class CMainParams : public CChainParams { genesis.nNonce = 2083236893; hashGenesisBlock = genesis.GetHash(); - assert(hashGenesisBlock == uint256("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); - assert(genesis.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); + assert(hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); + assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be")); vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me")); @@ -208,7 +208,7 @@ class CTestNetParams : public CMainParams { genesis.nTime = 1296688602; genesis.nNonce = 414098458; hashGenesisBlock = genesis.GetHash(); - assert(hashGenesisBlock == uint256("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943")); + assert(hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943")); vFixedSeeds.clear(); vSeeds.clear(); @@ -265,7 +265,7 @@ class CRegTestParams : public CTestNetParams { genesis.nNonce = 2; hashGenesisBlock = genesis.GetHash(); nDefaultPort = 18444; - assert(hashGenesisBlock == uint256("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); + assert(hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds. vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds. diff --git a/src/main.cpp b/src/main.cpp index c392138ff38c4..77d2dcb20481a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1738,8 +1738,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // two in the chain that violate it. This prevents exploiting the issue against nodes in their // initial block download. bool fEnforceBIP30 = (!pindex->phashBlock) || // Enforce on CreateNewBlock invocations which don't have a hash. - !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) || - (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721"))); + !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256S("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) || + (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256S("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721"))); if (fEnforceBIP30) { BOOST_FOREACH(const CTransaction& tx, block.vtx) { const CCoins* coins = view.AccessCoins(tx.GetHash()); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 60e7d62a7a713..8422f316f98db 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -213,7 +213,7 @@ void CoinControlDialog::showMenu(const QPoint &point) if (item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode) { copyTransactionHashAction->setEnabled(true); - if (model->isLockedCoin(uint256(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt())) + if (model->isLockedCoin(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt())) { lockAction->setEnabled(false); unlockAction->setEnabled(true); @@ -272,7 +272,7 @@ void CoinControlDialog::lockCoin() if (contextMenuItem->checkState(COLUMN_CHECKBOX) == Qt::Checked) contextMenuItem->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); - COutPoint outpt(uint256(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt()); + COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt()); model->lockCoin(outpt); contextMenuItem->setDisabled(true); contextMenuItem->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed")); @@ -282,7 +282,7 @@ void CoinControlDialog::lockCoin() // context menu action: unlock coin void CoinControlDialog::unlockCoin() { - COutPoint outpt(uint256(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt()); + COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt()); model->unlockCoin(outpt); contextMenuItem->setDisabled(false); contextMenuItem->setIcon(COLUMN_CHECKBOX, QIcon()); @@ -388,7 +388,7 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column) { if (column == COLUMN_CHECKBOX && item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode) { - COutPoint outpt(uint256(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt()); + COutPoint outpt(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt()); if (item->checkState(COLUMN_CHECKBOX) == Qt::Unchecked) coinControl->UnSelect(outpt); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 4705c07b8c028..cfc559d19866a 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -278,7 +278,7 @@ Value getblock(const Array& params, bool fHelp) ); std::string strHash = params[0].get_str(); - uint256 hash(strHash); + uint256 hash(uint256S(strHash)); bool fVerbose = true; if (params.size() > 1) @@ -383,7 +383,7 @@ Value gettxout(const Array& params, bool fHelp) Object ret; std::string strHash = params[0].get_str(); - uint256 hash(strHash); + uint256 hash(uint256S(strHash)); int n = params[1].get_int(); bool fMempool = true; if (params.size() > 2) @@ -619,7 +619,7 @@ Value invalidateblock(const Array& params, bool fHelp) ); std::string strHash = params[0].get_str(); - uint256 hash(strHash); + uint256 hash(uint256S(strHash)); CValidationState state; { @@ -658,7 +658,7 @@ Value reconsiderblock(const Array& params, bool fHelp) ); std::string strHash = params[0].get_str(); - uint256 hash(strHash); + uint256 hash(uint256S(strHash)); CValidationState state; { diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 21f6bcae3d726..470a48e4fb435 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1902,7 +1902,7 @@ Value lockunspent(const Array& params, bool fHelp) if (nOutput < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive"); - COutPoint outpt(uint256(txid), nOutput); + COutPoint outpt(uint256S(txid), nOutput); if (fUnlock) pwalletMain->UnlockCoin(outpt); diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 7f8b371d605d3..e979f61f6e727 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1030,7 +1030,7 @@ class CTransactionSignatureSerializer { uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) { - static const uint256 one("0000000000000000000000000000000000000000000000000000000000000001"); + static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); if (nIn >= txTo.vin.size()) { // nIn out of range return one; diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp index 4ea6a91d543e8..a9b6cd44a8720 100644 --- a/src/test/Checkpoints_tests.cpp +++ b/src/test/Checkpoints_tests.cpp @@ -18,8 +18,8 @@ BOOST_AUTO_TEST_SUITE(Checkpoints_tests) BOOST_AUTO_TEST_CASE(sanity) { - uint256 p11111 = uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"); - uint256 p134444 = uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"); + uint256 p11111 = uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"); + uint256 p134444 = uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"); BOOST_CHECK(Checkpoints::CheckBlock(11111, p11111)); BOOST_CHECK(Checkpoints::CheckBlock(134444, p134444)); diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index c32098efa09e3..f9cbcb0d9e544 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -125,7 +125,7 @@ BOOST_AUTO_TEST_CASE(bloom_match) spendStream >> spendingTx; CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL); - filter.insert(uint256("0xb4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b")); + filter.insert(uint256S("0xb4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b")); BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match tx hash"); filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); @@ -151,11 +151,11 @@ BOOST_AUTO_TEST_CASE(bloom_match) BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match output address"); filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); - filter.insert(COutPoint(uint256("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0)); + filter.insert(COutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0)); BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match COutPoint"); filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); - COutPoint prevOutPoint(uint256("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0); + COutPoint prevOutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0); { vector data(32 + sizeof(unsigned int)); memcpy(&data[0], prevOutPoint.hash.begin(), 32); @@ -165,7 +165,7 @@ BOOST_AUTO_TEST_CASE(bloom_match) BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match manually serialized COutPoint"); filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); - filter.insert(uint256("00000009e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436")); + filter.insert(uint256S("00000009e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436")); BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched random tx hash"); filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); @@ -173,11 +173,11 @@ BOOST_AUTO_TEST_CASE(bloom_match) BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched random address"); filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); - filter.insert(COutPoint(uint256("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 1)); + filter.insert(COutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 1)); BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched COutPoint for an output we didn't care about"); filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); - filter.insert(COutPoint(uint256("0x000000d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0)); + filter.insert(COutPoint(uint256S("0x000000d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0)); BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched COutPoint for an output we didn't care about"); } @@ -191,7 +191,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1) CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL); // Match the last transaction - filter.insert(uint256("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20")); + filter.insert(uint256S("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20")); CMerkleBlock merkleBlock(block, filter); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); @@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1) BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); pair pair = merkleBlock.vMatchedTxn[0]; - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20")); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 8); vector vMatched; @@ -209,7 +209,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1) BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second); // Also match the 8th transaction - filter.insert(uint256("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053")); + filter.insert(uint256S("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053")); merkleBlock = CMerkleBlock(block, filter); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); @@ -217,7 +217,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1) BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair); - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053")); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 7); BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); @@ -236,7 +236,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2) CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL); // Match the first transaction - filter.insert(uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); + filter.insert(uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); CMerkleBlock merkleBlock(block, filter); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); @@ -244,7 +244,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2) BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); pair pair = merkleBlock.vMatchedTxn[0]; - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0); vector vMatched; @@ -265,13 +265,13 @@ BOOST_AUTO_TEST_CASE(merkle_block_2) BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]); - BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f")); + BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256S("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f")); BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1); - BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256("0x6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df21bea5f4e27e2")); + BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256S("0x6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df21bea5f4e27e2")); BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 2); - BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23")); + BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256S("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23")); BOOST_CHECK(merkleBlock.vMatchedTxn[3].first == 3); BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); @@ -290,7 +290,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none) CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_NONE); // Match the first transaction - filter.insert(uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); + filter.insert(uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); CMerkleBlock merkleBlock(block, filter); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); @@ -298,7 +298,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none) BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); pair pair = merkleBlock.vMatchedTxn[0]; - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0); vector vMatched; @@ -319,10 +319,10 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none) BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]); - BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f")); + BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256S("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f")); BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1); - BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23")); + BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256S("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23")); BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 3); BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); @@ -341,14 +341,14 @@ BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize) CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL); // Match the only transaction - filter.insert(uint256("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5")); + filter.insert(uint256S("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5")); CMerkleBlock merkleBlock(block, filter); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5")); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0); vector vMatched; @@ -379,7 +379,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_4) CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL); // Match the last transaction - filter.insert(uint256("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154")); + filter.insert(uint256S("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154")); CMerkleBlock merkleBlock(block, filter); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); @@ -387,7 +387,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_4) BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); pair pair = merkleBlock.vMatchedTxn[0]; - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154")); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 6); vector vMatched; @@ -397,13 +397,13 @@ BOOST_AUTO_TEST_CASE(merkle_block_4) BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second); // Also match the 4th transaction - filter.insert(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041")); + filter.insert(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041")); merkleBlock = CMerkleBlock(block, filter); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 2); - BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041")); + BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 3); BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair); @@ -432,9 +432,9 @@ BOOST_AUTO_TEST_CASE(merkle_block_4_test_p2pubkey_only) BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); // We should match the generation outpoint - BOOST_CHECK(filter.contains(COutPoint(uint256("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0))); + BOOST_CHECK(filter.contains(COutPoint(uint256S("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0))); // ... but not the 4th transaction's output (its not pay-2-pubkey) - BOOST_CHECK(!filter.contains(COutPoint(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0))); + BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0))); } BOOST_AUTO_TEST_CASE(merkle_block_4_test_update_none) @@ -455,8 +455,8 @@ BOOST_AUTO_TEST_CASE(merkle_block_4_test_update_none) BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); // We shouldn't match any outpoints (UPDATE_NONE) - BOOST_CHECK(!filter.contains(COutPoint(uint256("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0))); - BOOST_CHECK(!filter.contains(COutPoint(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0))); + BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0))); + BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0))); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 036f70ec0f6f5..662f765a0bd99 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -24,7 +24,7 @@ extern Array read_json(const std::string& jsondata); // Old script.cpp SignatureHash function uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) { - static const uint256 one("0000000000000000000000000000000000000000000000000000000000000001"); + static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); if (nIn >= txTo.vin.size()) { printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 2594f89ac3e19..efa2af917e66f 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -118,7 +118,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) break; } - mapprevOutScriptPubKeys[COutPoint(uint256(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str()); + mapprevOutScriptPubKeys[COutPoint(uint256S(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str()); } if (!fValid) { @@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) break; } - mapprevOutScriptPubKeys[COutPoint(uint256(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str()); + mapprevOutScriptPubKeys[COutPoint(uint256S(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str()); } if (!fValid) { From 734f85c4f0b40efd3f6c0367683c1bab1a2a7b19 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 16 Dec 2014 15:43:03 +0100 Subject: [PATCH 06/12] Use arith_uint256 where necessary Also add conversion from/to uint256 where needed. --- src/chain.h | 5 +++-- src/chainparams.cpp | 4 ++-- src/chainparams.h | 6 +++--- src/key.cpp | 3 ++- src/main.cpp | 9 +++++---- src/miner.cpp | 4 ++-- src/pow.cpp | 15 ++++++++------- src/pow.h | 3 ++- src/rpcmining.cpp | 4 ++-- src/test/pmt_tests.cpp | 12 +++++++++--- src/test/skiplist_tests.cpp | 12 ++++++------ 11 files changed, 44 insertions(+), 33 deletions(-) diff --git a/src/chain.h b/src/chain.h index d7741762c758b..004e87ab527a2 100644 --- a/src/chain.h +++ b/src/chain.h @@ -6,6 +6,7 @@ #ifndef BITCOIN_CHAIN_H #define BITCOIN_CHAIN_H +#include "arith_uint256.h" #include "primitives/block.h" #include "pow.h" #include "tinyformat.h" @@ -117,7 +118,7 @@ class CBlockIndex unsigned int nUndoPos; //! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block - uint256 nChainWork; + arith_uint256 nChainWork; //! Number of transactions in this block. //! Note: in a potential headers-first mode, this number cannot be relied upon @@ -150,7 +151,7 @@ class CBlockIndex nFile = 0; nDataPos = 0; nUndoPos = 0; - nChainWork = uint256(); + nChainWork = arith_uint256(); nTx = 0; nChainTx = 0; nStatus = 0; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 844640061e88d..3abc569dcd7cf 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -114,7 +114,7 @@ class CMainParams : public CChainParams { pchMessageStart[3] = 0xd9; vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); nDefaultPort = 8333; - bnProofOfWorkLimit = ~uint256(0) >> 32; + bnProofOfWorkLimit = ~arith_uint256(0) >> 32; nSubsidyHalvingInterval = 210000; nEnforceBlockUpgradeMajority = 750; nRejectBlockOutdatedMajority = 950; @@ -259,7 +259,7 @@ class CRegTestParams : public CTestNetParams { nMinerThreads = 1; nTargetTimespan = 14 * 24 * 60 * 60; //! two weeks nTargetSpacing = 10 * 60; - bnProofOfWorkLimit = ~uint256(0) >> 1; + bnProofOfWorkLimit = ~arith_uint256(0) >> 1; genesis.nTime = 1296688602; genesis.nBits = 0x207fffff; genesis.nNonce = 2; diff --git a/src/chainparams.h b/src/chainparams.h index 60c7b475856f1..f1ef6a11f19ac 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -10,7 +10,7 @@ #include "checkpoints.h" #include "primitives/block.h" #include "protocol.h" -#include "uint256.h" +#include "arith_uint256.h" #include @@ -45,7 +45,7 @@ class CChainParams const MessageStartChars& MessageStart() const { return pchMessageStart; } const std::vector& AlertKey() const { return vAlertPubKey; } int GetDefaultPort() const { return nDefaultPort; } - const uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; } + const arith_uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; } int SubsidyHalvingInterval() const { return nSubsidyHalvingInterval; } /** Used to check majorities for block version upgrade */ int EnforceBlockUpgradeMajority() const { return nEnforceBlockUpgradeMajority; } @@ -87,7 +87,7 @@ class CChainParams //! Raw pub key bytes for the broadcast alert signing key. std::vector vAlertPubKey; int nDefaultPort; - uint256 bnProofOfWorkLimit; + arith_uint256 bnProofOfWorkLimit; int nSubsidyHalvingInterval; int nEnforceBlockUpgradeMajority; int nRejectBlockOutdatedMajority; diff --git a/src/key.cpp b/src/key.cpp index 50ccb09213c6c..2235c271d18bf 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -4,6 +4,7 @@ #include "key.h" +#include "arith_uint256.h" #include "crypto/hmac_sha512.h" #include "crypto/rfc6979_hmac_sha256.h" #include "eccryptoverify.h" @@ -81,7 +82,7 @@ bool CKey::Sign(const uint256 &hash, std::vector& vchSig, uint32_ do { uint256 nonce; prng.Generate((unsigned char*)&nonce, 32); - nonce += test_case; + nonce = ArithToUint256(UintToArith256(nonce) + test_case); int nSigLen = 72; int ret = secp256k1_ecdsa_sign((const unsigned char*)&hash, (unsigned char*)&vchSig[0], &nSigLen, begin(), (unsigned char*)&nonce); nonce = uint256(); diff --git a/src/main.cpp b/src/main.cpp index 77d2dcb20481a..d115f763f6642 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,7 @@ #include "main.h" +#include "arith_uint256.h" #include "addrman.h" #include "alert.h" #include "chainparams.h" @@ -3607,7 +3608,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (hashSalt.IsNull()) hashSalt = GetRandHash(); uint64_t hashAddr = addr.GetHash(); - uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)); + uint256 hashRand = ArithToUint256(UintToArith256(hashSalt) ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60))); hashRand = Hash(BEGIN(hashRand), END(hashRand)); multimap mapMix; BOOST_FOREACH(CNode* pnode, vNodes) @@ -3616,7 +3617,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, continue; unsigned int nPointer; memcpy(&nPointer, &pnode, sizeof(nPointer)); - uint256 hashKey = hashRand ^ nPointer; + uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer); hashKey = Hash(BEGIN(hashKey), END(hashKey)); mapMix.insert(make_pair(hashKey, pnode)); } @@ -4485,9 +4486,9 @@ bool SendMessages(CNode* pto, bool fSendTrickle) static uint256 hashSalt; if (hashSalt.IsNull()) hashSalt = GetRandHash(); - uint256 hashRand = inv.hash ^ hashSalt; + uint256 hashRand = ArithToUint256(UintToArith256(inv.hash) ^ UintToArith256(hashSalt)); hashRand = Hash(BEGIN(hashRand), END(hashRand)); - bool fTrickleWait = ((hashRand & 3) != 0); + bool fTrickleWait = ((UintToArith256(hashRand) & 3) != 0); if (fTrickleWait) { diff --git a/src/miner.cpp b/src/miner.cpp index 3bd2a9a41fca1..87cb158333e1a 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -481,7 +481,7 @@ void static BitcoinMiner(CWallet *pwallet) // Search // int64_t nStart = GetTime(); - uint256 hashTarget = uint256().SetCompact(pblock->nBits); + arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); uint256 hash; uint32_t nNonce = 0; uint32_t nOldNonce = 0; @@ -493,7 +493,7 @@ void static BitcoinMiner(CWallet *pwallet) // Check if something found if (fFound) { - if (hash <= hashTarget) + if (UintToArith256(hash) <= hashTarget) { // Found a solution pblock->nNonce = nNonce; diff --git a/src/pow.cpp b/src/pow.cpp index e91e3d893c3ff..90bbff0a33a4b 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -5,6 +5,7 @@ #include "pow.h" +#include "arith_uint256.h" #include "chain.h" #include "chainparams.h" #include "primitives/block.h" @@ -56,8 +57,8 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead nActualTimespan = Params().TargetTimespan()*4; // Retarget - uint256 bnNew; - uint256 bnOld; + arith_uint256 bnNew; + arith_uint256 bnOld; bnNew.SetCompact(pindexLast->nBits); bnOld = bnNew; bnNew *= nActualTimespan; @@ -79,7 +80,7 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) { bool fNegative; bool fOverflow; - uint256 bnTarget; + arith_uint256 bnTarget; if (Params().SkipProofOfWorkCheck()) return true; @@ -91,22 +92,22 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) return error("CheckProofOfWork() : nBits below minimum work"); // Check proof of work matches claimed amount - if (hash > bnTarget) + if (UintToArith256(hash) > bnTarget) return error("CheckProofOfWork() : hash doesn't match nBits"); return true; } -uint256 GetBlockProof(const CBlockIndex& block) +arith_uint256 GetBlockProof(const CBlockIndex& block) { - uint256 bnTarget; + arith_uint256 bnTarget; bool fNegative; bool fOverflow; bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); if (fNegative || fOverflow || bnTarget == 0) return 0; // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 - // as it's too large for a uint256. However, as 2**256 is at least as large + // as it's too large for a arith_uint256. However, as 2**256 is at least as large // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1, // or ~bnTarget / (nTarget+1) + 1. return (~bnTarget / (bnTarget + 1)) + 1; diff --git a/src/pow.h b/src/pow.h index 89b219f808f6f..3337a30a5e88d 100644 --- a/src/pow.h +++ b/src/pow.h @@ -11,11 +11,12 @@ class CBlockHeader; class CBlockIndex; class uint256; +class arith_uint256; unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock); /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ bool CheckProofOfWork(uint256 hash, unsigned int nBits); -uint256 GetBlockProof(const CBlockIndex& block); +arith_uint256 GetBlockProof(const CBlockIndex& block); #endif // BITCOIN_POW_H diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 35760f9af087b..603e2935dd9cc 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -64,7 +64,7 @@ Value GetNetworkHashPS(int lookup, int height) { if (minTime == maxTime) return 0; - uint256 workDiff = pb->nChainWork - pb0->nChainWork; + arith_uint256 workDiff = pb->nChainWork - pb0->nChainWork; int64_t timeDiff = maxTime - minTime; return (int64_t)(workDiff.getdouble() / timeDiff); @@ -562,7 +562,7 @@ Value getblocktemplate(const Array& params, bool fHelp) Object aux; aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); - uint256 hashTarget = uint256().SetCompact(pblock->nBits); + arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); static Array aMutable; if (aMutable.empty()) diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index af3d90f2eb142..372cf3b306e7c 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -6,6 +6,7 @@ #include "serialize.h" #include "streams.h" #include "uint256.h" +#include "arith_uint256.h" #include "version.h" #include @@ -22,8 +23,7 @@ class CPartialMerkleTreeTester : public CPartialMerkleTree void Damage() { unsigned int n = rand() % vHash.size(); int bit = rand() % 256; - uint256 &hash = vHash[n]; - hash ^= ((uint256)1 << bit); + *(vHash[n].begin() + (bit>>3)) ^= 1<<(bit&7); } }; @@ -107,7 +107,13 @@ BOOST_AUTO_TEST_CASE(pmt_test1) BOOST_AUTO_TEST_CASE(pmt_malleability) { - std::vector vTxid = boost::assign::list_of(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(9)(10); + std::vector vTxid = boost::assign::list_of + (ArithToUint256(1))(ArithToUint256(2)) + (ArithToUint256(3))(ArithToUint256(4)) + (ArithToUint256(5))(ArithToUint256(6)) + (ArithToUint256(7))(ArithToUint256(8)) + (ArithToUint256(9))(ArithToUint256(10)) + (ArithToUint256(9))(ArithToUint256(10)); std::vector vMatch = boost::assign::list_of(false)(false)(false)(false)(false)(false)(false)(false)(false)(true)(true)(false); CPartialMerkleTree tree(vTxid, vMatch); diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp index 646c7e6adedf8..c75e21a2adf2a 100644 --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.cpp @@ -49,12 +49,12 @@ BOOST_AUTO_TEST_CASE(getlocator_test) std::vector vHashMain(100000); std::vector vBlocksMain(100000); for (unsigned int i=0; inHeight + 1); } @@ -62,12 +62,12 @@ BOOST_AUTO_TEST_CASE(getlocator_test) std::vector vHashSide(50000); std::vector vBlocksSide(50000); for (unsigned int i=0; inHeight + 1); } @@ -87,13 +87,13 @@ BOOST_AUTO_TEST_CASE(getlocator_test) // Entries 1 through 11 (inclusive) go back one step each. for (unsigned int i = 1; i < 12 && i < locator.vHave.size() - 1; i++) { - BOOST_CHECK_EQUAL(locator.vHave[i].GetLow64(), tip->nHeight - i); + BOOST_CHECK_EQUAL(UintToArith256(locator.vHave[i]).GetLow64(), tip->nHeight - i); } // The further ones (excluding the last one) go back with exponential steps. unsigned int dist = 2; for (unsigned int i = 12; i < locator.vHave.size() - 1; i++) { - BOOST_CHECK_EQUAL(locator.vHave[i - 1].GetLow64() - locator.vHave[i].GetLow64(), dist); + BOOST_CHECK_EQUAL(UintToArith256(locator.vHave[i - 1]).GetLow64() - UintToArith256(locator.vHave[i]).GetLow64(), dist); dist *= 2; } } From bfc6070342b9f43bcf125526e6a3c8ed34e29a71 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 15 Dec 2014 10:22:19 +0100 Subject: [PATCH 07/12] uint256->arith_uint256 blob256->uint256 Introduce new opaque implementation of `uint256`, move old "arithmetic" implementation to `arith_uint256. --- src/Makefile.am | 31 +- src/Makefile.test.include | 2 +- src/arith_uint256.cpp | 357 ++++++++++++++++++ src/arith_uint256.h | 351 ++++++++++++++++- ...t256_tests.cpp => arith_uint256_tests.cpp} | 325 ++++++++-------- src/uint256.cpp | 281 ++------------ src/uint256.h | 339 ++++------------- 7 files changed, 985 insertions(+), 701 deletions(-) create mode 100644 src/arith_uint256.cpp rename src/test/{uint256_tests.cpp => arith_uint256_tests.cpp} (75%) diff --git a/src/Makefile.am b/src/Makefile.am index d6ac6e1277627..bc2b1aff963c7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -74,11 +74,12 @@ BITCOIN_CORE_H = \ alert.h \ allocators.h \ amount.h \ + arith_uint256.h \ base58.h \ bloom.h \ chain.h \ - chainparams.h \ chainparamsbase.h \ + chainparams.h \ chainparamsseeds.h \ checkpoints.h \ checkqueue.h \ @@ -87,8 +88,6 @@ BITCOIN_CORE_H = \ coins.h \ compat.h \ compressor.h \ - primitives/block.h \ - primitives/transaction.h \ core_io.h \ crypter.h \ db.h \ @@ -108,6 +107,8 @@ BITCOIN_CORE_H = \ net.h \ noui.h \ pow.h \ + primitives/block.h \ + primitives/transaction.h \ protocol.h \ pubkey.h \ random.h \ @@ -115,11 +116,11 @@ BITCOIN_CORE_H = \ rpcprotocol.h \ rpcserver.h \ script/interpreter.h \ + script/script_error.h \ script/script.h \ script/sigcache.h \ script/sign.h \ script/standard.h \ - script/script_error.h \ serialize.h \ streams.h \ sync.h \ @@ -132,13 +133,13 @@ BITCOIN_CORE_H = \ uint256.h \ undo.h \ util.h \ - utilstrencodings.h \ utilmoneystr.h \ + utilstrencodings.h \ utiltime.h \ version.h \ + walletdb.h \ wallet.h \ wallet_ismine.h \ - walletdb.h \ compat/sanity.h JSON_H = \ @@ -261,18 +262,19 @@ libbitcoin_common_a_SOURCES = \ # backward-compatibility objects and their sanity checks are linked. libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES) libbitcoin_util_a_SOURCES = \ - compat/strnlen.cpp \ - compat/glibc_sanity.cpp \ - compat/glibcxx_sanity.cpp \ + arith_uint256.cpp \ chainparamsbase.cpp \ clientversion.cpp \ + compat/glibc_sanity.cpp \ + compat/glibcxx_sanity.cpp \ + compat/strnlen.cpp \ random.cpp \ rpcprotocol.cpp \ sync.cpp \ uint256.cpp \ util.cpp \ - utilstrencodings.cpp \ utilmoneystr.cpp \ + utilstrencodings.cpp \ utiltime.cpp \ $(BITCOIN_CORE_H) @@ -352,19 +354,20 @@ bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if BUILD_BITCOIN_LIBS include_HEADERS = script/bitcoinconsensus.h libbitcoinconsensus_la_SOURCES = \ - primitives/transaction.cpp \ + arith_uint256.cpp \ crypto/hmac_sha512.cpp \ + crypto/ripemd160.cpp \ crypto/sha1.cpp \ crypto/sha256.cpp \ crypto/sha512.cpp \ - crypto/ripemd160.cpp \ eccryptoverify.cpp \ ecwrapper.cpp \ hash.cpp \ + primitives/transaction.cpp \ pubkey.cpp \ - script/script.cpp \ - script/interpreter.cpp \ script/bitcoinconsensus.cpp \ + script/interpreter.cpp \ + script/script.cpp \ uint256.cpp \ utilstrencodings.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 5f388e2806327..21d91acc6a72c 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -34,6 +34,7 @@ RAW_TEST_FILES = test/data/alertTests.raw GENERATED_TEST_FILES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h) BITCOIN_TESTS =\ + test/arith_uint256_tests.cpp \ test/bignum.h \ test/alert_tests.cpp \ test/allocator_tests.cpp \ @@ -67,7 +68,6 @@ BITCOIN_TESTS =\ test/test_bitcoin.cpp \ test/timedata_tests.cpp \ test/transaction_tests.cpp \ - test/uint256_tests.cpp \ test/univalue_tests.cpp \ test/util_tests.cpp diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp new file mode 100644 index 0000000000000..0dba429a8d519 --- /dev/null +++ b/src/arith_uint256.cpp @@ -0,0 +1,357 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "arith_uint256.h" + +#include "utilstrencodings.h" + +#include +#include + +template +base_uint::base_uint(const std::string& str) +{ + SetHex(str); +} + +template +base_uint::base_uint(const std::vector& vch) +{ + if (vch.size() != sizeof(pn)) + throw uint_error("Converting vector of wrong size to base_uint"); + memcpy(pn, &vch[0], sizeof(pn)); +} + +template +base_uint& 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; +} + +template +base_uint& 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; +} + +template +base_uint& base_uint::operator*=(uint32_t b32) +{ + uint64_t carry = 0; + for (int i = 0; i < WIDTH; i++) { + uint64_t n = carry + (uint64_t)b32 * pn[i]; + pn[i] = n & 0xffffffff; + carry = n >> 32; + } + return *this; +} + +template +base_uint& base_uint::operator*=(const base_uint& b) +{ + base_uint a = *this; + *this = 0; + for (int j = 0; j < WIDTH; j++) { + uint64_t carry = 0; + for (int i = 0; i + j < WIDTH; i++) { + uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i]; + pn[i + j] = n & 0xffffffff; + carry = n >> 32; + } + } + return *this; +} + +template +base_uint& base_uint::operator/=(const base_uint& b) +{ + base_uint div = b; // make a copy, so we can shift. + base_uint num = *this; // make a copy, so we can subtract. + *this = 0; // the quotient. + int num_bits = num.bits(); + int div_bits = div.bits(); + if (div_bits == 0) + throw uint_error("Division by zero"); + if (div_bits > num_bits) // the result is certainly 0. + return *this; + int shift = num_bits - div_bits; + div <<= shift; // shift so that div and num align. + while (shift >= 0) { + if (num >= div) { + num -= div; + pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result. + } + div >>= 1; // shift back. + shift--; + } + // num now contains the remainder of the division. + return *this; +} + +template +int base_uint::CompareTo(const base_uint& b) const +{ + for (int i = WIDTH - 1; i >= 0; i--) { + if (pn[i] < b.pn[i]) + return -1; + if (pn[i] > b.pn[i]) + return 1; + } + return 0; +} + +template +bool base_uint::EqualTo(uint64_t b) const +{ + for (int i = WIDTH - 1; i >= 2; i--) { + if (pn[i]) + return false; + } + if (pn[1] != (b >> 32)) + return false; + if (pn[0] != (b & 0xfffffffful)) + return false; + return true; +} + +template +double base_uint::getdouble() const +{ + double ret = 0.0; + double fact = 1.0; + for (int i = 0; i < WIDTH; i++) { + ret += fact * pn[i]; + fact *= 4294967296.0; + } + return ret; +} + +template +std::string base_uint::GetHex() const +{ + char psz[sizeof(pn) * 2 + 1]; + for (unsigned int i = 0; i < sizeof(pn); i++) + sprintf(psz + i * 2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); + return std::string(psz, psz + sizeof(pn) * 2); +} + +template +void base_uint::SetHex(const char* psz) +{ + memset(pn, 0, sizeof(pn)); + + // skip leading spaces + while (isspace(*psz)) + psz++; + + // skip 0x + if (psz[0] == '0' && tolower(psz[1]) == 'x') + psz += 2; + + // hex string to uint + const char* pbegin = psz; + while (::HexDigit(*psz) != -1) + psz++; + psz--; + unsigned char* p1 = (unsigned char*)pn; + unsigned char* pend = p1 + WIDTH * 4; + while (psz >= pbegin && p1 < pend) { + *p1 = ::HexDigit(*psz--); + if (psz >= pbegin) { + *p1 |= ((unsigned char)::HexDigit(*psz--) << 4); + p1++; + } + } +} + +template +void base_uint::SetHex(const std::string& str) +{ + SetHex(str.c_str()); +} + +template +std::string base_uint::ToString() const +{ + return (GetHex()); +} + +template +unsigned int base_uint::bits() const +{ + for (int pos = WIDTH - 1; pos >= 0; pos--) { + if (pn[pos]) { + for (int bits = 31; bits > 0; bits--) { + if (pn[pos] & 1 << bits) + return 32 * pos + bits + 1; + } + return 32 * pos + 1; + } + } + return 0; +} + +// Explicit instantiations for base_uint<160> +template base_uint<160>::base_uint(const std::string&); +template base_uint<160>::base_uint(const std::vector&); +template base_uint<160>& base_uint<160>::operator<<=(unsigned int); +template base_uint<160>& base_uint<160>::operator>>=(unsigned int); +template base_uint<160>& base_uint<160>::operator*=(uint32_t b32); +template base_uint<160>& base_uint<160>::operator*=(const base_uint<160>& b); +template base_uint<160>& base_uint<160>::operator/=(const base_uint<160>& b); +template int base_uint<160>::CompareTo(const base_uint<160>&) const; +template bool base_uint<160>::EqualTo(uint64_t) const; +template double base_uint<160>::getdouble() const; +template std::string base_uint<160>::GetHex() const; +template std::string base_uint<160>::ToString() const; +template void base_uint<160>::SetHex(const char*); +template void base_uint<160>::SetHex(const std::string&); +template unsigned int base_uint<160>::bits() const; + +// Explicit instantiations for base_uint<256> +template base_uint<256>::base_uint(const std::string&); +template base_uint<256>::base_uint(const std::vector&); +template base_uint<256>& base_uint<256>::operator<<=(unsigned int); +template base_uint<256>& base_uint<256>::operator>>=(unsigned int); +template base_uint<256>& base_uint<256>::operator*=(uint32_t b32); +template base_uint<256>& base_uint<256>::operator*=(const base_uint<256>& b); +template base_uint<256>& base_uint<256>::operator/=(const base_uint<256>& b); +template int base_uint<256>::CompareTo(const base_uint<256>&) const; +template bool base_uint<256>::EqualTo(uint64_t) const; +template double base_uint<256>::getdouble() const; +template std::string base_uint<256>::GetHex() const; +template std::string base_uint<256>::ToString() const; +template void base_uint<256>::SetHex(const char*); +template void base_uint<256>::SetHex(const std::string&); +template unsigned int base_uint<256>::bits() const; + +// This implementation directly uses shifts instead of going +// through an intermediate MPI representation. +arith_uint256& arith_uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow) +{ + int nSize = nCompact >> 24; + uint32_t nWord = nCompact & 0x007fffff; + if (nSize <= 3) { + nWord >>= 8 * (3 - nSize); + *this = nWord; + } else { + *this = nWord; + *this <<= 8 * (nSize - 3); + } + if (pfNegative) + *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0; + if (pfOverflow) + *pfOverflow = nWord != 0 && ((nSize > 34) || + (nWord > 0xff && nSize > 33) || + (nWord > 0xffff && nSize > 32)); + return *this; +} + +uint32_t arith_uint256::GetCompact(bool fNegative) const +{ + int nSize = (bits() + 7) / 8; + uint32_t nCompact = 0; + if (nSize <= 3) { + nCompact = GetLow64() << 8 * (3 - nSize); + } else { + arith_uint256 bn = *this >> 8 * (nSize - 3); + nCompact = bn.GetLow64(); + } + // The 0x00800000 bit denotes the sign. + // Thus, if it is already set, divide the mantissa by 256 and increase the exponent. + if (nCompact & 0x00800000) { + nCompact >>= 8; + nSize++; + } + assert((nCompact & ~0x007fffff) == 0); + assert(nSize < 256); + nCompact |= nSize << 24; + nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0); + return nCompact; +} + +static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c) +{ + // Taken from lookup3, by Bob Jenkins. + a -= c; + a ^= ((c << 4) | (c >> 28)); + c += b; + b -= a; + b ^= ((a << 6) | (a >> 26)); + a += c; + c -= b; + c ^= ((b << 8) | (b >> 24)); + b += a; + a -= c; + a ^= ((c << 16) | (c >> 16)); + c += b; + b -= a; + b ^= ((a << 19) | (a >> 13)); + a += c; + c -= b; + c ^= ((b << 4) | (b >> 28)); + b += a; +} + +static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c) +{ + // Taken from lookup3, by Bob Jenkins. + c ^= b; + c -= ((b << 14) | (b >> 18)); + a ^= c; + a -= ((c << 11) | (c >> 21)); + b ^= a; + b -= ((a << 25) | (a >> 7)); + c ^= b; + c -= ((b << 16) | (b >> 16)); + a ^= c; + a -= ((c << 4) | (c >> 28)); + b ^= a; + b -= ((a << 14) | (a >> 18)); + c ^= b; + c -= ((b << 24) | (b >> 8)); +} + +uint64_t arith_uint256::GetHash(const arith_uint256& salt) const +{ + uint32_t a, b, c; + a = b = c = 0xdeadbeef + (WIDTH << 2); + + a += pn[0] ^ salt.pn[0]; + b += pn[1] ^ salt.pn[1]; + c += pn[2] ^ salt.pn[2]; + HashMix(a, b, c); + a += pn[3] ^ salt.pn[3]; + b += pn[4] ^ salt.pn[4]; + c += pn[5] ^ salt.pn[5]; + HashMix(a, b, c); + a += pn[6] ^ salt.pn[6]; + b += pn[7] ^ salt.pn[7]; + HashFinal(a, b, c); + + return ((((uint64_t)b) << 32) | c); +} diff --git a/src/arith_uint256.h b/src/arith_uint256.h index 3bb384ca8aedd..9e32b124c250e 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -1,19 +1,350 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #ifndef BITCOIN_ARITH_UINT256_H #define BITCOIN_ARITH_UINT256_H -// Temporary for migration to opaque uint160/256 -#include "uint256.h" +#include +#include +#include +#include +#include +#include -class arith_uint256 : public uint256 { +class uint_error : public std::runtime_error { public: - arith_uint256() {} - arith_uint256(const base_uint<256>& b) : uint256(b) {} - arith_uint256(uint64_t b) : uint256(b) {} - explicit arith_uint256(const std::string& str) : uint256(str) {} - explicit arith_uint256(const std::vector& vch) : uint256(vch) {} + explicit uint_error(const std::string& str) : std::runtime_error(str) {} +}; + +/** Template base class for unsigned big integers. */ +template +class base_uint +{ +protected: + enum { WIDTH=BITS/32 }; + uint32_t pn[WIDTH]; +public: + + base_uint() + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + } + + base_uint(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + base_uint& operator=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + base_uint(uint64_t b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + explicit base_uint(const std::string& str); + explicit base_uint(const std::vector& vch); + + 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; + } + + double getdouble() const; + + 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<<=(unsigned int shift); + base_uint& operator>>=(unsigned int shift); + + 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*=(uint32_t b32); + base_uint& operator*=(const base_uint& b); + base_uint& operator/=(const base_uint& b); + + 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] == (uint32_t)-1 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator--(int) + { + // postfix operator + const base_uint ret = *this; + --(*this); + return ret; + } + + int CompareTo(const base_uint& b) const; + bool EqualTo(uint64_t b) const; + + friend inline const base_uint operator+(const base_uint& a, const base_uint& b) { return base_uint(a) += b; } + friend inline const base_uint operator-(const base_uint& a, const base_uint& b) { return base_uint(a) -= b; } + friend inline const base_uint operator*(const base_uint& a, const base_uint& b) { return base_uint(a) *= b; } + friend inline const base_uint operator/(const base_uint& a, const base_uint& b) { return base_uint(a) /= b; } + friend inline const base_uint operator|(const base_uint& a, const base_uint& b) { return base_uint(a) |= b; } + friend inline const base_uint operator&(const base_uint& a, const base_uint& b) { return base_uint(a) &= b; } + friend inline const base_uint operator^(const base_uint& a, const base_uint& b) { return base_uint(a) ^= b; } + friend inline const base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; } + friend inline const base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; } + friend inline const base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; } + friend inline bool operator==(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0; } + friend inline bool operator!=(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) != 0; } + friend inline bool operator>(const base_uint& a, const base_uint& b) { return a.CompareTo(b) > 0; } + friend inline bool operator<(const base_uint& a, const base_uint& b) { return a.CompareTo(b) < 0; } + friend inline bool operator>=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) >= 0; } + friend inline bool operator<=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) <= 0; } + friend inline bool operator==(const base_uint& a, uint64_t b) { return a.EqualTo(b); } + friend inline bool operator!=(const base_uint& a, uint64_t b) { return !a.EqualTo(b); } + + std::string GetHex() const; + void SetHex(const char* psz); + void SetHex(const std::string& str); + std::string ToString() const; + + unsigned char* begin() + { + return (unsigned char*)&pn[0]; + } + + unsigned char* end() + { + return (unsigned char*)&pn[WIDTH]; + } + + const unsigned char* begin() const + { + return (unsigned char*)&pn[0]; + } + + const unsigned char* end() const + { + return (unsigned char*)&pn[WIDTH]; + } + + unsigned int size() const + { + return sizeof(pn); + } + + /** + * Returns the position of the highest bit set plus one, or zero if the + * value is zero. + */ + unsigned int bits() const; + + uint64_t GetLow64() const + { + assert(WIDTH >= 2); + return pn[0] | (uint64_t)pn[1] << 32; + } + + unsigned int GetSerializeSize(int nType, int nVersion) const + { + return sizeof(pn); + } + + template + void Serialize(Stream& s, int nType, int nVersion) const + { + s.write((char*)pn, sizeof(pn)); + } + + template + void Unserialize(Stream& s, int nType, int nVersion) + { + s.read((char*)pn, sizeof(pn)); + } + + // Temporary for migration to blob160/256 + uint64_t GetCheapHash() const + { + return GetLow64(); + } + void SetNull() + { + memset(pn, 0, sizeof(pn)); + } + bool IsNull() const + { + for (int i = 0; i < WIDTH; i++) + if (pn[i] != 0) + return false; + return true; + } }; -#define ArithToUint256(x) (x) -#define UintToArith256(x) (x) +/** 160-bit unsigned big integer. */ +class arith_uint160 : public base_uint<160> { +public: + arith_uint160() {} + arith_uint160(const base_uint<160>& b) : base_uint<160>(b) {} + arith_uint160(uint64_t b) : base_uint<160>(b) {} + explicit arith_uint160(const std::string& str) : base_uint<160>(str) {} + explicit arith_uint160(const std::vector& vch) : base_uint<160>(vch) {} +}; + +/** 256-bit unsigned big integer. */ +class arith_uint256 : public base_uint<256> { +public: + arith_uint256() {} + arith_uint256(const base_uint<256>& b) : base_uint<256>(b) {} + arith_uint256(uint64_t b) : base_uint<256>(b) {} + explicit arith_uint256(const std::string& str) : base_uint<256>(str) {} + explicit arith_uint256(const std::vector& vch) : base_uint<256>(vch) {} + + /** + * The "compact" format is a representation of a whole + * number N using an unsigned 32bit number similar to a + * floating point format. + * The most significant 8 bits are the unsigned exponent of base 256. + * This exponent can be thought of as "number of bytes of N". + * The lower 23 bits are the mantissa. + * Bit number 24 (0x800000) represents the sign of N. + * N = (-1^sign) * mantissa * 256^(exponent-3) + * + * Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn(). + * MPI uses the most significant bit of the first byte as sign. + * Thus 0x1234560000 is compact (0x05123456) + * and 0xc0de000000 is compact (0x0600c0de) + * + * Bitcoin only uses this "compact" format for encoding difficulty + * targets, which are unsigned 256bit quantities. Thus, all the + * complexities of the sign bit and using base 256 are probably an + * implementation accident. + */ + arith_uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL); + uint32_t GetCompact(bool fNegative = false) const; + + uint64_t GetHash(const arith_uint256& salt) const; +}; #endif // BITCOIN_UINT256_H diff --git a/src/test/uint256_tests.cpp b/src/test/arith_uint256_tests.cpp similarity index 75% rename from src/test/uint256_tests.cpp rename to src/test/arith_uint256_tests.cpp index d05b28956c481..f5f71da6147db 100644 --- a/src/test/uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -8,65 +8,65 @@ #include #include #include -#include "uint256.h" +#include "arith_uint256.h" #include #include "version.h" -BOOST_AUTO_TEST_SUITE(uint256_tests) - -const unsigned char R1Array[] = +BOOST_AUTO_TEST_SUITE(arith_uint256_tests) + +const unsigned char R1Array[] = "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2" "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d"; const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c"; const double R1Ldouble = 0.4887374590559308955; // R1L equals roughly R1Ldouble * 2^256 -const double R1Sdouble = 0.7096329412477836074; -const uint256 R1L = uint256(std::vector(R1Array,R1Array+32)); -const uint160 R1S = uint160(std::vector(R1Array,R1Array+20)); +const double R1Sdouble = 0.7096329412477836074; +const arith_uint256 R1L = arith_uint256(std::vector(R1Array,R1Array+32)); +const arith_uint160 R1S = arith_uint160(std::vector(R1Array,R1Array+20)); const uint64_t R1LLow64 = 0x121156cfdb4a529cULL; -const unsigned char R2Array[] = +const unsigned char R2Array[] = "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf" "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7"; -const uint256 R2L = uint256(std::vector(R2Array,R2Array+32)); -const uint160 R2S = uint160(std::vector(R2Array,R2Array+20)); +const arith_uint256 R2L = arith_uint256(std::vector(R2Array,R2Array+32)); +const arith_uint160 R2S = arith_uint160(std::vector(R2Array,R2Array+20)); const char R1LplusR2L[] = "549FB09FEA236A1EA3E31D4D58F1B1369288D204211CA751527CFC175767850C"; -const unsigned char ZeroArray[] = +const unsigned char ZeroArray[] = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; -const uint256 ZeroL = uint256(std::vector(ZeroArray,ZeroArray+32)); -const uint160 ZeroS = uint160(std::vector(ZeroArray,ZeroArray+20)); - -const unsigned char OneArray[] = +const arith_uint256 ZeroL = arith_uint256(std::vector(ZeroArray,ZeroArray+32)); +const arith_uint160 ZeroS = arith_uint160(std::vector(ZeroArray,ZeroArray+20)); + +const unsigned char OneArray[] = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; -const uint256 OneL = uint256(std::vector(OneArray,OneArray+32)); -const uint160 OneS = uint160(std::vector(OneArray,OneArray+20)); +const arith_uint256 OneL = arith_uint256(std::vector(OneArray,OneArray+32)); +const arith_uint160 OneS = arith_uint160(std::vector(OneArray,OneArray+20)); -const unsigned char MaxArray[] = +const unsigned char MaxArray[] = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; -const uint256 MaxL = uint256(std::vector(MaxArray,MaxArray+32)); -const uint160 MaxS = uint160(std::vector(MaxArray,MaxArray+20)); +const arith_uint256 MaxL = arith_uint256(std::vector(MaxArray,MaxArray+32)); +const arith_uint160 MaxS = arith_uint160(std::vector(MaxArray,MaxArray+20)); -const uint256 HalfL = (OneL << 255); -const uint160 HalfS = (OneS << 159); +const arith_uint256 HalfL = (OneL << 255); +const arith_uint160 HalfS = (OneS << 159); std::string ArrayToString(const unsigned char A[], unsigned int width) { std::stringstream Stream; Stream << std::hex; - for (unsigned int i = 0; i < width; ++i) + for (unsigned int i = 0; i < width; ++i) { Stream<): + // constructor arith_uint256(vector): BOOST_CHECK(R1L.ToString() == ArrayToString(R1Array,32)); BOOST_CHECK(R1S.ToString() == ArrayToString(R1Array,20)); BOOST_CHECK(R2L.ToString() == ArrayToString(R2Array,32)); @@ -88,104 +88,104 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality BOOST_CHECK(~MaxL == ZeroL && ~MaxS == ZeroS); BOOST_CHECK( ((R1L ^ R2L) ^ R1L) == R2L); BOOST_CHECK( ((R1S ^ R2S) ^ R1S) == R2S); - + uint64_t Tmp64 = 0xc4dab720d9c7acaaULL; - for (unsigned int i = 0; i < 256; ++i) + for (unsigned int i = 0; i < 256; ++i) { - BOOST_CHECK(ZeroL != (OneL << i)); - BOOST_CHECK((OneL << i) != ZeroL); + BOOST_CHECK(ZeroL != (OneL << i)); + BOOST_CHECK((OneL << i) != ZeroL); BOOST_CHECK(R1L != (R1L ^ (OneL << i))); - BOOST_CHECK(((uint256(Tmp64) ^ (OneL << i) ) != Tmp64 )); + BOOST_CHECK(((arith_uint256(Tmp64) ^ (OneL << i) ) != Tmp64 )); } - BOOST_CHECK(ZeroL == (OneL << 256)); + BOOST_CHECK(ZeroL == (OneL << 256)); - for (unsigned int i = 0; i < 160; ++i) + for (unsigned int i = 0; i < 160; ++i) { - BOOST_CHECK(ZeroS != (OneS << i)); - BOOST_CHECK((OneS << i) != ZeroS); + BOOST_CHECK(ZeroS != (OneS << i)); + BOOST_CHECK((OneS << i) != ZeroS); BOOST_CHECK(R1S != (R1S ^ (OneS << i))); - BOOST_CHECK(((uint160(Tmp64) ^ (OneS << i) ) != Tmp64 )); + BOOST_CHECK(((arith_uint160(Tmp64) ^ (OneS << i) ) != Tmp64 )); } - BOOST_CHECK(ZeroS == (OneS << 256)); + BOOST_CHECK(ZeroS == (OneS << 256)); // String Constructor and Copy Constructor - BOOST_CHECK(uint256("0x"+R1L.ToString()) == R1L); - BOOST_CHECK(uint256("0x"+R2L.ToString()) == R2L); - BOOST_CHECK(uint256("0x"+ZeroL.ToString()) == ZeroL); - BOOST_CHECK(uint256("0x"+OneL.ToString()) == OneL); - BOOST_CHECK(uint256("0x"+MaxL.ToString()) == MaxL); - BOOST_CHECK(uint256(R1L.ToString()) == R1L); - BOOST_CHECK(uint256(" 0x"+R1L.ToString()+" ") == R1L); - BOOST_CHECK(uint256("") == ZeroL); - BOOST_CHECK(R1L == uint256(R1ArrayHex)); - BOOST_CHECK(uint256(R1L) == R1L); - BOOST_CHECK((uint256(R1L^R2L)^R2L) == R1L); - BOOST_CHECK(uint256(ZeroL) == ZeroL); - BOOST_CHECK(uint256(OneL) == OneL); - - BOOST_CHECK(uint160("0x"+R1S.ToString()) == R1S); - BOOST_CHECK(uint160("0x"+R2S.ToString()) == R2S); - BOOST_CHECK(uint160("0x"+ZeroS.ToString()) == ZeroS); - BOOST_CHECK(uint160("0x"+OneS.ToString()) == OneS); - BOOST_CHECK(uint160("0x"+MaxS.ToString()) == MaxS); - BOOST_CHECK(uint160(R1S.ToString()) == R1S); - BOOST_CHECK(uint160(" 0x"+R1S.ToString()+" ") == R1S); - BOOST_CHECK(uint160("") == ZeroS); - BOOST_CHECK(R1S == uint160(R1ArrayHex)); - - BOOST_CHECK(uint160(R1S) == R1S); - BOOST_CHECK((uint160(R1S^R2S)^R2S) == R1S); - BOOST_CHECK(uint160(ZeroS) == ZeroS); - BOOST_CHECK(uint160(OneS) == OneS); + BOOST_CHECK(arith_uint256("0x"+R1L.ToString()) == R1L); + BOOST_CHECK(arith_uint256("0x"+R2L.ToString()) == R2L); + BOOST_CHECK(arith_uint256("0x"+ZeroL.ToString()) == ZeroL); + BOOST_CHECK(arith_uint256("0x"+OneL.ToString()) == OneL); + BOOST_CHECK(arith_uint256("0x"+MaxL.ToString()) == MaxL); + BOOST_CHECK(arith_uint256(R1L.ToString()) == R1L); + BOOST_CHECK(arith_uint256(" 0x"+R1L.ToString()+" ") == R1L); + BOOST_CHECK(arith_uint256("") == ZeroL); + BOOST_CHECK(R1L == arith_uint256(R1ArrayHex)); + BOOST_CHECK(arith_uint256(R1L) == R1L); + BOOST_CHECK((arith_uint256(R1L^R2L)^R2L) == R1L); + BOOST_CHECK(arith_uint256(ZeroL) == ZeroL); + BOOST_CHECK(arith_uint256(OneL) == OneL); + + BOOST_CHECK(arith_uint160("0x"+R1S.ToString()) == R1S); + BOOST_CHECK(arith_uint160("0x"+R2S.ToString()) == R2S); + BOOST_CHECK(arith_uint160("0x"+ZeroS.ToString()) == ZeroS); + BOOST_CHECK(arith_uint160("0x"+OneS.ToString()) == OneS); + BOOST_CHECK(arith_uint160("0x"+MaxS.ToString()) == MaxS); + BOOST_CHECK(arith_uint160(R1S.ToString()) == R1S); + BOOST_CHECK(arith_uint160(" 0x"+R1S.ToString()+" ") == R1S); + BOOST_CHECK(arith_uint160("") == ZeroS); + BOOST_CHECK(R1S == arith_uint160(R1ArrayHex)); + + BOOST_CHECK(arith_uint160(R1S) == R1S); + BOOST_CHECK((arith_uint160(R1S^R2S)^R2S) == R1S); + BOOST_CHECK(arith_uint160(ZeroS) == ZeroS); + BOOST_CHECK(arith_uint160(OneS) == OneS); // uint64_t constructor - BOOST_CHECK( (R1L & uint256("0xffffffffffffffff")) == uint256(R1LLow64)); - BOOST_CHECK(ZeroL == uint256(0)); - BOOST_CHECK(OneL == uint256(1)); - BOOST_CHECK(uint256("0xffffffffffffffff") = uint256(0xffffffffffffffffULL)); - BOOST_CHECK( (R1S & uint160("0xffffffffffffffff")) == uint160(R1LLow64)); - BOOST_CHECK(ZeroS == uint160(0)); - BOOST_CHECK(OneS == uint160(1)); - BOOST_CHECK(uint160("0xffffffffffffffff") = uint160(0xffffffffffffffffULL)); + BOOST_CHECK( (R1L & arith_uint256("0xffffffffffffffff")) == arith_uint256(R1LLow64)); + BOOST_CHECK(ZeroL == arith_uint256(0)); + BOOST_CHECK(OneL == arith_uint256(1)); + BOOST_CHECK(arith_uint256("0xffffffffffffffff") = arith_uint256(0xffffffffffffffffULL)); + BOOST_CHECK( (R1S & arith_uint160("0xffffffffffffffff")) == arith_uint160(R1LLow64)); + BOOST_CHECK(ZeroS == arith_uint160(0)); + BOOST_CHECK(OneS == arith_uint160(1)); + BOOST_CHECK(arith_uint160("0xffffffffffffffff") = arith_uint160(0xffffffffffffffffULL)); // Assignment (from base_uint) - uint256 tmpL = ~ZeroL; BOOST_CHECK(tmpL == ~ZeroL); + arith_uint256 tmpL = ~ZeroL; BOOST_CHECK(tmpL == ~ZeroL); tmpL = ~OneL; BOOST_CHECK(tmpL == ~OneL); tmpL = ~R1L; BOOST_CHECK(tmpL == ~R1L); tmpL = ~R2L; BOOST_CHECK(tmpL == ~R2L); tmpL = ~MaxL; BOOST_CHECK(tmpL == ~MaxL); - uint160 tmpS = ~ZeroS; BOOST_CHECK(tmpS == ~ZeroS); + arith_uint160 tmpS = ~ZeroS; BOOST_CHECK(tmpS == ~ZeroS); tmpS = ~OneS; BOOST_CHECK(tmpS == ~OneS); tmpS = ~R1S; BOOST_CHECK(tmpS == ~R1S); tmpS = ~R2S; BOOST_CHECK(tmpS == ~R2S); tmpS = ~MaxS; BOOST_CHECK(tmpS == ~MaxS); // Wrong length must throw exception. - BOOST_CHECK_THROW(uint256(std::vector(OneArray,OneArray+31)), uint_error); - BOOST_CHECK_THROW(uint256(std::vector(OneArray,OneArray+20)), uint_error); - BOOST_CHECK_THROW(uint160(std::vector(OneArray,OneArray+32)), uint_error); - BOOST_CHECK_THROW(uint160(std::vector(OneArray,OneArray+19)), uint_error); + BOOST_CHECK_THROW(arith_uint256(std::vector(OneArray,OneArray+31)), uint_error); + BOOST_CHECK_THROW(arith_uint256(std::vector(OneArray,OneArray+20)), uint_error); + BOOST_CHECK_THROW(arith_uint160(std::vector(OneArray,OneArray+32)), uint_error); + BOOST_CHECK_THROW(arith_uint160(std::vector(OneArray,OneArray+19)), uint_error); } -void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift) +void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift) { - for (unsigned int T=0; T < arrayLength; ++T) + for (unsigned int T=0; T < arrayLength; ++T) { unsigned int F = (T+bitsToShift/8); - if (F < arrayLength) + if (F < arrayLength) to[T] = from[F] >> (bitsToShift%8); else to[T] = 0; - if (F + 1 < arrayLength) + if (F + 1 < arrayLength) to[T] |= from[(F+1)] << (8-bitsToShift%8); } } -void shiftArrayLeft(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift) +void shiftArrayLeft(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift) { - for (unsigned int T=0; T < arrayLength; ++T) + for (unsigned int T=0; T < arrayLength; ++T) { - if (T >= bitsToShift/8) + if (T >= bitsToShift/8) { unsigned int F = T-bitsToShift/8; to[T] = from[F] << (bitsToShift%8); @@ -200,39 +200,39 @@ void shiftArrayLeft(unsigned char* to, const unsigned char* from, unsigned int a BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>=" unsigned char TmpArray[32]; - uint256 TmpL; + arith_uint256 TmpL; for (unsigned int i = 0; i < 256; ++i) { shiftArrayLeft(TmpArray, OneArray, 32, i); - BOOST_CHECK(uint256(std::vector(TmpArray,TmpArray+32)) == (OneL << i)); + BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (OneL << i)); TmpL = OneL; TmpL <<= i; BOOST_CHECK(TmpL == (OneL << i)); BOOST_CHECK((HalfL >> (255-i)) == (OneL << i)); TmpL = HalfL; TmpL >>= (255-i); BOOST_CHECK(TmpL == (OneL << i)); - + shiftArrayLeft(TmpArray, R1Array, 32, i); - BOOST_CHECK(uint256(std::vector(TmpArray,TmpArray+32)) == (R1L << i)); + BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (R1L << i)); TmpL = R1L; TmpL <<= i; BOOST_CHECK(TmpL == (R1L << i)); shiftArrayRight(TmpArray, R1Array, 32, i); - BOOST_CHECK(uint256(std::vector(TmpArray,TmpArray+32)) == (R1L >> i)); + BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (R1L >> i)); TmpL = R1L; TmpL >>= i; BOOST_CHECK(TmpL == (R1L >> i)); shiftArrayLeft(TmpArray, MaxArray, 32, i); - BOOST_CHECK(uint256(std::vector(TmpArray,TmpArray+32)) == (MaxL << i)); + BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (MaxL << i)); TmpL = MaxL; TmpL <<= i; BOOST_CHECK(TmpL == (MaxL << i)); shiftArrayRight(TmpArray, MaxArray, 32, i); - BOOST_CHECK(uint256(std::vector(TmpArray,TmpArray+32)) == (MaxL >> i)); + BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (MaxL >> i)); TmpL = MaxL; TmpL >>= i; BOOST_CHECK(TmpL == (MaxL >> i)); } - uint256 c1L = uint256(0x0123456789abcdefULL); - uint256 c2L = c1L << 128; + arith_uint256 c1L = arith_uint256(0x0123456789abcdefULL); + arith_uint256 c2L = c1L << 128; for (unsigned int i = 0; i < 128; ++i) { BOOST_CHECK((c1L << i) == (c2L >> (128-i))); } @@ -240,39 +240,39 @@ BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>=" BOOST_CHECK((c1L << i) == (c2L << (i-128))); } - uint160 TmpS; + arith_uint160 TmpS; for (unsigned int i = 0; i < 160; ++i) { shiftArrayLeft(TmpArray, OneArray, 20, i); - BOOST_CHECK(uint160(std::vector(TmpArray,TmpArray+20)) == (OneS << i)); + BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (OneS << i)); TmpS = OneS; TmpS <<= i; BOOST_CHECK(TmpS == (OneS << i)); BOOST_CHECK((HalfS >> (159-i)) == (OneS << i)); TmpS = HalfS; TmpS >>= (159-i); BOOST_CHECK(TmpS == (OneS << i)); - + shiftArrayLeft(TmpArray, R1Array, 20, i); - BOOST_CHECK(uint160(std::vector(TmpArray,TmpArray+20)) == (R1S << i)); + BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (R1S << i)); TmpS = R1S; TmpS <<= i; BOOST_CHECK(TmpS == (R1S << i)); shiftArrayRight(TmpArray, R1Array, 20, i); - BOOST_CHECK(uint160(std::vector(TmpArray,TmpArray+20)) == (R1S >> i)); + BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (R1S >> i)); TmpS = R1S; TmpS >>= i; BOOST_CHECK(TmpS == (R1S >> i)); shiftArrayLeft(TmpArray, MaxArray, 20, i); - BOOST_CHECK(uint160(std::vector(TmpArray,TmpArray+20)) == (MaxS << i)); + BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (MaxS << i)); TmpS = MaxS; TmpS <<= i; BOOST_CHECK(TmpS == (MaxS << i)); shiftArrayRight(TmpArray, MaxArray, 20, i); - BOOST_CHECK(uint160(std::vector(TmpArray,TmpArray+20)) == (MaxS >> i)); + BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (MaxS >> i)); TmpS = MaxS; TmpS >>= i; BOOST_CHECK(TmpS == (MaxS >> i)); } - uint160 c1S = uint160(0x0123456789abcdefULL); - uint160 c2S = c1S << 80; + arith_uint160 c1S = arith_uint160(0x0123456789abcdefULL); + arith_uint160 c2S = c1S << 80; for (unsigned int i = 0; i < 80; ++i) { BOOST_CHECK((c1S << i) == (c2S >> (80-i))); } @@ -285,47 +285,47 @@ BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ - { BOOST_CHECK(!ZeroL); BOOST_CHECK(!ZeroS); BOOST_CHECK(!(!OneL));BOOST_CHECK(!(!OneS)); - for (unsigned int i = 0; i < 256; ++i) + for (unsigned int i = 0; i < 256; ++i) BOOST_CHECK(!(!(OneL<(TmpArray,TmpArray+32)) == (~R1L)); - BOOST_CHECK(uint160(std::vector(TmpArray,TmpArray+20)) == (~R1S)); + for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = ~R1Array[i]; } + BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (~R1L)); + BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (~R1S)); BOOST_CHECK(-ZeroL == ZeroL); BOOST_CHECK(-ZeroS == ZeroS); BOOST_CHECK(-R1L == (~R1L)+1); BOOST_CHECK(-R1S == (~R1S)+1); - for (unsigned int i = 0; i < 256; ++i) + for (unsigned int i = 0; i < 256; ++i) BOOST_CHECK(-(OneL<(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); \ + BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); \ for (unsigned int i = 0; i < 20; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \ - BOOST_CHECK(uint160(std::vector(TmpArray,TmpArray+20)) == (_A_##S _OP_ _B_##S)); + BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (_A_##S _OP_ _B_##S)); #define CHECKASSIGNMENTOPERATOR(_A_,_B_,_OP_) \ TmpL = _A_##L; TmpL _OP_##= _B_##L; BOOST_CHECK(TmpL == (_A_##L _OP_ _B_##L)); \ TmpS = _A_##S; TmpS _OP_##= _B_##S; BOOST_CHECK(TmpS == (_A_##S _OP_ _B_##S)); -BOOST_AUTO_TEST_CASE( bitwiseOperators ) +BOOST_AUTO_TEST_CASE( bitwiseOperators ) { unsigned char TmpArray[32]; - + CHECKBITWISEOPERATOR(R1,R2,|) CHECKBITWISEOPERATOR(R1,R2,^) CHECKBITWISEOPERATOR(R1,R2,&) @@ -342,8 +342,8 @@ BOOST_AUTO_TEST_CASE( bitwiseOperators ) CHECKBITWISEOPERATOR(Max,R1,^) CHECKBITWISEOPERATOR(Max,R1,&) - uint256 TmpL; - uint160 TmpS; + arith_uint256 TmpL; + arith_uint160 TmpS; CHECKASSIGNMENTOPERATOR(R1,R2,|) CHECKASSIGNMENTOPERATOR(R1,R2,^) CHECKASSIGNMENTOPERATOR(R1,R2,&) @@ -360,20 +360,20 @@ BOOST_AUTO_TEST_CASE( bitwiseOperators ) CHECKASSIGNMENTOPERATOR(Max,R1,^) CHECKASSIGNMENTOPERATOR(Max,R1,&) - uint64_t Tmp64 = 0xe1db685c9a0b47a2ULL; - TmpL = R1L; TmpL |= Tmp64; BOOST_CHECK(TmpL == (R1L | uint256(Tmp64))); - TmpS = R1S; TmpS |= Tmp64; BOOST_CHECK(TmpS == (R1S | uint160(Tmp64))); + uint64_t Tmp64 = 0xe1db685c9a0b47a2ULL; + TmpL = R1L; TmpL |= Tmp64; BOOST_CHECK(TmpL == (R1L | arith_uint256(Tmp64))); + TmpS = R1S; TmpS |= Tmp64; BOOST_CHECK(TmpS == (R1S | arith_uint160(Tmp64))); TmpL = R1L; TmpL |= 0; BOOST_CHECK(TmpL == R1L); TmpS = R1S; TmpS |= 0; BOOST_CHECK(TmpS == R1S); TmpL ^= 0; BOOST_CHECK(TmpL == R1L); TmpS ^= 0; BOOST_CHECK(TmpS == R1S); - TmpL ^= Tmp64; BOOST_CHECK(TmpL == (R1L ^ uint256(Tmp64))); - TmpS ^= Tmp64; BOOST_CHECK(TmpS == (R1S ^ uint160(Tmp64))); + TmpL ^= Tmp64; BOOST_CHECK(TmpL == (R1L ^ arith_uint256(Tmp64))); + TmpS ^= Tmp64; BOOST_CHECK(TmpS == (R1S ^ arith_uint160(Tmp64))); } BOOST_AUTO_TEST_CASE( comparison ) // <= >= < > { - uint256 TmpL; + arith_uint256 TmpL; for (unsigned int i = 0; i < 256; ++i) { TmpL= OneL<< i; BOOST_CHECK( TmpL >= ZeroL && TmpL > ZeroL && ZeroL < TmpL && ZeroL <= TmpL); @@ -383,7 +383,7 @@ BOOST_AUTO_TEST_CASE( comparison ) // <= >= < > BOOST_CHECK( R1L <= TmpL ); BOOST_CHECK( (R1L == TmpL) != (R1L < TmpL)); BOOST_CHECK( (TmpL == R1L) || !( R1L >= TmpL)); BOOST_CHECK(! (TmpL < R1L)); BOOST_CHECK(! (R1L > TmpL)); } - uint160 TmpS; + arith_uint160 TmpS; for (unsigned int i = 0; i < 160; ++i) { TmpS= OneS<< i; BOOST_CHECK( TmpS >= ZeroS && TmpS > ZeroS && ZeroS < TmpS && ZeroS <= TmpS); @@ -395,10 +395,10 @@ BOOST_AUTO_TEST_CASE( comparison ) // <= >= < > } } -BOOST_AUTO_TEST_CASE( plusMinus ) +BOOST_AUTO_TEST_CASE( plusMinus ) { - uint256 TmpL = 0; - BOOST_CHECK(R1L+R2L == uint256(R1LplusR2L)); + arith_uint256 TmpL = 0; + BOOST_CHECK(R1L+R2L == arith_uint256(R1LplusR2L)); TmpL += R1L; BOOST_CHECK(TmpL == R1L); TmpL += R2L; @@ -412,13 +412,13 @@ BOOST_AUTO_TEST_CASE( plusMinus ) BOOST_CHECK( TmpL == (HalfL >> (i-1)) ); TmpL = (MaxL>>i); TmpL += 1; BOOST_CHECK( TmpL == (HalfL >> (i-1)) ); - TmpL = (MaxL>>i); + TmpL = (MaxL>>i); BOOST_CHECK( TmpL++ == (MaxL>>i) ); BOOST_CHECK( TmpL == (HalfL >> (i-1))); } - BOOST_CHECK(uint256(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == uint256(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL)); - TmpL = uint256(0xbedc77e27940a7ULL); TmpL += 0xee8d836fce66fbULL; - BOOST_CHECK(TmpL == uint256(0xbedc77e27940a7ULL+0xee8d836fce66fbULL)); + BOOST_CHECK(arith_uint256(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == arith_uint256(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL)); + TmpL = arith_uint256(0xbedc77e27940a7ULL); TmpL += 0xee8d836fce66fbULL; + BOOST_CHECK(TmpL == arith_uint256(0xbedc77e27940a7ULL+0xee8d836fce66fbULL)); TmpL -= 0xee8d836fce66fbULL; BOOST_CHECK(TmpL == 0xbedc77e27940a7ULL); TmpL = R1L; BOOST_CHECK(++TmpL == R1L+1); @@ -439,8 +439,8 @@ BOOST_AUTO_TEST_CASE( plusMinus ) BOOST_CHECK(--TmpL == R1L-1); // 160-bit; copy-pasted - uint160 TmpS = 0; - BOOST_CHECK(R1S+R2S == uint160(R1LplusR2L)); + arith_uint160 TmpS = 0; + BOOST_CHECK(R1S+R2S == arith_uint160(R1LplusR2L)); TmpS += R1S; BOOST_CHECK(TmpS == R1S); TmpS += R2S; @@ -454,13 +454,13 @@ BOOST_AUTO_TEST_CASE( plusMinus ) BOOST_CHECK( TmpS == (HalfS >> (i-1)) ); TmpS = (MaxS>>i); TmpS += 1; BOOST_CHECK( TmpS == (HalfS >> (i-1)) ); - TmpS = (MaxS>>i); + TmpS = (MaxS>>i); BOOST_CHECK( TmpS++ == (MaxS>>i) ); BOOST_CHECK( TmpS == (HalfS >> (i-1))); } - BOOST_CHECK(uint160(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == uint160(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL)); - TmpS = uint160(0xbedc77e27940a7ULL); TmpS += 0xee8d836fce66fbULL; - BOOST_CHECK(TmpS == uint160(0xbedc77e27940a7ULL+0xee8d836fce66fbULL)); + BOOST_CHECK(arith_uint160(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == arith_uint160(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL)); + TmpS = arith_uint160(0xbedc77e27940a7ULL); TmpS += 0xee8d836fce66fbULL; + BOOST_CHECK(TmpS == arith_uint160(0xbedc77e27940a7ULL+0xee8d836fce66fbULL)); TmpS -= 0xee8d836fce66fbULL; BOOST_CHECK(TmpS == 0xbedc77e27940a7ULL); TmpS = R1S; BOOST_CHECK(++TmpS == R1S+1); @@ -521,8 +521,8 @@ BOOST_AUTO_TEST_CASE( multiply ) BOOST_AUTO_TEST_CASE( divide ) { - uint256 D1L("AD7133AC1977FA2B7"); - uint256 D2L("ECD751716"); + arith_uint256 D1L("AD7133AC1977FA2B7"); + arith_uint256 D2L("ECD751716"); BOOST_CHECK((R1L / D1L).ToString() == "00000000000000000b8ac01106981635d9ed112290f8895545a7654dde28fb3a"); BOOST_CHECK((R1L / D2L).ToString() == "000000000873ce8efec5b67150bad3aa8c5fcb70e947586153bf2cec7c37c57a"); BOOST_CHECK(R1L / OneL == R1L); @@ -536,8 +536,8 @@ BOOST_AUTO_TEST_CASE( divide ) BOOST_CHECK(MaxL / R2L == 1); BOOST_CHECK_THROW(R2L / ZeroL, uint_error); - uint160 D1S("D3C5EDCDEA54EB92679F0A4B4"); - uint160 D2S("13037"); + arith_uint160 D1S("D3C5EDCDEA54EB92679F0A4B4"); + arith_uint160 D2S("13037"); BOOST_CHECK((R1S / D1S).ToString() == "0000000000000000000000000db9af3beade6c02"); BOOST_CHECK((R1S / D2S).ToString() == "000098dfb6cc40ca592bf74366794f298ada205c"); BOOST_CHECK(R1S / OneS == R1S); @@ -553,7 +553,7 @@ BOOST_AUTO_TEST_CASE( divide ) } -bool almostEqual(double d1, double d2) +bool almostEqual(double d1, double d2) { return fabs(d1-d2) <= 4*fabs(d1)*std::numeric_limits::epsilon(); } @@ -564,7 +564,7 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G BOOST_CHECK(R2L.GetHex() == R2L.ToString()); BOOST_CHECK(OneL.GetHex() == OneL.ToString()); BOOST_CHECK(MaxL.GetHex() == MaxL.ToString()); - uint256 TmpL(R1L); + arith_uint256 TmpL(R1L); BOOST_CHECK(TmpL == R1L); TmpL.SetHex(R2L.ToString()); BOOST_CHECK(TmpL == R2L); TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK(TmpL == 0); @@ -612,7 +612,7 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G BOOST_CHECK(R2S.GetHex() == R2S.ToString()); BOOST_CHECK(OneS.GetHex() == OneS.ToString()); BOOST_CHECK(MaxS.GetHex() == MaxS.ToString()); - uint160 TmpS(R1S); + arith_uint160 TmpS(R1S); BOOST_CHECK(TmpS == R1S); TmpS.SetHex(R2S.ToString()); BOOST_CHECK(TmpS == R2S); TmpS.SetHex(ZeroS.ToString()); BOOST_CHECK(TmpS == 0); @@ -634,7 +634,7 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G BOOST_CHECK(MaxS.begin() + 20 == MaxS.end()); BOOST_CHECK(TmpS.begin() + 20 == TmpS.end()); BOOST_CHECK(R1S.GetLow64() == R1LLow64); - BOOST_CHECK(HalfS.GetLow64() ==0x0000000000000000ULL); + BOOST_CHECK(HalfS.GetLow64() ==0x0000000000000000ULL); BOOST_CHECK(OneS.GetLow64() ==0x0000000000000001ULL); BOOST_CHECK(R1S.GetSerializeSize(0,PROTOCOL_VERSION) == 20); BOOST_CHECK(ZeroS.GetSerializeSize(0,PROTOCOL_VERSION) == 20); @@ -654,17 +654,17 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G TmpS.Unserialize(ss,0,PROTOCOL_VERSION); BOOST_CHECK(MaxS == TmpS); ss.str(""); - - for (unsigned int i = 0; i < 255; ++i) + + for (unsigned int i = 0; i < 255; ++i) { BOOST_CHECK((OneL << i).getdouble() == ldexp(1.0,i)); if (i < 160) BOOST_CHECK((OneS << i).getdouble() == ldexp(1.0,i)); } BOOST_CHECK(ZeroL.getdouble() == 0.0); BOOST_CHECK(ZeroS.getdouble() == 0.0); - for (int i = 256; i > 53; --i) + for (int i = 256; i > 53; --i) BOOST_CHECK(almostEqual((R1L>>(256-i)).getdouble(), ldexp(R1Ldouble,i))); - for (int i = 160; i > 53; --i) + for (int i = 160; i > 53; --i) BOOST_CHECK(almostEqual((R1S>>(160-i)).getdouble(), ldexp(R1Sdouble,i))); uint64_t R1L64part = (R1L>>192).GetLow64(); uint64_t R1S64part = (R1S>>96).GetLow64(); @@ -677,7 +677,7 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G BOOST_AUTO_TEST_CASE(bignum_SetCompact) { - uint256 num; + arith_uint256 num; bool fNegative; bool fOverflow; num.SetCompact(0, &fNegative, &fOverflow); @@ -809,21 +809,21 @@ BOOST_AUTO_TEST_CASE( getmaxcoverage ) // some more tests just to get 100% cover // ~R1L give a base_uint<256> BOOST_CHECK((~~R1L >> 10) == (R1L >> 10)); BOOST_CHECK((~~R1S >> 10) == (R1S >> 10)); BOOST_CHECK((~~R1L << 10) == (R1L << 10)); BOOST_CHECK((~~R1S << 10) == (R1S << 10)); - BOOST_CHECK(!(~~R1L < R1L)); BOOST_CHECK(!(~~R1S < R1S)); - BOOST_CHECK(~~R1L <= R1L); BOOST_CHECK(~~R1S <= R1S); - BOOST_CHECK(!(~~R1L > R1L)); BOOST_CHECK(!(~~R1S > R1S)); - BOOST_CHECK(~~R1L >= R1L); BOOST_CHECK(~~R1S >= R1S); - BOOST_CHECK(!(R1L < ~~R1L)); BOOST_CHECK(!(R1S < ~~R1S)); - BOOST_CHECK(R1L <= ~~R1L); BOOST_CHECK(R1S <= ~~R1S); - BOOST_CHECK(!(R1L > ~~R1L)); BOOST_CHECK(!(R1S > ~~R1S)); - BOOST_CHECK(R1L >= ~~R1L); BOOST_CHECK(R1S >= ~~R1S); - + BOOST_CHECK(!(~~R1L < R1L)); BOOST_CHECK(!(~~R1S < R1S)); + BOOST_CHECK(~~R1L <= R1L); BOOST_CHECK(~~R1S <= R1S); + BOOST_CHECK(!(~~R1L > R1L)); BOOST_CHECK(!(~~R1S > R1S)); + BOOST_CHECK(~~R1L >= R1L); BOOST_CHECK(~~R1S >= R1S); + BOOST_CHECK(!(R1L < ~~R1L)); BOOST_CHECK(!(R1S < ~~R1S)); + BOOST_CHECK(R1L <= ~~R1L); BOOST_CHECK(R1S <= ~~R1S); + BOOST_CHECK(!(R1L > ~~R1L)); BOOST_CHECK(!(R1S > ~~R1S)); + BOOST_CHECK(R1L >= ~~R1L); BOOST_CHECK(R1S >= ~~R1S); + BOOST_CHECK(~~R1L + R2L == R1L + ~~R2L); BOOST_CHECK(~~R1S + R2S == R1S + ~~R2S); BOOST_CHECK(~~R1L - R2L == R1L - ~~R2L); BOOST_CHECK(~~R1S - R2S == R1S - ~~R2S); - BOOST_CHECK(~R1L != R1L); BOOST_CHECK(R1L != ~R1L); - BOOST_CHECK(~R1S != R1S); BOOST_CHECK(R1S != ~R1S); + BOOST_CHECK(~R1L != R1L); BOOST_CHECK(R1L != ~R1L); + BOOST_CHECK(~R1S != R1S); BOOST_CHECK(R1S != ~R1S); unsigned char TmpArray[32]; CHECKBITWISEOPERATOR(~R1,R2,|) CHECKBITWISEOPERATOR(~R1,R2,^) @@ -834,4 +834,3 @@ BOOST_AUTO_TEST_CASE( getmaxcoverage ) // some more tests just to get 100% cover } BOOST_AUTO_TEST_SUITE_END() - diff --git a/src/uint256.cpp b/src/uint256.cpp index 918c1a7cd7bd5..3b1334a032438 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -11,158 +11,25 @@ #include template -base_uint::base_uint(const std::string& str) +base_blob::base_blob(const std::vector& vch) { - SetHex(str); + assert(vch.size() == sizeof(data)); + memcpy(data, &vch[0], sizeof(data)); } template -base_uint::base_uint(const std::vector& vch) +std::string base_blob::GetHex() const { - if (vch.size() != sizeof(pn)) - throw uint_error("Converting vector of wrong size to base_uint"); - memcpy(pn, &vch[0], sizeof(pn)); + char psz[sizeof(data) * 2 + 1]; + for (unsigned int i = 0; i < sizeof(data); i++) + sprintf(psz + i * 2, "%02x", data[sizeof(data) - i - 1]); + return std::string(psz, psz + sizeof(data) * 2); } template -base_uint& base_uint::operator<<=(unsigned int shift) +void base_blob::SetHex(const char* psz) { - 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; -} - -template -base_uint& 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; -} - -template -base_uint& base_uint::operator*=(uint32_t b32) -{ - uint64_t carry = 0; - for (int i = 0; i < WIDTH; i++) { - uint64_t n = carry + (uint64_t)b32 * pn[i]; - pn[i] = n & 0xffffffff; - carry = n >> 32; - } - return *this; -} - -template -base_uint& base_uint::operator*=(const base_uint& b) -{ - base_uint a = *this; - *this = 0; - for (int j = 0; j < WIDTH; j++) { - uint64_t carry = 0; - for (int i = 0; i + j < WIDTH; i++) { - uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i]; - pn[i + j] = n & 0xffffffff; - carry = n >> 32; - } - } - return *this; -} - -template -base_uint& base_uint::operator/=(const base_uint& b) -{ - base_uint div = b; // make a copy, so we can shift. - base_uint num = *this; // make a copy, so we can subtract. - *this = 0; // the quotient. - int num_bits = num.bits(); - int div_bits = div.bits(); - if (div_bits == 0) - throw uint_error("Division by zero"); - if (div_bits > num_bits) // the result is certainly 0. - return *this; - int shift = num_bits - div_bits; - div <<= shift; // shift so that div and num align. - while (shift >= 0) { - if (num >= div) { - num -= div; - pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result. - } - div >>= 1; // shift back. - shift--; - } - // num now contains the remainder of the division. - return *this; -} - -template -int base_uint::CompareTo(const base_uint& b) const -{ - for (int i = WIDTH - 1; i >= 0; i--) { - if (pn[i] < b.pn[i]) - return -1; - if (pn[i] > b.pn[i]) - return 1; - } - return 0; -} - -template -bool base_uint::EqualTo(uint64_t b) const -{ - for (int i = WIDTH - 1; i >= 2; i--) { - if (pn[i]) - return false; - } - if (pn[1] != (b >> 32)) - return false; - if (pn[0] != (b & 0xfffffffful)) - return false; - return true; -} - -template -double base_uint::getdouble() const -{ - double ret = 0.0; - double fact = 1.0; - for (int i = 0; i < WIDTH; i++) { - ret += fact * pn[i]; - fact *= 4294967296.0; - } - return ret; -} - -template -std::string base_uint::GetHex() const -{ - char psz[sizeof(pn) * 2 + 1]; - for (unsigned int i = 0; i < sizeof(pn); i++) - sprintf(psz + i * 2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); - return std::string(psz, psz + sizeof(pn) * 2); -} - -template -void base_uint::SetHex(const char* psz) -{ - memset(pn, 0, sizeof(pn)); + memset(data, 0, sizeof(data)); // skip leading spaces while (isspace(*psz)) @@ -177,7 +44,7 @@ void base_uint::SetHex(const char* psz) while (::HexDigit(*psz) != -1) psz++; psz--; - unsigned char* p1 = (unsigned char*)pn; + unsigned char* p1 = (unsigned char*)data; unsigned char* pend = p1 + WIDTH * 4; while (psz >= pbegin && p1 < pend) { *p1 = ::HexDigit(*psz--); @@ -189,110 +56,30 @@ void base_uint::SetHex(const char* psz) } template -void base_uint::SetHex(const std::string& str) +void base_blob::SetHex(const std::string& str) { SetHex(str.c_str()); } template -std::string base_uint::ToString() const +std::string base_blob::ToString() const { return (GetHex()); } -template -unsigned int base_uint::bits() const -{ - for (int pos = WIDTH - 1; pos >= 0; pos--) { - if (pn[pos]) { - for (int bits = 31; bits > 0; bits--) { - if (pn[pos] & 1 << bits) - return 32 * pos + bits + 1; - } - return 32 * pos + 1; - } - } - return 0; -} - -// Explicit instantiations for base_uint<160> -template base_uint<160>::base_uint(const std::string&); -template base_uint<160>::base_uint(const std::vector&); -template base_uint<160>& base_uint<160>::operator<<=(unsigned int); -template base_uint<160>& base_uint<160>::operator>>=(unsigned int); -template base_uint<160>& base_uint<160>::operator*=(uint32_t b32); -template base_uint<160>& base_uint<160>::operator*=(const base_uint<160>& b); -template base_uint<160>& base_uint<160>::operator/=(const base_uint<160>& b); -template int base_uint<160>::CompareTo(const base_uint<160>&) const; -template bool base_uint<160>::EqualTo(uint64_t) const; -template double base_uint<160>::getdouble() const; -template std::string base_uint<160>::GetHex() const; -template std::string base_uint<160>::ToString() const; -template void base_uint<160>::SetHex(const char*); -template void base_uint<160>::SetHex(const std::string&); -template unsigned int base_uint<160>::bits() const; +// Explicit instantiations for base_blob<160> +template base_blob<160>::base_blob(const std::vector&); +template std::string base_blob<160>::GetHex() const; +template std::string base_blob<160>::ToString() const; +template void base_blob<160>::SetHex(const char*); +template void base_blob<160>::SetHex(const std::string&); -// Explicit instantiations for base_uint<256> -template base_uint<256>::base_uint(const std::string&); -template base_uint<256>::base_uint(const std::vector&); -template base_uint<256>& base_uint<256>::operator<<=(unsigned int); -template base_uint<256>& base_uint<256>::operator>>=(unsigned int); -template base_uint<256>& base_uint<256>::operator*=(uint32_t b32); -template base_uint<256>& base_uint<256>::operator*=(const base_uint<256>& b); -template base_uint<256>& base_uint<256>::operator/=(const base_uint<256>& b); -template int base_uint<256>::CompareTo(const base_uint<256>&) const; -template bool base_uint<256>::EqualTo(uint64_t) const; -template double base_uint<256>::getdouble() const; -template std::string base_uint<256>::GetHex() const; -template std::string base_uint<256>::ToString() const; -template void base_uint<256>::SetHex(const char*); -template void base_uint<256>::SetHex(const std::string&); -template unsigned int base_uint<256>::bits() const; - -// This implementation directly uses shifts instead of going -// through an intermediate MPI representation. -uint256& uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow) -{ - int nSize = nCompact >> 24; - uint32_t nWord = nCompact & 0x007fffff; - if (nSize <= 3) { - nWord >>= 8 * (3 - nSize); - *this = nWord; - } else { - *this = nWord; - *this <<= 8 * (nSize - 3); - } - if (pfNegative) - *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0; - if (pfOverflow) - *pfOverflow = nWord != 0 && ((nSize > 34) || - (nWord > 0xff && nSize > 33) || - (nWord > 0xffff && nSize > 32)); - return *this; -} - -uint32_t uint256::GetCompact(bool fNegative) const -{ - int nSize = (bits() + 7) / 8; - uint32_t nCompact = 0; - if (nSize <= 3) { - nCompact = GetLow64() << 8 * (3 - nSize); - } else { - uint256 bn = *this >> 8 * (nSize - 3); - nCompact = bn.GetLow64(); - } - // The 0x00800000 bit denotes the sign. - // Thus, if it is already set, divide the mantissa by 256 and increase the exponent. - if (nCompact & 0x00800000) { - nCompact >>= 8; - nSize++; - } - assert((nCompact & ~0x007fffff) == 0); - assert(nSize < 256); - nCompact |= nSize << 24; - nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0); - return nCompact; -} +// Explicit instantiations for base_blob<256> +template base_blob<256>::base_blob(const std::vector&); +template std::string base_blob<256>::GetHex() const; +template std::string base_blob<256>::ToString() const; +template void base_blob<256>::SetHex(const char*); +template void base_blob<256>::SetHex(const std::string&); static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c) { @@ -339,18 +126,20 @@ static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c) uint64_t uint256::GetHash(const uint256& salt) const { uint32_t a, b, c; + const uint32_t *pn = (const uint32_t*)data; + const uint32_t *salt_pn = (const uint32_t*)salt.data; a = b = c = 0xdeadbeef + (WIDTH << 2); - a += pn[0] ^ salt.pn[0]; - b += pn[1] ^ salt.pn[1]; - c += pn[2] ^ salt.pn[2]; + a += pn[0] ^ salt_pn[0]; + b += pn[1] ^ salt_pn[1]; + c += pn[2] ^ salt_pn[2]; HashMix(a, b, c); - a += pn[3] ^ salt.pn[3]; - b += pn[4] ^ salt.pn[4]; - c += pn[5] ^ salt.pn[5]; + a += pn[3] ^ salt_pn[3]; + b += pn[4] ^ salt_pn[4]; + c += pn[5] ^ salt_pn[5]; HashMix(a, b, c); - a += pn[6] ^ salt.pn[6]; - b += pn[7] ^ salt.pn[7]; + a += pn[6] ^ salt_pn[6]; + b += pn[7] ^ salt_pn[7]; HashFinal(a, b, c); return ((((uint64_t)b) << 32) | c); diff --git a/src/uint256.h b/src/uint256.h index 8189b27cb3c88..6d016ab164867 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -13,217 +13,37 @@ #include #include -class uint_error : public std::runtime_error { -public: - explicit uint_error(const std::string& str) : std::runtime_error(str) {} -}; - -/** Template base class for unsigned big integers. */ +/** Template base class for fixed-sized opaque blobs. */ template -class base_uint +class base_blob { protected: - enum { WIDTH=BITS/32 }; - uint32_t pn[WIDTH]; + enum { WIDTH=BITS/8 }; + uint8_t data[WIDTH]; public: - - base_uint() + base_blob() { - for (int i = 0; i < WIDTH; i++) - pn[i] = 0; + memset(data, 0, sizeof(data)); } - base_uint(const base_uint& b) - { - for (int i = 0; i < WIDTH; i++) - pn[i] = b.pn[i]; - } - - base_uint& operator=(const base_uint& b) - { - for (int i = 0; i < WIDTH; i++) - pn[i] = b.pn[i]; - return *this; - } + explicit base_blob(const std::vector& vch); - base_uint(uint64_t b) - { - pn[0] = (unsigned int)b; - pn[1] = (unsigned int)(b >> 32); - for (int i = 2; i < WIDTH; i++) - pn[i] = 0; - } - - explicit base_uint(const std::string& str); - explicit base_uint(const std::vector& vch); - - bool operator!() const + bool IsNull() const { for (int i = 0; i < WIDTH; i++) - if (pn[i] != 0) + if (data[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; - } - - double getdouble() const; - - 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<<=(unsigned int shift); - base_uint& operator>>=(unsigned int shift); - - 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*=(uint32_t b32); - base_uint& operator*=(const base_uint& b); - base_uint& operator/=(const base_uint& b); - - 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] == (uint32_t)-1 && i < WIDTH-1) - i++; - return *this; - } - - const base_uint operator--(int) + void SetNull() { - // postfix operator - const base_uint ret = *this; - --(*this); - return ret; + memset(data, 0, sizeof(data)); } - int CompareTo(const base_uint& b) const; - bool EqualTo(uint64_t b) const; - - friend inline const base_uint operator+(const base_uint& a, const base_uint& b) { return base_uint(a) += b; } - friend inline const base_uint operator-(const base_uint& a, const base_uint& b) { return base_uint(a) -= b; } - friend inline const base_uint operator*(const base_uint& a, const base_uint& b) { return base_uint(a) *= b; } - friend inline const base_uint operator/(const base_uint& a, const base_uint& b) { return base_uint(a) /= b; } - friend inline const base_uint operator|(const base_uint& a, const base_uint& b) { return base_uint(a) |= b; } - friend inline const base_uint operator&(const base_uint& a, const base_uint& b) { return base_uint(a) &= b; } - friend inline const base_uint operator^(const base_uint& a, const base_uint& b) { return base_uint(a) ^= b; } - friend inline const base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; } - friend inline const base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; } - friend inline const base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; } - friend inline bool operator==(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0; } - friend inline bool operator!=(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) != 0; } - friend inline bool operator>(const base_uint& a, const base_uint& b) { return a.CompareTo(b) > 0; } - friend inline bool operator<(const base_uint& a, const base_uint& b) { return a.CompareTo(b) < 0; } - friend inline bool operator>=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) >= 0; } - friend inline bool operator<=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) <= 0; } - friend inline bool operator==(const base_uint& a, uint64_t b) { return a.EqualTo(b); } - friend inline bool operator!=(const base_uint& a, uint64_t b) { return !a.EqualTo(b); } + friend inline bool operator==(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) == 0; } + friend inline bool operator!=(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) != 0; } + friend inline bool operator<(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) < 0; } std::string GetHex() const; void SetHex(const char* psz); @@ -232,122 +52,107 @@ class base_uint unsigned char* begin() { - return (unsigned char*)&pn[0]; + return &data[0]; } unsigned char* end() { - return (unsigned char*)&pn[WIDTH]; + return &data[WIDTH]; } const unsigned char* begin() const { - return (unsigned char*)&pn[0]; + return &data[0]; } const unsigned char* end() const { - return (unsigned char*)&pn[WIDTH]; + return &data[WIDTH]; } unsigned int size() const { - return sizeof(pn); - } - - /** - * Returns the position of the highest bit set plus one, or zero if the - * value is zero. - */ - unsigned int bits() const; - - uint64_t GetLow64() const - { - assert(WIDTH >= 2); - return pn[0] | (uint64_t)pn[1] << 32; + return sizeof(data); } unsigned int GetSerializeSize(int nType, int nVersion) const { - return sizeof(pn); + return sizeof(data); } template void Serialize(Stream& s, int nType, int nVersion) const { - s.write((char*)pn, sizeof(pn)); + s.write((char*)data, sizeof(data)); } template void Unserialize(Stream& s, int nType, int nVersion) { - s.read((char*)pn, sizeof(pn)); - } - - // Temporary for migration to opaque uint160/256 - uint64_t GetCheapHash() const - { - return GetLow64(); - } - void SetNull() - { - memset(pn, 0, sizeof(pn)); - } - bool IsNull() const - { - for (int i = 0; i < WIDTH; i++) - if (pn[i] != 0) - return false; - return true; + s.read((char*)data, sizeof(data)); } }; -/** 160-bit unsigned big integer. */ -class uint160 : public base_uint<160> { +/** 160-bit opaque blob. + * @note This type is called uint160 for historical reasons only. It is an opaque + * blob of 160 bits and has no integer operations. + */ +class uint160 : public base_blob<160> { public: uint160() {} - uint160(const base_uint<160>& b) : base_uint<160>(b) {} - uint160(uint64_t b) : base_uint<160>(b) {} - explicit uint160(const std::string& str) : base_uint<160>(str) {} - explicit uint160(const std::vector& vch) : base_uint<160>(vch) {} + uint160(const base_blob<160>& b) : base_blob<160>(b) {} + explicit uint160(const std::vector& vch) : base_blob<160>(vch) {} }; -/** 256-bit unsigned big integer. */ -class uint256 : public base_uint<256> { +/** 256-bit opaque blob. + * @note This type is called uint256 for historical reasons only. It is an + * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if + * those are required. + */ +class uint256 : public base_blob<256> { public: uint256() {} - uint256(const base_uint<256>& b) : base_uint<256>(b) {} - uint256(uint64_t b) : base_uint<256>(b) {} - explicit uint256(const std::string& str) : base_uint<256>(str) {} - explicit uint256(const std::vector& vch) : base_uint<256>(vch) {} - - /** - * The "compact" format is a representation of a whole - * number N using an unsigned 32bit number similar to a - * floating point format. - * The most significant 8 bits are the unsigned exponent of base 256. - * This exponent can be thought of as "number of bytes of N". - * The lower 23 bits are the mantissa. - * Bit number 24 (0x800000) represents the sign of N. - * N = (-1^sign) * mantissa * 256^(exponent-3) - * - * Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn(). - * MPI uses the most significant bit of the first byte as sign. - * Thus 0x1234560000 is compact (0x05123456) - * and 0xc0de000000 is compact (0x0600c0de) - * - * Bitcoin only uses this "compact" format for encoding difficulty - * targets, which are unsigned 256bit quantities. Thus, all the - * complexities of the sign bit and using base 256 are probably an - * implementation accident. + uint256(const base_blob<256>& b) : base_blob<256>(b) {} + explicit uint256(const std::vector& vch) : base_blob<256>(vch) {} + + /** A cheap hash function that just returns 64 bits from the result, it can be + * used when the contents are considered uniformly random. It is not appropriate + * when the value can easily be influenced from outside as e.g. a network adversary could + * provide values to trigger worst-case behavior. + * @note The result of this function is not stable between little and big endian. */ - uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL); - uint32_t GetCompact(bool fNegative = false) const; + uint64_t GetCheapHash() const + { + uint64_t result; + memcpy((void*)&result, (void*)data, 8); + return result; + } + /** A more secure, salted hash function. + * @note This hash is not stable between little and big endian. + */ uint64_t GetHash(const uint256& salt) const; }; -// Temporary for migration to opaque uint160/256 -inline uint256 uint256S(const std::string &x) { return uint256(x); } +/* uint256 from const char *. + * This is a separate function because the constructor uint256(const char*) can result + * in dangerously catching uint256(0). + */ +inline uint256 uint256S(const char *str) +{ + uint256 rv; + rv.SetHex(str); + return rv; +} +/* uint256 from std::string. + * This is a separate function because the constructor uint256(const std::string &str) can result + * in dangerously catching uint256(0) via std::string(const char*). + */ +inline uint256 uint256S(const std::string& str) +{ + uint256 rv; + rv.SetHex(str); + return rv; +} #endif // BITCOIN_UINT256_H From 92cdb1aace3c7343e9c9472061508d3b01d9883d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 16 Dec 2014 17:29:51 +0100 Subject: [PATCH 08/12] Add conversion functions arith_uint256<->uint_256 --- src/arith_uint256.cpp | 16 ++++++++++++++++ src/arith_uint256.h | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp index 0dba429a8d519..f0b6a6a3bdef3 100644 --- a/src/arith_uint256.cpp +++ b/src/arith_uint256.cpp @@ -5,6 +5,7 @@ #include "arith_uint256.h" +#include "uint256.h" #include "utilstrencodings.h" #include @@ -355,3 +356,18 @@ uint64_t arith_uint256::GetHash(const arith_uint256& salt) const return ((((uint64_t)b) << 32) | c); } + +uint256 ArithToUint256(const arith_uint256 &a) +{ + uint256 b; + // TODO: needs bswap32 on big-endian + memcpy(b.begin(), a.pn, a.size()); + return b; +} +arith_uint256 UintToArith256(const uint256 &a) +{ + arith_uint256 b; + // TODO: needs bswap32 on big-endian + memcpy(b.pn, a.begin(), a.size()); + return b; +} diff --git a/src/arith_uint256.h b/src/arith_uint256.h index 9e32b124c250e..5cb04f3c3caf2 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -13,6 +13,8 @@ #include #include +class uint256; + class uint_error : public std::runtime_error { public: explicit uint_error(const std::string& str) : std::runtime_error(str) {} @@ -345,6 +347,12 @@ class arith_uint256 : public base_uint<256> { uint32_t GetCompact(bool fNegative = false) const; uint64_t GetHash(const arith_uint256& salt) const; + + friend uint256 ArithToUint256(const arith_uint256 &); + friend arith_uint256 UintToArith256(const uint256 &); }; +uint256 ArithToUint256(const arith_uint256 &); +arith_uint256 UintToArith256(const uint256 &); + #endif // BITCOIN_UINT256_H From dba2e9141a4f07154829bdaed35adaf7af7908d3 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 16 Dec 2014 15:50:31 +0100 Subject: [PATCH 09/12] Add tests for new uint256 --- src/Makefile.test.include | 1 + src/test/uint256_tests.cpp | 268 +++++++++++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 src/test/uint256_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 21d91acc6a72c..2f10702d86fb8 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -68,6 +68,7 @@ BITCOIN_TESTS =\ test/test_bitcoin.cpp \ test/timedata_tests.cpp \ test/transaction_tests.cpp \ + test/uint256_tests.cpp \ test/univalue_tests.cpp \ test/util_tests.cpp diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp new file mode 100644 index 0000000000000..5b33846ba9467 --- /dev/null +++ b/src/test/uint256_tests.cpp @@ -0,0 +1,268 @@ +// Copyright (c) 2011-2013 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "arith_uint256.h" +#include "uint256.h" +#include "version.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +BOOST_AUTO_TEST_SUITE(uint256_tests) + +const unsigned char R1Array[] = + "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2" + "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d"; +const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c"; +const uint256 R1L = uint256(std::vector(R1Array,R1Array+32)); +const uint160 R1S = uint160(std::vector(R1Array,R1Array+20)); + +const unsigned char R2Array[] = + "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf" + "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7"; +const uint256 R2L = uint256(std::vector(R2Array,R2Array+32)); +const uint160 R2S = uint160(std::vector(R2Array,R2Array+20)); + +const unsigned char ZeroArray[] = + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; +const uint256 ZeroL = uint256(std::vector(ZeroArray,ZeroArray+32)); +const uint160 ZeroS = uint160(std::vector(ZeroArray,ZeroArray+20)); + +const unsigned char OneArray[] = + "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; +const uint256 OneL = uint256(std::vector(OneArray,OneArray+32)); +const uint160 OneS = uint160(std::vector(OneArray,OneArray+20)); + +const unsigned char MaxArray[] = + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; +const uint256 MaxL = uint256(std::vector(MaxArray,MaxArray+32)); +const uint160 MaxS = uint160(std::vector(MaxArray,MaxArray+20)); + +std::string ArrayToString(const unsigned char A[], unsigned int width) +{ + std::stringstream Stream; + Stream << std::hex; + for (unsigned int i = 0; i < width; ++i) + { + Stream<): + BOOST_CHECK(R1L.ToString() == ArrayToString(R1Array,32)); + BOOST_CHECK(R1S.ToString() == ArrayToString(R1Array,20)); + BOOST_CHECK(R2L.ToString() == ArrayToString(R2Array,32)); + BOOST_CHECK(R2S.ToString() == ArrayToString(R2Array,20)); + BOOST_CHECK(ZeroL.ToString() == ArrayToString(ZeroArray,32)); + BOOST_CHECK(ZeroS.ToString() == ArrayToString(ZeroArray,20)); + BOOST_CHECK(OneL.ToString() == ArrayToString(OneArray,32)); + BOOST_CHECK(OneS.ToString() == ArrayToString(OneArray,20)); + BOOST_CHECK(MaxL.ToString() == ArrayToString(MaxArray,32)); + BOOST_CHECK(MaxS.ToString() == ArrayToString(MaxArray,20)); + BOOST_CHECK(OneL.ToString() != ArrayToString(ZeroArray,32)); + BOOST_CHECK(OneS.ToString() != ArrayToString(ZeroArray,20)); + + // == and != + BOOST_CHECK(R1L != R2L && R1S != R2S); + BOOST_CHECK(ZeroL != OneL && ZeroS != OneS); + BOOST_CHECK(OneL != ZeroL && OneS != ZeroS); + BOOST_CHECK(MaxL != ZeroL && MaxS != ZeroS); + + // String Constructor and Copy Constructor + BOOST_CHECK(uint256S("0x"+R1L.ToString()) == R1L); + BOOST_CHECK(uint256S("0x"+R2L.ToString()) == R2L); + BOOST_CHECK(uint256S("0x"+ZeroL.ToString()) == ZeroL); + BOOST_CHECK(uint256S("0x"+OneL.ToString()) == OneL); + BOOST_CHECK(uint256S("0x"+MaxL.ToString()) == MaxL); + BOOST_CHECK(uint256S(R1L.ToString()) == R1L); + BOOST_CHECK(uint256S(" 0x"+R1L.ToString()+" ") == R1L); + BOOST_CHECK(uint256S("") == ZeroL); + BOOST_CHECK(R1L == uint256S(R1ArrayHex)); + BOOST_CHECK(uint256(R1L) == R1L); + BOOST_CHECK(uint256(ZeroL) == ZeroL); + BOOST_CHECK(uint256(OneL) == OneL); + + BOOST_CHECK(uint160S("0x"+R1S.ToString()) == R1S); + BOOST_CHECK(uint160S("0x"+R2S.ToString()) == R2S); + BOOST_CHECK(uint160S("0x"+ZeroS.ToString()) == ZeroS); + BOOST_CHECK(uint160S("0x"+OneS.ToString()) == OneS); + BOOST_CHECK(uint160S("0x"+MaxS.ToString()) == MaxS); + BOOST_CHECK(uint160S(R1S.ToString()) == R1S); + BOOST_CHECK(uint160S(" 0x"+R1S.ToString()+" ") == R1S); + BOOST_CHECK(uint160S("") == ZeroS); + BOOST_CHECK(R1S == uint160S(R1ArrayHex)); + + BOOST_CHECK(uint160(R1S) == R1S); + BOOST_CHECK(uint160(ZeroS) == ZeroS); + BOOST_CHECK(uint160(OneS) == OneS); +} + +BOOST_AUTO_TEST_CASE( comparison ) // <= >= < > +{ + uint256 LastL; + for (int i = 255; i >= 0; --i) { + uint256 TmpL; + *(TmpL.begin() + (i>>3)) |= 1<<(7-(i&7)); + BOOST_CHECK( LastL < TmpL ); + LastL = TmpL; + } + + BOOST_CHECK( ZeroL < R1L ); + BOOST_CHECK( R2L < R1L ); + BOOST_CHECK( ZeroL < OneL ); + BOOST_CHECK( OneL < MaxL ); + BOOST_CHECK( R1L < MaxL ); + BOOST_CHECK( R2L < MaxL ); + + uint160 LastS; + for (int i = 159; i >= 0; --i) { + uint160 TmpS; + *(TmpS.begin() + (i>>3)) |= 1<<(7-(i&7)); + BOOST_CHECK( LastS < TmpS ); + LastS = TmpS; + } + BOOST_CHECK( ZeroS < R1S ); + BOOST_CHECK( R2S < R1S ); + BOOST_CHECK( ZeroS < OneS ); + BOOST_CHECK( OneS < MaxS ); + BOOST_CHECK( R1S < MaxS ); + BOOST_CHECK( R2S < MaxS ); +} + +BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 GetSerializeSize, Serialize, Unserialize +{ + BOOST_CHECK(R1L.GetHex() == R1L.ToString()); + BOOST_CHECK(R2L.GetHex() == R2L.ToString()); + BOOST_CHECK(OneL.GetHex() == OneL.ToString()); + BOOST_CHECK(MaxL.GetHex() == MaxL.ToString()); + uint256 TmpL(R1L); + BOOST_CHECK(TmpL == R1L); + TmpL.SetHex(R2L.ToString()); BOOST_CHECK(TmpL == R2L); + TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK(TmpL == uint256()); + + TmpL.SetHex(R1L.ToString()); + BOOST_CHECK(memcmp(R1L.begin(), R1Array, 32)==0); + BOOST_CHECK(memcmp(TmpL.begin(), R1Array, 32)==0); + BOOST_CHECK(memcmp(R2L.begin(), R2Array, 32)==0); + BOOST_CHECK(memcmp(ZeroL.begin(), ZeroArray, 32)==0); + BOOST_CHECK(memcmp(OneL.begin(), OneArray, 32)==0); + BOOST_CHECK(R1L.size() == sizeof(R1L)); + BOOST_CHECK(sizeof(R1L) == 32); + BOOST_CHECK(R1L.size() == 32); + BOOST_CHECK(R2L.size() == 32); + BOOST_CHECK(ZeroL.size() == 32); + BOOST_CHECK(MaxL.size() == 32); + BOOST_CHECK(R1L.begin() + 32 == R1L.end()); + BOOST_CHECK(R2L.begin() + 32 == R2L.end()); + BOOST_CHECK(OneL.begin() + 32 == OneL.end()); + BOOST_CHECK(MaxL.begin() + 32 == MaxL.end()); + BOOST_CHECK(TmpL.begin() + 32 == TmpL.end()); + BOOST_CHECK(R1L.GetSerializeSize(0,PROTOCOL_VERSION) == 32); + BOOST_CHECK(ZeroL.GetSerializeSize(0,PROTOCOL_VERSION) == 32); + + std::stringstream ss; + R1L.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(R1Array,R1Array+32)); + TmpL.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(R1L == TmpL); + ss.str(""); + ZeroL.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(ZeroArray,ZeroArray+32)); + TmpL.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ZeroL == TmpL); + ss.str(""); + MaxL.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(MaxArray,MaxArray+32)); + TmpL.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(MaxL == TmpL); + ss.str(""); + + BOOST_CHECK(R1S.GetHex() == R1S.ToString()); + BOOST_CHECK(R2S.GetHex() == R2S.ToString()); + BOOST_CHECK(OneS.GetHex() == OneS.ToString()); + BOOST_CHECK(MaxS.GetHex() == MaxS.ToString()); + uint160 TmpS(R1S); + BOOST_CHECK(TmpS == R1S); + TmpS.SetHex(R2S.ToString()); BOOST_CHECK(TmpS == R2S); + TmpS.SetHex(ZeroS.ToString()); BOOST_CHECK(TmpS == uint160()); + + TmpS.SetHex(R1S.ToString()); + BOOST_CHECK(memcmp(R1S.begin(), R1Array, 20)==0); + BOOST_CHECK(memcmp(TmpS.begin(), R1Array, 20)==0); + BOOST_CHECK(memcmp(R2S.begin(), R2Array, 20)==0); + BOOST_CHECK(memcmp(ZeroS.begin(), ZeroArray, 20)==0); + BOOST_CHECK(memcmp(OneS.begin(), OneArray, 20)==0); + BOOST_CHECK(R1S.size() == sizeof(R1S)); + BOOST_CHECK(sizeof(R1S) == 20); + BOOST_CHECK(R1S.size() == 20); + BOOST_CHECK(R2S.size() == 20); + BOOST_CHECK(ZeroS.size() == 20); + BOOST_CHECK(MaxS.size() == 20); + BOOST_CHECK(R1S.begin() + 20 == R1S.end()); + BOOST_CHECK(R2S.begin() + 20 == R2S.end()); + BOOST_CHECK(OneS.begin() + 20 == OneS.end()); + BOOST_CHECK(MaxS.begin() + 20 == MaxS.end()); + BOOST_CHECK(TmpS.begin() + 20 == TmpS.end()); + BOOST_CHECK(R1S.GetSerializeSize(0,PROTOCOL_VERSION) == 20); + BOOST_CHECK(ZeroS.GetSerializeSize(0,PROTOCOL_VERSION) == 20); + + R1S.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(R1Array,R1Array+20)); + TmpS.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(R1S == TmpS); + ss.str(""); + ZeroS.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(ZeroArray,ZeroArray+20)); + TmpS.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ZeroS == TmpS); + ss.str(""); + MaxS.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(MaxArray,MaxArray+20)); + TmpS.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(MaxS == TmpS); + ss.str(""); +} + +BOOST_AUTO_TEST_CASE( conversion ) +{ + BOOST_CHECK(ArithToUint256(UintToArith256(ZeroL)) == ZeroL); + BOOST_CHECK(ArithToUint256(UintToArith256(OneL)) == OneL); + BOOST_CHECK(ArithToUint256(UintToArith256(R1L)) == R1L); + BOOST_CHECK(ArithToUint256(UintToArith256(R2L)) == R2L); + BOOST_CHECK(UintToArith256(ZeroL) == 0); + BOOST_CHECK(UintToArith256(OneL) == 1); + BOOST_CHECK(ArithToUint256(0) == ZeroL); + BOOST_CHECK(ArithToUint256(1) == OneL); + BOOST_CHECK(arith_uint256(R1L.GetHex()) == UintToArith256(R1L)); + BOOST_CHECK(arith_uint256(R2L.GetHex()) == UintToArith256(R2L)); + BOOST_CHECK(R1L.GetHex() == UintToArith256(R1L).GetHex()); + BOOST_CHECK(R2L.GetHex() == UintToArith256(R2L).GetHex()); +} + +BOOST_AUTO_TEST_SUITE_END() From edc720479d0749a000d5a6970da6d2d72657cf38 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 16 Dec 2014 15:44:57 +0100 Subject: [PATCH 10/12] Remove arith_uint160 We never do 160-bit arithmetic. --- src/arith_uint256.cpp | 17 -- src/arith_uint256.h | 10 -- src/test/arith_uint256_tests.cpp | 290 +++---------------------------- 3 files changed, 23 insertions(+), 294 deletions(-) diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp index f0b6a6a3bdef3..12f9e7d1b18d8 100644 --- a/src/arith_uint256.cpp +++ b/src/arith_uint256.cpp @@ -216,23 +216,6 @@ unsigned int base_uint::bits() const return 0; } -// Explicit instantiations for base_uint<160> -template base_uint<160>::base_uint(const std::string&); -template base_uint<160>::base_uint(const std::vector&); -template base_uint<160>& base_uint<160>::operator<<=(unsigned int); -template base_uint<160>& base_uint<160>::operator>>=(unsigned int); -template base_uint<160>& base_uint<160>::operator*=(uint32_t b32); -template base_uint<160>& base_uint<160>::operator*=(const base_uint<160>& b); -template base_uint<160>& base_uint<160>::operator/=(const base_uint<160>& b); -template int base_uint<160>::CompareTo(const base_uint<160>&) const; -template bool base_uint<160>::EqualTo(uint64_t) const; -template double base_uint<160>::getdouble() const; -template std::string base_uint<160>::GetHex() const; -template std::string base_uint<160>::ToString() const; -template void base_uint<160>::SetHex(const char*); -template void base_uint<160>::SetHex(const std::string&); -template unsigned int base_uint<160>::bits() const; - // Explicit instantiations for base_uint<256> template base_uint<256>::base_uint(const std::string&); template base_uint<256>::base_uint(const std::vector&); diff --git a/src/arith_uint256.h b/src/arith_uint256.h index 5cb04f3c3caf2..b69eef676990a 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -304,16 +304,6 @@ class base_uint } }; -/** 160-bit unsigned big integer. */ -class arith_uint160 : public base_uint<160> { -public: - arith_uint160() {} - arith_uint160(const base_uint<160>& b) : base_uint<160>(b) {} - arith_uint160(uint64_t b) : base_uint<160>(b) {} - explicit arith_uint160(const std::string& str) : base_uint<160>(str) {} - explicit arith_uint160(const std::vector& vch) : base_uint<160>(vch) {} -}; - /** 256-bit unsigned big integer. */ class arith_uint256 : public base_uint<256> { public: diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index f5f71da6147db..e0c4b272599bd 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -19,16 +19,13 @@ const unsigned char R1Array[] = "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d"; const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c"; const double R1Ldouble = 0.4887374590559308955; // R1L equals roughly R1Ldouble * 2^256 -const double R1Sdouble = 0.7096329412477836074; const arith_uint256 R1L = arith_uint256(std::vector(R1Array,R1Array+32)); -const arith_uint160 R1S = arith_uint160(std::vector(R1Array,R1Array+20)); const uint64_t R1LLow64 = 0x121156cfdb4a529cULL; const unsigned char R2Array[] = "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf" "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7"; const arith_uint256 R2L = arith_uint256(std::vector(R2Array,R2Array+32)); -const arith_uint160 R2S = arith_uint160(std::vector(R2Array,R2Array+20)); const char R1LplusR2L[] = "549FB09FEA236A1EA3E31D4D58F1B1369288D204211CA751527CFC175767850C"; @@ -36,22 +33,18 @@ const unsigned char ZeroArray[] = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; const arith_uint256 ZeroL = arith_uint256(std::vector(ZeroArray,ZeroArray+32)); -const arith_uint160 ZeroS = arith_uint160(std::vector(ZeroArray,ZeroArray+20)); const unsigned char OneArray[] = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; const arith_uint256 OneL = arith_uint256(std::vector(OneArray,OneArray+32)); -const arith_uint160 OneS = arith_uint160(std::vector(OneArray,OneArray+20)); const unsigned char MaxArray[] = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; const arith_uint256 MaxL = arith_uint256(std::vector(MaxArray,MaxArray+32)); -const arith_uint160 MaxS = arith_uint160(std::vector(MaxArray,MaxArray+20)); const arith_uint256 HalfL = (OneL << 255); -const arith_uint160 HalfS = (OneS << 159); std::string ArrayToString(const unsigned char A[], unsigned int width) { std::stringstream Stream; @@ -68,26 +61,19 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality BOOST_CHECK(1 == 0+1); // constructor arith_uint256(vector): BOOST_CHECK(R1L.ToString() == ArrayToString(R1Array,32)); - BOOST_CHECK(R1S.ToString() == ArrayToString(R1Array,20)); BOOST_CHECK(R2L.ToString() == ArrayToString(R2Array,32)); - BOOST_CHECK(R2S.ToString() == ArrayToString(R2Array,20)); BOOST_CHECK(ZeroL.ToString() == ArrayToString(ZeroArray,32)); - BOOST_CHECK(ZeroS.ToString() == ArrayToString(ZeroArray,20)); BOOST_CHECK(OneL.ToString() == ArrayToString(OneArray,32)); - BOOST_CHECK(OneS.ToString() == ArrayToString(OneArray,20)); BOOST_CHECK(MaxL.ToString() == ArrayToString(MaxArray,32)); - BOOST_CHECK(MaxS.ToString() == ArrayToString(MaxArray,20)); BOOST_CHECK(OneL.ToString() != ArrayToString(ZeroArray,32)); - BOOST_CHECK(OneS.ToString() != ArrayToString(ZeroArray,20)); // == and != - BOOST_CHECK(R1L != R2L && R1S != R2S); - BOOST_CHECK(ZeroL != OneL && ZeroS != OneS); - BOOST_CHECK(OneL != ZeroL && OneS != ZeroS); - BOOST_CHECK(MaxL != ZeroL && MaxS != ZeroS); - BOOST_CHECK(~MaxL == ZeroL && ~MaxS == ZeroS); + BOOST_CHECK(R1L != R2L); + BOOST_CHECK(ZeroL != OneL); + BOOST_CHECK(OneL != ZeroL); + BOOST_CHECK(MaxL != ZeroL); + BOOST_CHECK(~MaxL == ZeroL); BOOST_CHECK( ((R1L ^ R2L) ^ R1L) == R2L); - BOOST_CHECK( ((R1S ^ R2S) ^ R1S) == R2S); uint64_t Tmp64 = 0xc4dab720d9c7acaaULL; for (unsigned int i = 0; i < 256; ++i) @@ -99,15 +85,6 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality } BOOST_CHECK(ZeroL == (OneL << 256)); - for (unsigned int i = 0; i < 160; ++i) - { - BOOST_CHECK(ZeroS != (OneS << i)); - BOOST_CHECK((OneS << i) != ZeroS); - BOOST_CHECK(R1S != (R1S ^ (OneS << i))); - BOOST_CHECK(((arith_uint160(Tmp64) ^ (OneS << i) ) != Tmp64 )); - } - BOOST_CHECK(ZeroS == (OneS << 256)); - // String Constructor and Copy Constructor BOOST_CHECK(arith_uint256("0x"+R1L.ToString()) == R1L); BOOST_CHECK(arith_uint256("0x"+R2L.ToString()) == R2L); @@ -123,30 +100,11 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality BOOST_CHECK(arith_uint256(ZeroL) == ZeroL); BOOST_CHECK(arith_uint256(OneL) == OneL); - BOOST_CHECK(arith_uint160("0x"+R1S.ToString()) == R1S); - BOOST_CHECK(arith_uint160("0x"+R2S.ToString()) == R2S); - BOOST_CHECK(arith_uint160("0x"+ZeroS.ToString()) == ZeroS); - BOOST_CHECK(arith_uint160("0x"+OneS.ToString()) == OneS); - BOOST_CHECK(arith_uint160("0x"+MaxS.ToString()) == MaxS); - BOOST_CHECK(arith_uint160(R1S.ToString()) == R1S); - BOOST_CHECK(arith_uint160(" 0x"+R1S.ToString()+" ") == R1S); - BOOST_CHECK(arith_uint160("") == ZeroS); - BOOST_CHECK(R1S == arith_uint160(R1ArrayHex)); - - BOOST_CHECK(arith_uint160(R1S) == R1S); - BOOST_CHECK((arith_uint160(R1S^R2S)^R2S) == R1S); - BOOST_CHECK(arith_uint160(ZeroS) == ZeroS); - BOOST_CHECK(arith_uint160(OneS) == OneS); - // uint64_t constructor BOOST_CHECK( (R1L & arith_uint256("0xffffffffffffffff")) == arith_uint256(R1LLow64)); BOOST_CHECK(ZeroL == arith_uint256(0)); BOOST_CHECK(OneL == arith_uint256(1)); BOOST_CHECK(arith_uint256("0xffffffffffffffff") = arith_uint256(0xffffffffffffffffULL)); - BOOST_CHECK( (R1S & arith_uint160("0xffffffffffffffff")) == arith_uint160(R1LLow64)); - BOOST_CHECK(ZeroS == arith_uint160(0)); - BOOST_CHECK(OneS == arith_uint160(1)); - BOOST_CHECK(arith_uint160("0xffffffffffffffff") = arith_uint160(0xffffffffffffffffULL)); // Assignment (from base_uint) arith_uint256 tmpL = ~ZeroL; BOOST_CHECK(tmpL == ~ZeroL); @@ -154,17 +112,10 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality tmpL = ~R1L; BOOST_CHECK(tmpL == ~R1L); tmpL = ~R2L; BOOST_CHECK(tmpL == ~R2L); tmpL = ~MaxL; BOOST_CHECK(tmpL == ~MaxL); - arith_uint160 tmpS = ~ZeroS; BOOST_CHECK(tmpS == ~ZeroS); - tmpS = ~OneS; BOOST_CHECK(tmpS == ~OneS); - tmpS = ~R1S; BOOST_CHECK(tmpS == ~R1S); - tmpS = ~R2S; BOOST_CHECK(tmpS == ~R2S); - tmpS = ~MaxS; BOOST_CHECK(tmpS == ~MaxS); // Wrong length must throw exception. BOOST_CHECK_THROW(arith_uint256(std::vector(OneArray,OneArray+31)), uint_error); BOOST_CHECK_THROW(arith_uint256(std::vector(OneArray,OneArray+20)), uint_error); - BOOST_CHECK_THROW(arith_uint160(std::vector(OneArray,OneArray+32)), uint_error); - BOOST_CHECK_THROW(arith_uint160(std::vector(OneArray,OneArray+19)), uint_error); } void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift) @@ -239,74 +190,27 @@ BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>=" for (unsigned int i = 128; i < 256; ++i) { BOOST_CHECK((c1L << i) == (c2L << (i-128))); } - - arith_uint160 TmpS; - for (unsigned int i = 0; i < 160; ++i) - { - shiftArrayLeft(TmpArray, OneArray, 20, i); - BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (OneS << i)); - TmpS = OneS; TmpS <<= i; - BOOST_CHECK(TmpS == (OneS << i)); - BOOST_CHECK((HalfS >> (159-i)) == (OneS << i)); - TmpS = HalfS; TmpS >>= (159-i); - BOOST_CHECK(TmpS == (OneS << i)); - - shiftArrayLeft(TmpArray, R1Array, 20, i); - BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (R1S << i)); - TmpS = R1S; TmpS <<= i; - BOOST_CHECK(TmpS == (R1S << i)); - - shiftArrayRight(TmpArray, R1Array, 20, i); - BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (R1S >> i)); - TmpS = R1S; TmpS >>= i; - BOOST_CHECK(TmpS == (R1S >> i)); - - shiftArrayLeft(TmpArray, MaxArray, 20, i); - BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (MaxS << i)); - TmpS = MaxS; TmpS <<= i; - BOOST_CHECK(TmpS == (MaxS << i)); - - shiftArrayRight(TmpArray, MaxArray, 20, i); - BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (MaxS >> i)); - TmpS = MaxS; TmpS >>= i; - BOOST_CHECK(TmpS == (MaxS >> i)); - } - arith_uint160 c1S = arith_uint160(0x0123456789abcdefULL); - arith_uint160 c2S = c1S << 80; - for (unsigned int i = 0; i < 80; ++i) { - BOOST_CHECK((c1S << i) == (c2S >> (80-i))); - } - for (unsigned int i = 80; i < 160; ++i) { - BOOST_CHECK((c1S << i) == (c2S << (i-80))); - } } BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ - { - BOOST_CHECK(!ZeroL); BOOST_CHECK(!ZeroS); - BOOST_CHECK(!(!OneL));BOOST_CHECK(!(!OneS)); + BOOST_CHECK(!ZeroL); + BOOST_CHECK(!(!OneL)); for (unsigned int i = 0; i < 256; ++i) BOOST_CHECK(!(!(OneL<(TmpArray,TmpArray+32)) == (~R1L)); - BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (~R1S)); - BOOST_CHECK(-ZeroL == ZeroL); BOOST_CHECK(-ZeroS == ZeroS); + BOOST_CHECK(-ZeroL == ZeroL); BOOST_CHECK(-R1L == (~R1L)+1); - BOOST_CHECK(-R1S == (~R1S)+1); for (unsigned int i = 0; i < 256; ++i) BOOST_CHECK(-(OneL<(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); \ - for (unsigned int i = 0; i < 20; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \ - BOOST_CHECK(arith_uint160(std::vector(TmpArray,TmpArray+20)) == (_A_##S _OP_ _B_##S)); + BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); #define CHECKASSIGNMENTOPERATOR(_A_,_B_,_OP_) \ - TmpL = _A_##L; TmpL _OP_##= _B_##L; BOOST_CHECK(TmpL == (_A_##L _OP_ _B_##L)); \ - TmpS = _A_##S; TmpS _OP_##= _B_##S; BOOST_CHECK(TmpS == (_A_##S _OP_ _B_##S)); + TmpL = _A_##L; TmpL _OP_##= _B_##L; BOOST_CHECK(TmpL == (_A_##L _OP_ _B_##L)); BOOST_AUTO_TEST_CASE( bitwiseOperators ) { @@ -343,7 +244,6 @@ BOOST_AUTO_TEST_CASE( bitwiseOperators ) CHECKBITWISEOPERATOR(Max,R1,&) arith_uint256 TmpL; - arith_uint160 TmpS; CHECKASSIGNMENTOPERATOR(R1,R2,|) CHECKASSIGNMENTOPERATOR(R1,R2,^) CHECKASSIGNMENTOPERATOR(R1,R2,&) @@ -362,13 +262,9 @@ BOOST_AUTO_TEST_CASE( bitwiseOperators ) uint64_t Tmp64 = 0xe1db685c9a0b47a2ULL; TmpL = R1L; TmpL |= Tmp64; BOOST_CHECK(TmpL == (R1L | arith_uint256(Tmp64))); - TmpS = R1S; TmpS |= Tmp64; BOOST_CHECK(TmpS == (R1S | arith_uint160(Tmp64))); TmpL = R1L; TmpL |= 0; BOOST_CHECK(TmpL == R1L); - TmpS = R1S; TmpS |= 0; BOOST_CHECK(TmpS == R1S); TmpL ^= 0; BOOST_CHECK(TmpL == R1L); - TmpS ^= 0; BOOST_CHECK(TmpS == R1S); TmpL ^= Tmp64; BOOST_CHECK(TmpL == (R1L ^ arith_uint256(Tmp64))); - TmpS ^= Tmp64; BOOST_CHECK(TmpS == (R1S ^ arith_uint160(Tmp64))); } BOOST_AUTO_TEST_CASE( comparison ) // <= >= < > @@ -383,16 +279,6 @@ BOOST_AUTO_TEST_CASE( comparison ) // <= >= < > BOOST_CHECK( R1L <= TmpL ); BOOST_CHECK( (R1L == TmpL) != (R1L < TmpL)); BOOST_CHECK( (TmpL == R1L) || !( R1L >= TmpL)); BOOST_CHECK(! (TmpL < R1L)); BOOST_CHECK(! (R1L > TmpL)); } - arith_uint160 TmpS; - for (unsigned int i = 0; i < 160; ++i) { - TmpS= OneS<< i; - BOOST_CHECK( TmpS >= ZeroS && TmpS > ZeroS && ZeroS < TmpS && ZeroS <= TmpS); - BOOST_CHECK( TmpS >= 0 && TmpS > 0 && 0 < TmpS && 0 <= TmpS); - TmpS |= R1S; - BOOST_CHECK( TmpS >= R1S ); BOOST_CHECK( (TmpS == R1S) != (TmpS > R1S)); BOOST_CHECK( (TmpS == R1S) || !( TmpS <= R1S)); - BOOST_CHECK( R1S <= TmpS ); BOOST_CHECK( (R1S == TmpS) != (R1S < TmpS)); BOOST_CHECK( (TmpS == R1S) || !( R1S >= TmpS)); - BOOST_CHECK(! (TmpS < R1S)); BOOST_CHECK(! (R1S > TmpS)); - } } BOOST_AUTO_TEST_CASE( plusMinus ) @@ -437,49 +323,6 @@ BOOST_AUTO_TEST_CASE( plusMinus ) } TmpL = R1L; BOOST_CHECK(--TmpL == R1L-1); - - // 160-bit; copy-pasted - arith_uint160 TmpS = 0; - BOOST_CHECK(R1S+R2S == arith_uint160(R1LplusR2L)); - TmpS += R1S; - BOOST_CHECK(TmpS == R1S); - TmpS += R2S; - BOOST_CHECK(TmpS == R1S + R2S); - BOOST_CHECK(OneS+MaxS == ZeroS); - BOOST_CHECK(MaxS+OneS == ZeroS); - for (unsigned int i = 1; i < 160; ++i) { - BOOST_CHECK( (MaxS >> i) + OneS == (HalfS >> (i-1)) ); - BOOST_CHECK( OneS + (MaxS >> i) == (HalfS >> (i-1)) ); - TmpS = (MaxS>>i); TmpS += OneS; - BOOST_CHECK( TmpS == (HalfS >> (i-1)) ); - TmpS = (MaxS>>i); TmpS += 1; - BOOST_CHECK( TmpS == (HalfS >> (i-1)) ); - TmpS = (MaxS>>i); - BOOST_CHECK( TmpS++ == (MaxS>>i) ); - BOOST_CHECK( TmpS == (HalfS >> (i-1))); - } - BOOST_CHECK(arith_uint160(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == arith_uint160(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL)); - TmpS = arith_uint160(0xbedc77e27940a7ULL); TmpS += 0xee8d836fce66fbULL; - BOOST_CHECK(TmpS == arith_uint160(0xbedc77e27940a7ULL+0xee8d836fce66fbULL)); - TmpS -= 0xee8d836fce66fbULL; BOOST_CHECK(TmpS == 0xbedc77e27940a7ULL); - TmpS = R1S; - BOOST_CHECK(++TmpS == R1S+1); - - BOOST_CHECK(R1S -(-R2S) == R1S+R2S); - BOOST_CHECK(R1S -(-OneS) == R1S+OneS); - BOOST_CHECK(R1S - OneS == R1S+(-OneS)); - for (unsigned int i = 1; i < 160; ++i) { - BOOST_CHECK((MaxS>>i) - (-OneS) == (HalfS >> (i-1))); - BOOST_CHECK((HalfS >> (i-1)) - OneS == (MaxS>>i)); - TmpS = (HalfS >> (i-1)); - BOOST_CHECK(TmpS-- == (HalfS >> (i-1))); - BOOST_CHECK(TmpS == (MaxS >> i)); - TmpS = (HalfS >> (i-1)); - BOOST_CHECK(--TmpS == (MaxS >> i)); - } - TmpS = R1S; - BOOST_CHECK(--TmpS == R1S-1); - } BOOST_AUTO_TEST_CASE( multiply ) @@ -495,28 +338,12 @@ BOOST_AUTO_TEST_CASE( multiply ) BOOST_CHECK((R2L * OneL) == R2L); BOOST_CHECK((R2L * MaxL) == -R2L); - BOOST_CHECK((R1S * R1S).ToString() == "a7761bf30d5237e9873f9bff3642a732c4d84f10"); - BOOST_CHECK((R1S * R2S).ToString() == "ba51c008df851987d9dd323f0e5de07760529c40"); - BOOST_CHECK((R1S * ZeroS) == ZeroS); - BOOST_CHECK((R1S * OneS) == R1S); - BOOST_CHECK((R1S * MaxS) == -R1S); - BOOST_CHECK((R2S * R1S) == (R1S * R2S)); - BOOST_CHECK((R2S * R2S).ToString() == "c28bb2b45a1d85ab7996ccd3e102a650f74ff100"); - BOOST_CHECK((R2S * ZeroS) == ZeroS); - BOOST_CHECK((R2S * OneS) == R2S); - BOOST_CHECK((R2S * MaxS) == -R2S); - BOOST_CHECK(MaxL * MaxL == OneL); - BOOST_CHECK(MaxS * MaxS == OneS); BOOST_CHECK((R1L * 0) == 0); BOOST_CHECK((R1L * 1) == R1L); BOOST_CHECK((R1L * 3).ToString() == "7759b1c0ed14047f961ad09b20ff83687876a0181a367b813634046f91def7d4"); BOOST_CHECK((R2L * 0x87654321UL).ToString() == "23f7816e30c4ae2017257b7a0fa64d60402f5234d46e746b61c960d09a26d070"); - BOOST_CHECK((R1S * 0) == 0); - BOOST_CHECK((R1S * 1) == R1S); - BOOST_CHECK((R1S * 7).ToString() == "f7a987f3c3bf758d927f202d7e795faeff084244"); - BOOST_CHECK((R2S * 0xFFFFFFFFUL).ToString() == "1c6f6c930353e17f7d6127213bb18d2883e2cd90"); } BOOST_AUTO_TEST_CASE( divide ) @@ -535,21 +362,6 @@ BOOST_AUTO_TEST_CASE( divide ) BOOST_CHECK(R2L / MaxL == ZeroL); BOOST_CHECK(MaxL / R2L == 1); BOOST_CHECK_THROW(R2L / ZeroL, uint_error); - - arith_uint160 D1S("D3C5EDCDEA54EB92679F0A4B4"); - arith_uint160 D2S("13037"); - BOOST_CHECK((R1S / D1S).ToString() == "0000000000000000000000000db9af3beade6c02"); - BOOST_CHECK((R1S / D2S).ToString() == "000098dfb6cc40ca592bf74366794f298ada205c"); - BOOST_CHECK(R1S / OneS == R1S); - BOOST_CHECK(R1S / MaxS == ZeroS); - BOOST_CHECK(MaxS / R1S == 1); - BOOST_CHECK_THROW(R1S / ZeroS, uint_error); - BOOST_CHECK((R2S / D1S).ToString() == "0000000000000000000000000c5608e781182047"); - BOOST_CHECK((R2S / D2S).ToString() == "00008966751b7187c3c67c1fda5cea7db2c1c069"); - BOOST_CHECK(R2S / OneS == R2S); - BOOST_CHECK(R2S / MaxS == ZeroS); - BOOST_CHECK(MaxS / R2S == 1); - BOOST_CHECK_THROW(R2S / ZeroS, uint_error); } @@ -608,70 +420,17 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G BOOST_CHECK(MaxL == TmpL); ss.str(""); - BOOST_CHECK(R1S.GetHex() == R1S.ToString()); - BOOST_CHECK(R2S.GetHex() == R2S.ToString()); - BOOST_CHECK(OneS.GetHex() == OneS.ToString()); - BOOST_CHECK(MaxS.GetHex() == MaxS.ToString()); - arith_uint160 TmpS(R1S); - BOOST_CHECK(TmpS == R1S); - TmpS.SetHex(R2S.ToString()); BOOST_CHECK(TmpS == R2S); - TmpS.SetHex(ZeroS.ToString()); BOOST_CHECK(TmpS == 0); - TmpS.SetHex(HalfS.ToString()); BOOST_CHECK(TmpS == HalfS); - - TmpS.SetHex(R1S.ToString()); - BOOST_CHECK(memcmp(R1S.begin(), R1Array, 20)==0); - BOOST_CHECK(memcmp(TmpS.begin(), R1Array, 20)==0); - BOOST_CHECK(memcmp(R2S.begin(), R2Array, 20)==0); - BOOST_CHECK(memcmp(ZeroS.begin(), ZeroArray, 20)==0); - BOOST_CHECK(memcmp(OneS.begin(), OneArray, 20)==0); - BOOST_CHECK(R1S.size() == 20); - BOOST_CHECK(R2S.size() == 20); - BOOST_CHECK(ZeroS.size() == 20); - BOOST_CHECK(MaxS.size() == 20); - BOOST_CHECK(R1S.begin() + 20 == R1S.end()); - BOOST_CHECK(R2S.begin() + 20 == R2S.end()); - BOOST_CHECK(OneS.begin() + 20 == OneS.end()); - BOOST_CHECK(MaxS.begin() + 20 == MaxS.end()); - BOOST_CHECK(TmpS.begin() + 20 == TmpS.end()); - BOOST_CHECK(R1S.GetLow64() == R1LLow64); - BOOST_CHECK(HalfS.GetLow64() ==0x0000000000000000ULL); - BOOST_CHECK(OneS.GetLow64() ==0x0000000000000001ULL); - BOOST_CHECK(R1S.GetSerializeSize(0,PROTOCOL_VERSION) == 20); - BOOST_CHECK(ZeroS.GetSerializeSize(0,PROTOCOL_VERSION) == 20); - - R1S.Serialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(ss.str() == std::string(R1Array,R1Array+20)); - TmpS.Unserialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(R1S == TmpS); - ss.str(""); - ZeroS.Serialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(ss.str() == std::string(ZeroArray,ZeroArray+20)); - TmpS.Unserialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(ZeroS == TmpS); - ss.str(""); - MaxS.Serialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(ss.str() == std::string(MaxArray,MaxArray+20)); - TmpS.Unserialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(MaxS == TmpS); - ss.str(""); - for (unsigned int i = 0; i < 255; ++i) { BOOST_CHECK((OneL << i).getdouble() == ldexp(1.0,i)); - if (i < 160) BOOST_CHECK((OneS << i).getdouble() == ldexp(1.0,i)); } BOOST_CHECK(ZeroL.getdouble() == 0.0); - BOOST_CHECK(ZeroS.getdouble() == 0.0); for (int i = 256; i > 53; --i) BOOST_CHECK(almostEqual((R1L>>(256-i)).getdouble(), ldexp(R1Ldouble,i))); - for (int i = 160; i > 53; --i) - BOOST_CHECK(almostEqual((R1S>>(160-i)).getdouble(), ldexp(R1Sdouble,i))); uint64_t R1L64part = (R1L>>192).GetLow64(); - uint64_t R1S64part = (R1S>>96).GetLow64(); for (int i = 53; i > 0; --i) // doubles can store all integers in {0,...,2^54-1} exactly { BOOST_CHECK((R1L>>(256-i)).getdouble() == (double)(R1L64part >> (64-i))); - BOOST_CHECK((R1S>>(160-i)).getdouble() == (double)(R1S64part >> (64-i))); } } @@ -807,23 +566,20 @@ BOOST_AUTO_TEST_CASE(bignum_SetCompact) BOOST_AUTO_TEST_CASE( getmaxcoverage ) // some more tests just to get 100% coverage { // ~R1L give a base_uint<256> - BOOST_CHECK((~~R1L >> 10) == (R1L >> 10)); BOOST_CHECK((~~R1S >> 10) == (R1S >> 10)); - BOOST_CHECK((~~R1L << 10) == (R1L << 10)); BOOST_CHECK((~~R1S << 10) == (R1S << 10)); - BOOST_CHECK(!(~~R1L < R1L)); BOOST_CHECK(!(~~R1S < R1S)); - BOOST_CHECK(~~R1L <= R1L); BOOST_CHECK(~~R1S <= R1S); - BOOST_CHECK(!(~~R1L > R1L)); BOOST_CHECK(!(~~R1S > R1S)); - BOOST_CHECK(~~R1L >= R1L); BOOST_CHECK(~~R1S >= R1S); - BOOST_CHECK(!(R1L < ~~R1L)); BOOST_CHECK(!(R1S < ~~R1S)); - BOOST_CHECK(R1L <= ~~R1L); BOOST_CHECK(R1S <= ~~R1S); - BOOST_CHECK(!(R1L > ~~R1L)); BOOST_CHECK(!(R1S > ~~R1S)); - BOOST_CHECK(R1L >= ~~R1L); BOOST_CHECK(R1S >= ~~R1S); + BOOST_CHECK((~~R1L >> 10) == (R1L >> 10)); + BOOST_CHECK((~~R1L << 10) == (R1L << 10)); + BOOST_CHECK(!(~~R1L < R1L)); + BOOST_CHECK(~~R1L <= R1L); + BOOST_CHECK(!(~~R1L > R1L)); + BOOST_CHECK(~~R1L >= R1L); + BOOST_CHECK(!(R1L < ~~R1L)); + BOOST_CHECK(R1L <= ~~R1L); + BOOST_CHECK(!(R1L > ~~R1L)); + BOOST_CHECK(R1L >= ~~R1L); BOOST_CHECK(~~R1L + R2L == R1L + ~~R2L); - BOOST_CHECK(~~R1S + R2S == R1S + ~~R2S); BOOST_CHECK(~~R1L - R2L == R1L - ~~R2L); - BOOST_CHECK(~~R1S - R2S == R1S - ~~R2S); BOOST_CHECK(~R1L != R1L); BOOST_CHECK(R1L != ~R1L); - BOOST_CHECK(~R1S != R1S); BOOST_CHECK(R1S != ~R1S); unsigned char TmpArray[32]; CHECKBITWISEOPERATOR(~R1,R2,|) CHECKBITWISEOPERATOR(~R1,R2,^) From 30007fda76aa7ba4e4090f7a16298874a7722926 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 16 Dec 2014 15:47:29 +0100 Subject: [PATCH 11/12] Remove now-unused methods from arith_uint256 and base_uint - Methods that access the guts of arith_uint256 are removed, as these are incompatible between endians. Use uint256 instead - Serialization is no longer needed as arith_uint256's are never read or written - GetHash is never used on arith_uint256 --- src/arith_uint256.cpp | 62 -------------------------------- src/arith_uint256.h | 56 ----------------------------- src/test/arith_uint256_tests.cpp | 31 +--------------- 3 files changed, 1 insertion(+), 148 deletions(-) diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp index 12f9e7d1b18d8..11df3b05c0576 100644 --- a/src/arith_uint256.cpp +++ b/src/arith_uint256.cpp @@ -278,68 +278,6 @@ uint32_t arith_uint256::GetCompact(bool fNegative) const return nCompact; } -static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c) -{ - // Taken from lookup3, by Bob Jenkins. - a -= c; - a ^= ((c << 4) | (c >> 28)); - c += b; - b -= a; - b ^= ((a << 6) | (a >> 26)); - a += c; - c -= b; - c ^= ((b << 8) | (b >> 24)); - b += a; - a -= c; - a ^= ((c << 16) | (c >> 16)); - c += b; - b -= a; - b ^= ((a << 19) | (a >> 13)); - a += c; - c -= b; - c ^= ((b << 4) | (b >> 28)); - b += a; -} - -static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c) -{ - // Taken from lookup3, by Bob Jenkins. - c ^= b; - c -= ((b << 14) | (b >> 18)); - a ^= c; - a -= ((c << 11) | (c >> 21)); - b ^= a; - b -= ((a << 25) | (a >> 7)); - c ^= b; - c -= ((b << 16) | (b >> 16)); - a ^= c; - a -= ((c << 4) | (c >> 28)); - b ^= a; - b -= ((a << 14) | (a >> 18)); - c ^= b; - c -= ((b << 24) | (b >> 8)); -} - -uint64_t arith_uint256::GetHash(const arith_uint256& salt) const -{ - uint32_t a, b, c; - a = b = c = 0xdeadbeef + (WIDTH << 2); - - a += pn[0] ^ salt.pn[0]; - b += pn[1] ^ salt.pn[1]; - c += pn[2] ^ salt.pn[2]; - HashMix(a, b, c); - a += pn[3] ^ salt.pn[3]; - b += pn[4] ^ salt.pn[4]; - c += pn[5] ^ salt.pn[5]; - HashMix(a, b, c); - a += pn[6] ^ salt.pn[6]; - b += pn[7] ^ salt.pn[7]; - HashFinal(a, b, c); - - return ((((uint64_t)b) << 32) | c); -} - uint256 ArithToUint256(const arith_uint256 &a) { uint256 b; diff --git a/src/arith_uint256.h b/src/arith_uint256.h index b69eef676990a..ec8e15997fa05 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -232,26 +232,6 @@ class base_uint void SetHex(const std::string& str); std::string ToString() const; - unsigned char* begin() - { - return (unsigned char*)&pn[0]; - } - - unsigned char* end() - { - return (unsigned char*)&pn[WIDTH]; - } - - const unsigned char* begin() const - { - return (unsigned char*)&pn[0]; - } - - const unsigned char* end() const - { - return (unsigned char*)&pn[WIDTH]; - } - unsigned int size() const { return sizeof(pn); @@ -268,40 +248,6 @@ class base_uint assert(WIDTH >= 2); return pn[0] | (uint64_t)pn[1] << 32; } - - unsigned int GetSerializeSize(int nType, int nVersion) const - { - return sizeof(pn); - } - - template - void Serialize(Stream& s, int nType, int nVersion) const - { - s.write((char*)pn, sizeof(pn)); - } - - template - void Unserialize(Stream& s, int nType, int nVersion) - { - s.read((char*)pn, sizeof(pn)); - } - - // Temporary for migration to blob160/256 - uint64_t GetCheapHash() const - { - return GetLow64(); - } - void SetNull() - { - memset(pn, 0, sizeof(pn)); - } - bool IsNull() const - { - for (int i = 0; i < WIDTH; i++) - if (pn[i] != 0) - return false; - return true; - } }; /** 256-bit unsigned big integer. */ @@ -336,8 +282,6 @@ class arith_uint256 : public base_uint<256> { arith_uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL); uint32_t GetCompact(bool fNegative = false) const; - uint64_t GetHash(const arith_uint256& salt) const; - friend uint256 ArithToUint256(const arith_uint256 &); friend arith_uint256 UintToArith256(const uint256 &); }; diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index e0c4b272599bd..6895367531880 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -370,7 +370,7 @@ bool almostEqual(double d1, double d2) return fabs(d1-d2) <= 4*fabs(d1)*std::numeric_limits::epsilon(); } -BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 GetSerializeSize, Serialize, Unserialize +BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex size() GetLow64 GetSerializeSize, Serialize, Unserialize { BOOST_CHECK(R1L.GetHex() == R1L.ToString()); BOOST_CHECK(R2L.GetHex() == R2L.ToString()); @@ -383,42 +383,13 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G TmpL.SetHex(HalfL.ToString()); BOOST_CHECK(TmpL == HalfL); TmpL.SetHex(R1L.ToString()); - BOOST_CHECK(memcmp(R1L.begin(), R1Array, 32)==0); - BOOST_CHECK(memcmp(TmpL.begin(), R1Array, 32)==0); - BOOST_CHECK(memcmp(R2L.begin(), R2Array, 32)==0); - BOOST_CHECK(memcmp(ZeroL.begin(), ZeroArray, 32)==0); - BOOST_CHECK(memcmp(OneL.begin(), OneArray, 32)==0); BOOST_CHECK(R1L.size() == 32); BOOST_CHECK(R2L.size() == 32); BOOST_CHECK(ZeroL.size() == 32); BOOST_CHECK(MaxL.size() == 32); - BOOST_CHECK(R1L.begin() + 32 == R1L.end()); - BOOST_CHECK(R2L.begin() + 32 == R2L.end()); - BOOST_CHECK(OneL.begin() + 32 == OneL.end()); - BOOST_CHECK(MaxL.begin() + 32 == MaxL.end()); - BOOST_CHECK(TmpL.begin() + 32 == TmpL.end()); BOOST_CHECK(R1L.GetLow64() == R1LLow64); BOOST_CHECK(HalfL.GetLow64() ==0x0000000000000000ULL); BOOST_CHECK(OneL.GetLow64() ==0x0000000000000001ULL); - BOOST_CHECK(R1L.GetSerializeSize(0,PROTOCOL_VERSION) == 32); - BOOST_CHECK(ZeroL.GetSerializeSize(0,PROTOCOL_VERSION) == 32); - - std::stringstream ss; - R1L.Serialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(ss.str() == std::string(R1Array,R1Array+32)); - TmpL.Unserialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(R1L == TmpL); - ss.str(""); - ZeroL.Serialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(ss.str() == std::string(ZeroArray,ZeroArray+32)); - TmpL.Unserialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(ZeroL == TmpL); - ss.str(""); - MaxL.Serialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(ss.str() == std::string(MaxArray,MaxArray+32)); - TmpL.Unserialize(ss,0,PROTOCOL_VERSION); - BOOST_CHECK(MaxL == TmpL); - ss.str(""); for (unsigned int i = 0; i < 255; ++i) { From 6bd0dc2a845b4d17d5ffabbdadda80d47d6c2dc3 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 19 Dec 2014 13:07:07 +0100 Subject: [PATCH 12/12] arith_uint256: remove initialization from byte vector Remove initialization from vector (as this is only used in the tests). Also implement SetHex and GetHex in terms of uint256, to avoid duplicate code as well as avoid endianness issues (as they work in term of bytes). --- src/arith_uint256.cpp | 39 ++------------------------------ src/arith_uint256.h | 2 -- src/test/arith_uint256_tests.cpp | 35 +++++++++++++++------------- 3 files changed, 21 insertions(+), 55 deletions(-) diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp index 11df3b05c0576..1243823da5228 100644 --- a/src/arith_uint256.cpp +++ b/src/arith_uint256.cpp @@ -17,14 +17,6 @@ base_uint::base_uint(const std::string& str) SetHex(str); } -template -base_uint::base_uint(const std::vector& vch) -{ - if (vch.size() != sizeof(pn)) - throw uint_error("Converting vector of wrong size to base_uint"); - memcpy(pn, &vch[0], sizeof(pn)); -} - template base_uint& base_uint::operator<<=(unsigned int shift) { @@ -154,39 +146,13 @@ double base_uint::getdouble() const template std::string base_uint::GetHex() const { - char psz[sizeof(pn) * 2 + 1]; - for (unsigned int i = 0; i < sizeof(pn); i++) - sprintf(psz + i * 2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); - return std::string(psz, psz + sizeof(pn) * 2); + return ArithToUint256(*this).GetHex(); } template void base_uint::SetHex(const char* psz) { - memset(pn, 0, sizeof(pn)); - - // skip leading spaces - while (isspace(*psz)) - psz++; - - // skip 0x - if (psz[0] == '0' && tolower(psz[1]) == 'x') - psz += 2; - - // hex string to uint - const char* pbegin = psz; - while (::HexDigit(*psz) != -1) - psz++; - psz--; - unsigned char* p1 = (unsigned char*)pn; - unsigned char* pend = p1 + WIDTH * 4; - while (psz >= pbegin && p1 < pend) { - *p1 = ::HexDigit(*psz--); - if (psz >= pbegin) { - *p1 |= ((unsigned char)::HexDigit(*psz--) << 4); - p1++; - } - } + *this = UintToArith256(uint256S(psz)); } template @@ -218,7 +184,6 @@ unsigned int base_uint::bits() const // Explicit instantiations for base_uint<256> template base_uint<256>::base_uint(const std::string&); -template base_uint<256>::base_uint(const std::vector&); template base_uint<256>& base_uint<256>::operator<<=(unsigned int); template base_uint<256>& base_uint<256>::operator>>=(unsigned int); template base_uint<256>& base_uint<256>::operator*=(uint32_t b32); diff --git a/src/arith_uint256.h b/src/arith_uint256.h index ec8e15997fa05..b6ba3a10874c8 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -57,7 +57,6 @@ class base_uint } explicit base_uint(const std::string& str); - explicit base_uint(const std::vector& vch); bool operator!() const { @@ -257,7 +256,6 @@ class arith_uint256 : public base_uint<256> { arith_uint256(const base_uint<256>& b) : base_uint<256>(b) {} arith_uint256(uint64_t b) : base_uint<256>(b) {} explicit arith_uint256(const std::string& str) : base_uint<256>(str) {} - explicit arith_uint256(const std::vector& vch) : base_uint<256>(vch) {} /** * The "compact" format is a representation of a whole diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index 6895367531880..565b02ae64291 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -8,41 +8,48 @@ #include #include #include +#include "uint256.h" #include "arith_uint256.h" #include #include "version.h" BOOST_AUTO_TEST_SUITE(arith_uint256_tests) +/// Convert vector to arith_uint256, via uint256 blob +inline arith_uint256 arith_uint256V(const std::vector& vch) +{ + return UintToArith256(uint256(vch)); +} + const unsigned char R1Array[] = "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2" "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d"; const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c"; const double R1Ldouble = 0.4887374590559308955; // R1L equals roughly R1Ldouble * 2^256 -const arith_uint256 R1L = arith_uint256(std::vector(R1Array,R1Array+32)); +const arith_uint256 R1L = arith_uint256V(std::vector(R1Array,R1Array+32)); const uint64_t R1LLow64 = 0x121156cfdb4a529cULL; const unsigned char R2Array[] = "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf" "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7"; -const arith_uint256 R2L = arith_uint256(std::vector(R2Array,R2Array+32)); +const arith_uint256 R2L = arith_uint256V(std::vector(R2Array,R2Array+32)); const char R1LplusR2L[] = "549FB09FEA236A1EA3E31D4D58F1B1369288D204211CA751527CFC175767850C"; const unsigned char ZeroArray[] = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; -const arith_uint256 ZeroL = arith_uint256(std::vector(ZeroArray,ZeroArray+32)); +const arith_uint256 ZeroL = arith_uint256V(std::vector(ZeroArray,ZeroArray+32)); const unsigned char OneArray[] = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; -const arith_uint256 OneL = arith_uint256(std::vector(OneArray,OneArray+32)); +const arith_uint256 OneL = arith_uint256V(std::vector(OneArray,OneArray+32)); const unsigned char MaxArray[] = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; -const arith_uint256 MaxL = arith_uint256(std::vector(MaxArray,MaxArray+32)); +const arith_uint256 MaxL = arith_uint256V(std::vector(MaxArray,MaxArray+32)); const arith_uint256 HalfL = (OneL << 255); std::string ArrayToString(const unsigned char A[], unsigned int width) @@ -112,10 +119,6 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality tmpL = ~R1L; BOOST_CHECK(tmpL == ~R1L); tmpL = ~R2L; BOOST_CHECK(tmpL == ~R2L); tmpL = ~MaxL; BOOST_CHECK(tmpL == ~MaxL); - - // Wrong length must throw exception. - BOOST_CHECK_THROW(arith_uint256(std::vector(OneArray,OneArray+31)), uint_error); - BOOST_CHECK_THROW(arith_uint256(std::vector(OneArray,OneArray+20)), uint_error); } void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift) @@ -155,7 +158,7 @@ BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>=" for (unsigned int i = 0; i < 256; ++i) { shiftArrayLeft(TmpArray, OneArray, 32, i); - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (OneL << i)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (OneL << i)); TmpL = OneL; TmpL <<= i; BOOST_CHECK(TmpL == (OneL << i)); BOOST_CHECK((HalfL >> (255-i)) == (OneL << i)); @@ -163,22 +166,22 @@ BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>=" BOOST_CHECK(TmpL == (OneL << i)); shiftArrayLeft(TmpArray, R1Array, 32, i); - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (R1L << i)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (R1L << i)); TmpL = R1L; TmpL <<= i; BOOST_CHECK(TmpL == (R1L << i)); shiftArrayRight(TmpArray, R1Array, 32, i); - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (R1L >> i)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (R1L >> i)); TmpL = R1L; TmpL >>= i; BOOST_CHECK(TmpL == (R1L >> i)); shiftArrayLeft(TmpArray, MaxArray, 32, i); - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (MaxL << i)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (MaxL << i)); TmpL = MaxL; TmpL <<= i; BOOST_CHECK(TmpL == (MaxL << i)); shiftArrayRight(TmpArray, MaxArray, 32, i); - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (MaxL >> i)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (MaxL >> i)); TmpL = MaxL; TmpL >>= i; BOOST_CHECK(TmpL == (MaxL >> i)); } @@ -205,7 +208,7 @@ BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ - unsigned char TmpArray[32]; for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = ~R1Array[i]; } - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (~R1L)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (~R1L)); BOOST_CHECK(-ZeroL == ZeroL); BOOST_CHECK(-R1L == (~R1L)+1); @@ -218,7 +221,7 @@ BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ - // element of Aarray and Barray, and then converting the result into a arith_uint256. #define CHECKBITWISEOPERATOR(_A_,_B_,_OP_) \ for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \ - BOOST_CHECK(arith_uint256(std::vector(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); + BOOST_CHECK(arith_uint256V(std::vector(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); #define CHECKASSIGNMENTOPERATOR(_A_,_B_,_OP_) \ TmpL = _A_##L; TmpL _OP_##= _B_##L; BOOST_CHECK(TmpL == (_A_##L _OP_ _B_##L));