Merge pull request #5490

6bd0dc2 arith_uint256: remove initialization from byte vector (Wladimir J. van der Laan)
30007fd Remove now-unused methods from arith_uint256 and base_uint (Wladimir J. van der Laan)
edc7204 Remove arith_uint160 (Wladimir J. van der Laan)
dba2e91 Add tests for new uint256 (Wladimir J. van der Laan)
92cdb1a Add conversion functions arith_uint256<->uint_256 (Wladimir J. van der Laan)
bfc6070 uint256->arith_uint256 blob256->uint256 (Wladimir J. van der Laan)
734f85c Use arith_uint256 where necessary (Wladimir J. van der Laan)
34cdc41 String conversions uint256 -> uint256S (Wladimir J. van der Laan)
2eae315 Replace uint256(1) with static constant (Wladimir J. van der Laan)
8076585 Replace GetLow64 with GetCheapHash (Wladimir J. van der Laan)
4f15249 Replace direct use of 0 with SetNull and IsNull (Wladimir J. van der Laan)
5d3064b Temporarily add SetNull/IsNull/GetCheapHash to base_uint (Wladimir J. van der Laan)
This commit is contained in:
Wladimir J. van der Laan 2015-01-05 16:44:49 +01:00
commit ec20fd74b8
No known key found for this signature in database
GPG key ID: 74810B012346C9A6
50 changed files with 1518 additions and 1341 deletions

View file

@ -74,11 +74,12 @@ BITCOIN_CORE_H = \
alert.h \ alert.h \
allocators.h \ allocators.h \
amount.h \ amount.h \
arith_uint256.h \
base58.h \ base58.h \
bloom.h \ bloom.h \
chain.h \ chain.h \
chainparams.h \
chainparamsbase.h \ chainparamsbase.h \
chainparams.h \
chainparamsseeds.h \ chainparamsseeds.h \
checkpoints.h \ checkpoints.h \
checkqueue.h \ checkqueue.h \
@ -87,8 +88,6 @@ BITCOIN_CORE_H = \
coins.h \ coins.h \
compat.h \ compat.h \
compressor.h \ compressor.h \
primitives/block.h \
primitives/transaction.h \
core_io.h \ core_io.h \
crypter.h \ crypter.h \
db.h \ db.h \
@ -108,6 +107,8 @@ BITCOIN_CORE_H = \
net.h \ net.h \
noui.h \ noui.h \
pow.h \ pow.h \
primitives/block.h \
primitives/transaction.h \
protocol.h \ protocol.h \
pubkey.h \ pubkey.h \
random.h \ random.h \
@ -115,11 +116,11 @@ BITCOIN_CORE_H = \
rpcprotocol.h \ rpcprotocol.h \
rpcserver.h \ rpcserver.h \
script/interpreter.h \ script/interpreter.h \
script/script_error.h \
script/script.h \ script/script.h \
script/sigcache.h \ script/sigcache.h \
script/sign.h \ script/sign.h \
script/standard.h \ script/standard.h \
script/script_error.h \
serialize.h \ serialize.h \
streams.h \ streams.h \
sync.h \ sync.h \
@ -132,13 +133,13 @@ BITCOIN_CORE_H = \
uint256.h \ uint256.h \
undo.h \ undo.h \
util.h \ util.h \
utilstrencodings.h \
utilmoneystr.h \ utilmoneystr.h \
utilstrencodings.h \
utiltime.h \ utiltime.h \
version.h \ version.h \
walletdb.h \
wallet.h \ wallet.h \
wallet_ismine.h \ wallet_ismine.h \
walletdb.h \
compat/sanity.h compat/sanity.h
JSON_H = \ JSON_H = \
@ -261,18 +262,19 @@ libbitcoin_common_a_SOURCES = \
# backward-compatibility objects and their sanity checks are linked. # backward-compatibility objects and their sanity checks are linked.
libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES) libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_util_a_SOURCES = \ libbitcoin_util_a_SOURCES = \
compat/strnlen.cpp \ arith_uint256.cpp \
compat/glibc_sanity.cpp \
compat/glibcxx_sanity.cpp \
chainparamsbase.cpp \ chainparamsbase.cpp \
clientversion.cpp \ clientversion.cpp \
compat/glibc_sanity.cpp \
compat/glibcxx_sanity.cpp \
compat/strnlen.cpp \
random.cpp \ random.cpp \
rpcprotocol.cpp \ rpcprotocol.cpp \
sync.cpp \ sync.cpp \
uint256.cpp \ uint256.cpp \
util.cpp \ util.cpp \
utilstrencodings.cpp \
utilmoneystr.cpp \ utilmoneystr.cpp \
utilstrencodings.cpp \
utiltime.cpp \ utiltime.cpp \
$(BITCOIN_CORE_H) $(BITCOIN_CORE_H)
@ -352,19 +354,20 @@ bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
if BUILD_BITCOIN_LIBS if BUILD_BITCOIN_LIBS
include_HEADERS = script/bitcoinconsensus.h include_HEADERS = script/bitcoinconsensus.h
libbitcoinconsensus_la_SOURCES = \ libbitcoinconsensus_la_SOURCES = \
primitives/transaction.cpp \ arith_uint256.cpp \
crypto/hmac_sha512.cpp \ crypto/hmac_sha512.cpp \
crypto/ripemd160.cpp \
crypto/sha1.cpp \ crypto/sha1.cpp \
crypto/sha256.cpp \ crypto/sha256.cpp \
crypto/sha512.cpp \ crypto/sha512.cpp \
crypto/ripemd160.cpp \
eccryptoverify.cpp \ eccryptoverify.cpp \
ecwrapper.cpp \ ecwrapper.cpp \
hash.cpp \ hash.cpp \
primitives/transaction.cpp \
pubkey.cpp \ pubkey.cpp \
script/script.cpp \
script/interpreter.cpp \
script/bitcoinconsensus.cpp \ script/bitcoinconsensus.cpp \
script/interpreter.cpp \
script/script.cpp \
uint256.cpp \ uint256.cpp \
utilstrencodings.cpp utilstrencodings.cpp

View file

@ -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) GENERATED_TEST_FILES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h)
BITCOIN_TESTS =\ BITCOIN_TESTS =\
test/arith_uint256_tests.cpp \
test/bignum.h \ test/bignum.h \
test/alert_tests.cpp \ test/alert_tests.cpp \
test/allocator_tests.cpp \ test/allocator_tests.cpp \

View file

@ -15,12 +15,12 @@ int CAddrInfo::GetTriedBucket(const std::vector<unsigned char>& nKey) const
CDataStream ss1(SER_GETHASH, 0); CDataStream ss1(SER_GETHASH, 0);
std::vector<unsigned char> vchKey = GetKey(); std::vector<unsigned char> vchKey = GetKey();
ss1 << nKey << vchKey; 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); CDataStream ss2(SER_GETHASH, 0);
std::vector<unsigned char> vchGroupKey = GetGroup(); std::vector<unsigned char> vchGroupKey = GetGroup();
ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP); 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; return hash2 % ADDRMAN_TRIED_BUCKET_COUNT;
} }
@ -30,11 +30,11 @@ int CAddrInfo::GetNewBucket(const std::vector<unsigned char>& nKey, const CNetAd
std::vector<unsigned char> vchGroupKey = GetGroup(); std::vector<unsigned char> vchGroupKey = GetGroup();
std::vector<unsigned char> vchSourceGroupKey = src.GetGroup(); std::vector<unsigned char> vchSourceGroupKey = src.GetGroup();
ss1 << nKey << vchGroupKey << vchSourceGroupKey; 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); CDataStream ss2(SER_GETHASH, 0);
ss2 << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP); 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; return hash2 % ADDRMAN_NEW_BUCKET_COUNT;
} }

259
src/arith_uint256.cpp Normal file
View file

@ -0,0 +1,259 @@
// 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 "uint256.h"
#include "utilstrencodings.h"
#include <stdio.h>
#include <string.h>
template <unsigned int BITS>
base_uint<BITS>::base_uint(const std::string& str)
{
SetHex(str);
}
template <unsigned int BITS>
base_uint<BITS>& base_uint<BITS>::operator<<=(unsigned int shift)
{
base_uint<BITS> 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 <unsigned int BITS>
base_uint<BITS>& base_uint<BITS>::operator>>=(unsigned int shift)
{
base_uint<BITS> 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 <unsigned int BITS>
base_uint<BITS>& base_uint<BITS>::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 <unsigned int BITS>
base_uint<BITS>& base_uint<BITS>::operator*=(const base_uint& b)
{
base_uint<BITS> 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 <unsigned int BITS>
base_uint<BITS>& base_uint<BITS>::operator/=(const base_uint& b)
{
base_uint<BITS> div = b; // make a copy, so we can shift.
base_uint<BITS> 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 <unsigned int BITS>
int base_uint<BITS>::CompareTo(const base_uint<BITS>& 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 <unsigned int BITS>
bool base_uint<BITS>::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 <unsigned int BITS>
double base_uint<BITS>::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 <unsigned int BITS>
std::string base_uint<BITS>::GetHex() const
{
return ArithToUint256(*this).GetHex();
}
template <unsigned int BITS>
void base_uint<BITS>::SetHex(const char* psz)
{
*this = UintToArith256(uint256S(psz));
}
template <unsigned int BITS>
void base_uint<BITS>::SetHex(const std::string& str)
{
SetHex(str.c_str());
}
template <unsigned int BITS>
std::string base_uint<BITS>::ToString() const
{
return (GetHex());
}
template <unsigned int BITS>
unsigned int base_uint<BITS>::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<256>
template base_uint<256>::base_uint(const std::string&);
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;
}
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;
}

290
src/arith_uint256.h Normal file
View file

@ -0,0 +1,290 @@
// 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
#include <assert.h>
#include <cstring>
#include <stdexcept>
#include <stdint.h>
#include <string>
#include <vector>
class uint256;
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<unsigned int BITS>
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);
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 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;
}
};
/** 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) {}
/**
* 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;
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

View file

@ -191,7 +191,7 @@ static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput)
string strTxid = strInput.substr(0, pos); string strTxid = strInput.substr(0, pos);
if ((strTxid.size() != 64) || !IsHex(strTxid)) if ((strTxid.size() != 64) || !IsHex(strTxid))
throw runtime_error("invalid TX input txid"); throw runtime_error("invalid TX input txid");
uint256 txid(strTxid); uint256 txid(uint256S(strTxid));
static const unsigned int minTxOutSz = 9; static const unsigned int minTxOutSz = 9;
static const unsigned int maxVout = MAX_BLOCK_SIZE / minTxOutSz; static const unsigned int maxVout = MAX_BLOCK_SIZE / minTxOutSz;
@ -315,7 +315,7 @@ static bool findSighashFlags(int& flags, const string& flagStr)
uint256 ParseHashUO(map<string,UniValue>& o, string strKey) uint256 ParseHashUO(map<string,UniValue>& o, string strKey)
{ {
if (!o.count(strKey)) if (!o.count(strKey))
return 0; return uint256();
return ParseHashUV(o[strKey], strKey); return ParseHashUV(o[strKey], strKey);
} }
@ -485,7 +485,7 @@ static void MutateTx(CMutableTransaction& tx, const string& command,
static void OutputTxJSON(const CTransaction& tx) static void OutputTxJSON(const CTransaction& tx)
{ {
UniValue entry(UniValue::VOBJ); UniValue entry(UniValue::VOBJ);
TxToUniv(tx, 0, entry); TxToUniv(tx, uint256(), entry);
string jsonOutput = entry.write(4); string jsonOutput = entry.write(4);
fprintf(stdout, "%s\n", jsonOutput.c_str()); fprintf(stdout, "%s\n", jsonOutput.c_str());

View file

@ -6,6 +6,7 @@
#ifndef BITCOIN_CHAIN_H #ifndef BITCOIN_CHAIN_H
#define BITCOIN_CHAIN_H #define BITCOIN_CHAIN_H
#include "arith_uint256.h"
#include "primitives/block.h" #include "primitives/block.h"
#include "pow.h" #include "pow.h"
#include "tinyformat.h" #include "tinyformat.h"
@ -117,7 +118,7 @@ public:
unsigned int nUndoPos; unsigned int nUndoPos;
//! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block //! (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. //! Number of transactions in this block.
//! Note: in a potential headers-first mode, this number cannot be relied upon //! Note: in a potential headers-first mode, this number cannot be relied upon
@ -150,14 +151,14 @@ public:
nFile = 0; nFile = 0;
nDataPos = 0; nDataPos = 0;
nUndoPos = 0; nUndoPos = 0;
nChainWork = 0; nChainWork = arith_uint256();
nTx = 0; nTx = 0;
nChainTx = 0; nChainTx = 0;
nStatus = 0; nStatus = 0;
nSequenceId = 0; nSequenceId = 0;
nVersion = 0; nVersion = 0;
hashMerkleRoot = 0; hashMerkleRoot = uint256();
nTime = 0; nTime = 0;
nBits = 0; nBits = 0;
nNonce = 0; nNonce = 0;
@ -282,11 +283,11 @@ public:
uint256 hashPrev; uint256 hashPrev;
CDiskBlockIndex() { CDiskBlockIndex() {
hashPrev = 0; hashPrev = uint256();
} }
explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) { explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) {
hashPrev = (pprev ? pprev->GetBlockHash() : 0); hashPrev = (pprev ? pprev->GetBlockHash() : uint256());
} }
ADD_SERIALIZE_METHODS; ADD_SERIALIZE_METHODS;

View file

@ -54,19 +54,19 @@ static void convertSeed6(std::vector<CAddress> &vSeedsOut, const SeedSpec6 *data
*/ */
static Checkpoints::MapCheckpoints mapCheckpoints = static Checkpoints::MapCheckpoints mapCheckpoints =
boost::assign::map_list_of boost::assign::map_list_of
( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) ( 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) ( 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")) ( 74000, uint256S("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
(105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")) (105000, uint256S("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
(134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")) (134444, uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
(168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")) (168000, uint256S("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
(193000, uint256("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")) (193000, uint256S("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
(210000, uint256("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")) (210000, uint256S("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
(216116, uint256("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")) (216116, uint256S("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e"))
(225430, uint256("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")) (225430, uint256S("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932"))
(250000, uint256("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")) (250000, uint256S("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214"))
(279000, uint256("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")) (279000, uint256S("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40"))
(295000, uint256("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983")) (295000, uint256S("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983"))
; ;
static const Checkpoints::CCheckpointData data = { static const Checkpoints::CCheckpointData data = {
&mapCheckpoints, &mapCheckpoints,
@ -78,7 +78,7 @@ static const Checkpoints::CCheckpointData data = {
static Checkpoints::MapCheckpoints mapCheckpointsTestnet = static Checkpoints::MapCheckpoints mapCheckpointsTestnet =
boost::assign::map_list_of boost::assign::map_list_of
( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")) ( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
; ;
static const Checkpoints::CCheckpointData dataTestnet = { static const Checkpoints::CCheckpointData dataTestnet = {
&mapCheckpointsTestnet, &mapCheckpointsTestnet,
@ -89,7 +89,7 @@ static const Checkpoints::CCheckpointData dataTestnet = {
static Checkpoints::MapCheckpoints mapCheckpointsRegtest = static Checkpoints::MapCheckpoints mapCheckpointsRegtest =
boost::assign::map_list_of boost::assign::map_list_of
( 0, uint256("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")) ( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"))
; ;
static const Checkpoints::CCheckpointData dataRegtest = { static const Checkpoints::CCheckpointData dataRegtest = {
&mapCheckpointsRegtest, &mapCheckpointsRegtest,
@ -114,7 +114,7 @@ public:
pchMessageStart[3] = 0xd9; pchMessageStart[3] = 0xd9;
vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284");
nDefaultPort = 8333; nDefaultPort = 8333;
bnProofOfWorkLimit = ~uint256(0) >> 32; bnProofOfWorkLimit = ~arith_uint256(0) >> 32;
nSubsidyHalvingInterval = 210000; nSubsidyHalvingInterval = 210000;
nEnforceBlockUpgradeMajority = 750; nEnforceBlockUpgradeMajority = 750;
nRejectBlockOutdatedMajority = 950; nRejectBlockOutdatedMajority = 950;
@ -141,7 +141,7 @@ public:
txNew.vout[0].nValue = 50 * COIN; txNew.vout[0].nValue = 50 * COIN;
txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
genesis.vtx.push_back(txNew); genesis.vtx.push_back(txNew);
genesis.hashPrevBlock = 0; genesis.hashPrevBlock.SetNull();
genesis.hashMerkleRoot = genesis.BuildMerkleTree(); genesis.hashMerkleRoot = genesis.BuildMerkleTree();
genesis.nVersion = 1; genesis.nVersion = 1;
genesis.nTime = 1231006505; genesis.nTime = 1231006505;
@ -149,8 +149,8 @@ public:
genesis.nNonce = 2083236893; genesis.nNonce = 2083236893;
hashGenesisBlock = genesis.GetHash(); hashGenesisBlock = genesis.GetHash();
assert(hashGenesisBlock == uint256("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); assert(hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
assert(genesis.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be")); vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be"));
vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me")); vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me"));
@ -208,7 +208,7 @@ public:
genesis.nTime = 1296688602; genesis.nTime = 1296688602;
genesis.nNonce = 414098458; genesis.nNonce = 414098458;
hashGenesisBlock = genesis.GetHash(); hashGenesisBlock = genesis.GetHash();
assert(hashGenesisBlock == uint256("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943")); assert(hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"));
vFixedSeeds.clear(); vFixedSeeds.clear();
vSeeds.clear(); vSeeds.clear();
@ -259,13 +259,13 @@ public:
nMinerThreads = 1; nMinerThreads = 1;
nTargetTimespan = 14 * 24 * 60 * 60; //! two weeks nTargetTimespan = 14 * 24 * 60 * 60; //! two weeks
nTargetSpacing = 10 * 60; nTargetSpacing = 10 * 60;
bnProofOfWorkLimit = ~uint256(0) >> 1; bnProofOfWorkLimit = ~arith_uint256(0) >> 1;
genesis.nTime = 1296688602; genesis.nTime = 1296688602;
genesis.nBits = 0x207fffff; genesis.nBits = 0x207fffff;
genesis.nNonce = 2; genesis.nNonce = 2;
hashGenesisBlock = genesis.GetHash(); hashGenesisBlock = genesis.GetHash();
nDefaultPort = 18444; nDefaultPort = 18444;
assert(hashGenesisBlock == uint256("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); assert(hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds. vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds.
vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds. vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds.

View file

@ -10,7 +10,7 @@
#include "checkpoints.h" #include "checkpoints.h"
#include "primitives/block.h" #include "primitives/block.h"
#include "protocol.h" #include "protocol.h"
#include "uint256.h" #include "arith_uint256.h"
#include <vector> #include <vector>
@ -45,7 +45,7 @@ public:
const MessageStartChars& MessageStart() const { return pchMessageStart; } const MessageStartChars& MessageStart() const { return pchMessageStart; }
const std::vector<unsigned char>& AlertKey() const { return vAlertPubKey; } const std::vector<unsigned char>& AlertKey() const { return vAlertPubKey; }
int GetDefaultPort() const { return nDefaultPort; } int GetDefaultPort() const { return nDefaultPort; }
const uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; } const arith_uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; }
int SubsidyHalvingInterval() const { return nSubsidyHalvingInterval; } int SubsidyHalvingInterval() const { return nSubsidyHalvingInterval; }
/** Used to check majorities for block version upgrade */ /** Used to check majorities for block version upgrade */
int EnforceBlockUpgradeMajority() const { return nEnforceBlockUpgradeMajority; } int EnforceBlockUpgradeMajority() const { return nEnforceBlockUpgradeMajority; }
@ -87,7 +87,7 @@ protected:
//! Raw pub key bytes for the broadcast alert signing key. //! Raw pub key bytes for the broadcast alert signing key.
std::vector<unsigned char> vAlertPubKey; std::vector<unsigned char> vAlertPubKey;
int nDefaultPort; int nDefaultPort;
uint256 bnProofOfWorkLimit; arith_uint256 bnProofOfWorkLimit;
int nSubsidyHalvingInterval; int nSubsidyHalvingInterval;
int nEnforceBlockUpgradeMajority; int nEnforceBlockUpgradeMajority;
int nRejectBlockOutdatedMajority; int nRejectBlockOutdatedMajority;

View file

@ -42,7 +42,7 @@ bool CCoins::Spend(uint32_t nPos)
bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; } bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; }
bool CCoinsView::HaveCoins(const uint256 &txid) 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::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
bool CCoinsView::GetStats(CCoinsStats &stats) const { 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()) {} CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {}
CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false), hashBlock(0) { } CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false) { }
CCoinsViewCache::~CCoinsViewCache() CCoinsViewCache::~CCoinsViewCache()
{ {
@ -128,7 +128,7 @@ bool CCoinsViewCache::HaveCoins(const uint256 &txid) const {
} }
uint256 CCoinsViewCache::GetBestBlock() const { uint256 CCoinsViewCache::GetBestBlock() const {
if (hashBlock == uint256(0)) if (hashBlock.IsNull())
hashBlock = base->GetBestBlock(); hashBlock = base->GetBestBlock();
return hashBlock; return hashBlock;
} }

View file

@ -297,7 +297,7 @@ struct CCoinsStats
uint256 hashSerialized; uint256 hashSerialized;
CAmount nTotalAmount; 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) {}
}; };

View file

@ -127,7 +127,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry)
} }
entry.pushKV("vout", vout); entry.pushKV("vout", vout);
if (hashBlock != 0) if (!hashBlock.IsNull())
entry.pushKV("blockhash", hashBlock.GetHex()); 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". entry.pushKV("hex", EncodeHexTx(tx)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction".

View file

@ -4,6 +4,7 @@
#include "key.h" #include "key.h"
#include "arith_uint256.h"
#include "crypto/hmac_sha512.h" #include "crypto/hmac_sha512.h"
#include "crypto/rfc6979_hmac_sha256.h" #include "crypto/rfc6979_hmac_sha256.h"
#include "eccryptoverify.h" #include "eccryptoverify.h"
@ -81,10 +82,10 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, uint32_
do { do {
uint256 nonce; uint256 nonce;
prng.Generate((unsigned char*)&nonce, 32); prng.Generate((unsigned char*)&nonce, 32);
nonce += test_case; nonce = ArithToUint256(UintToArith256(nonce) + test_case);
int nSigLen = 72; int nSigLen = 72;
int ret = secp256k1_ecdsa_sign((const unsigned char*)&hash, (unsigned char*)&vchSig[0], &nSigLen, begin(), (unsigned char*)&nonce); int ret = secp256k1_ecdsa_sign((const unsigned char*)&hash, (unsigned char*)&vchSig[0], &nSigLen, begin(), (unsigned char*)&nonce);
nonce = 0; nonce = uint256();
if (ret) { if (ret) {
vchSig.resize(nSigLen); vchSig.resize(nSigLen);
return true; return true;
@ -116,7 +117,7 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig)
uint256 nonce; uint256 nonce;
prng.Generate((unsigned char*)&nonce, 32); prng.Generate((unsigned char*)&nonce, 32);
int ret = secp256k1_ecdsa_sign_compact((const unsigned char*)&hash, &vchSig[1], begin(), (unsigned char*)&nonce, &rec); int ret = secp256k1_ecdsa_sign_compact((const unsigned char*)&hash, &vchSig[1], begin(), (unsigned char*)&nonce, &rec);
nonce = 0; nonce = uint256();
if (ret) if (ret)
break; break;
} while(true); } while(true);

View file

@ -5,6 +5,7 @@
#include "main.h" #include "main.h"
#include "arith_uint256.h"
#include "addrman.h" #include "addrman.h"
#include "alert.h" #include "alert.h"
#include "chainparams.h" #include "chainparams.h"
@ -261,7 +262,7 @@ struct CNodeState {
nMisbehavior = 0; nMisbehavior = 0;
fShouldBan = false; fShouldBan = false;
pindexBestKnownBlock = NULL; pindexBestKnownBlock = NULL;
hashLastUnknownBlock = uint256(0); hashLastUnknownBlock.SetNull();
pindexLastCommonBlock = NULL; pindexLastCommonBlock = NULL;
fSyncStarted = false; fSyncStarted = false;
nStallingSince = 0; nStallingSince = 0;
@ -349,12 +350,12 @@ void ProcessBlockAvailability(NodeId nodeid) {
CNodeState *state = State(nodeid); CNodeState *state = State(nodeid);
assert(state != NULL); assert(state != NULL);
if (state->hashLastUnknownBlock != 0) { if (!state->hashLastUnknownBlock.IsNull()) {
BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock); BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock);
if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0) { if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0) {
if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork) if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
state->pindexBestKnownBlock = itOld->second; state->pindexBestKnownBlock = itOld->second;
state->hashLastUnknownBlock = uint256(0); state->hashLastUnknownBlock.SetNull();
} }
} }
} }
@ -1712,7 +1713,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
return false; return false;
// verify that the view's current state corresponds to the previous block // 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()); assert(hashPrevBlock == view.GetBestBlock());
// Special case for the genesis block, skipping connection of its transactions // Special case for the genesis block, skipping connection of its transactions
@ -1738,8 +1739,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 // two in the chain that violate it. This prevents exploiting the issue against nodes in their
// initial block download. // initial block download.
bool fEnforceBIP30 = (!pindex->phashBlock) || // Enforce on CreateNewBlock invocations which don't have a hash. bool fEnforceBIP30 = (!pindex->phashBlock) || // Enforce on CreateNewBlock invocations which don't have a hash.
!((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) || !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256S("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
(pindex->nHeight==91880 && pindex->GetBlockHash() == uint256("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721"))); (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256S("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
if (fEnforceBIP30) { if (fEnforceBIP30) {
BOOST_FOREACH(const CTransaction& tx, block.vtx) { BOOST_FOREACH(const CTransaction& tx, block.vtx) {
const CCoins* coins = view.AccessCoins(tx.GetHash()); const CCoins* coins = view.AccessCoins(tx.GetHash());
@ -2835,7 +2836,7 @@ boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char
CBlockIndex * InsertBlockIndex(uint256 hash) CBlockIndex * InsertBlockIndex(uint256 hash)
{ {
if (hash == 0) if (hash.IsNull())
return NULL; return NULL;
// Return existing // Return existing
@ -3369,7 +3370,7 @@ void static ProcessGetData(CNode* pfrom)
vector<CInv> vInv; vector<CInv> vInv;
vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash())); vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
pfrom->PushMessage("inv", vInv); pfrom->PushMessage("inv", vInv);
pfrom->hashContinue = 0; pfrom->hashContinue.SetNull();
} }
} }
} }
@ -3604,10 +3605,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// Use deterministic randomness to send to the same nodes for 24 hours // Use deterministic randomness to send to the same nodes for 24 hours
// at a time so the setAddrKnowns of the chosen nodes prevent repeats // at a time so the setAddrKnowns of the chosen nodes prevent repeats
static uint256 hashSalt; static uint256 hashSalt;
if (hashSalt == 0) if (hashSalt.IsNull())
hashSalt = GetRandHash(); hashSalt = GetRandHash();
uint64_t hashAddr = addr.GetHash(); 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)); hashRand = Hash(BEGIN(hashRand), END(hashRand));
multimap<uint256, CNode*> mapMix; multimap<uint256, CNode*> mapMix;
BOOST_FOREACH(CNode* pnode, vNodes) BOOST_FOREACH(CNode* pnode, vNodes)
@ -3616,7 +3617,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
continue; continue;
unsigned int nPointer; unsigned int nPointer;
memcpy(&nPointer, &pnode, sizeof(nPointer)); memcpy(&nPointer, &pnode, sizeof(nPointer));
uint256 hashKey = hashRand ^ nPointer; uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer);
hashKey = Hash(BEGIN(hashKey), END(hashKey)); hashKey = Hash(BEGIN(hashKey), END(hashKey));
mapMix.insert(make_pair(hashKey, pnode)); mapMix.insert(make_pair(hashKey, pnode));
} }
@ -3738,7 +3739,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
if (pindex) if (pindex)
pindex = chainActive.Next(pindex); pindex = chainActive.Next(pindex);
int nLimit = 500; 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)) for (; pindex; pindex = chainActive.Next(pindex))
{ {
if (pindex->GetBlockHash() == hashStop) if (pindex->GetBlockHash() == hashStop)
@ -3954,7 +3955,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
// from there instead. // from there instead.
LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight); 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 +4453,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
nSyncStarted++; nSyncStarted++;
CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader; CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight); 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,11 +4484,11 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
{ {
// 1/4 of tx invs blast to all immediately // 1/4 of tx invs blast to all immediately
static uint256 hashSalt; static uint256 hashSalt;
if (hashSalt == 0) if (hashSalt.IsNull())
hashSalt = GetRandHash(); hashSalt = GetRandHash();
uint256 hashRand = inv.hash ^ hashSalt; uint256 hashRand = ArithToUint256(UintToArith256(inv.hash) ^ UintToArith256(hashSalt));
hashRand = Hash(BEGIN(hashRand), END(hashRand)); hashRand = Hash(BEGIN(hashRand), END(hashRand));
bool fTrickleWait = ((hashRand & 3) != 0); bool fTrickleWait = ((UintToArith256(hashRand) & 3) != 0);
if (fTrickleWait) if (fTrickleWait)
{ {

View file

@ -106,7 +106,7 @@ static const unsigned char REJECT_CHECKPOINT = 0x43;
struct BlockHasher 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; extern CScript COINBASE_FLAGS;

View file

@ -76,7 +76,7 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns
if (nBitsUsed >= vBits.size()) { if (nBitsUsed >= vBits.size()) {
// overflowed the bits array - failure // overflowed the bits array - failure
fBad = true; fBad = true;
return 0; return uint256();
} }
bool fParentOfMatch = vBits[nBitsUsed++]; bool fParentOfMatch = vBits[nBitsUsed++];
if (height==0 || !fParentOfMatch) { if (height==0 || !fParentOfMatch) {
@ -84,7 +84,7 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns
if (nHashUsed >= vHash.size()) { if (nHashUsed >= vHash.size()) {
// overflowed the hash array - failure // overflowed the hash array - failure
fBad = true; fBad = true;
return 0; return uint256();
} }
const uint256 &hash = vHash[nHashUsed++]; const uint256 &hash = vHash[nHashUsed++];
if (height==0 && fParentOfMatch) // in case of height 0, we have a matched txid if (height==0 && fParentOfMatch) // in case of height 0, we have a matched txid
@ -128,16 +128,16 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) {
vMatch.clear(); vMatch.clear();
// An empty set will not work // An empty set will not work
if (nTransactions == 0) if (nTransactions == 0)
return 0; return uint256();
// check for excessively high numbers of transactions // 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 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 // there can never be more hashes provided than one for every txid
if (vHash.size() > nTransactions) 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 // 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()) if (vBits.size() < vHash.size())
return 0; return uint256();
// calculate height of tree // calculate height of tree
int nHeight = 0; int nHeight = 0;
while (CalcTreeWidth(nHeight) > 1) while (CalcTreeWidth(nHeight) > 1)
@ -147,12 +147,12 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) {
uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch); uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch);
// verify that no problems occured during the tree traversal // verify that no problems occured during the tree traversal
if (fBad) if (fBad)
return 0; return uint256();
// verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence) // 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) if ((nBitsUsed+7)/8 != (vBits.size()+7)/8)
return 0; return uint256();
// verify that all hashes were consumed // verify that all hashes were consumed
if (nHashUsed != vHash.size()) if (nHashUsed != vHash.size())
return 0; return uint256();
return hashMerkleRoot; return hashMerkleRoot;
} }

View file

@ -481,7 +481,7 @@ void static BitcoinMiner(CWallet *pwallet)
// Search // Search
// //
int64_t nStart = GetTime(); int64_t nStart = GetTime();
uint256 hashTarget = uint256().SetCompact(pblock->nBits); arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
uint256 hash; uint256 hash;
uint32_t nNonce = 0; uint32_t nNonce = 0;
uint32_t nOldNonce = 0; uint32_t nOldNonce = 0;
@ -493,7 +493,7 @@ void static BitcoinMiner(CWallet *pwallet)
// Check if something found // Check if something found
if (fFound) if (fFound)
{ {
if (hash <= hashTarget) if (UintToArith256(hash) <= hashTarget)
{ {
// Found a solution // Found a solution
pblock->nNonce = nNonce; pblock->nNonce = nNonce;

View file

@ -1949,7 +1949,7 @@ CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fIn
nRefCount = 0; nRefCount = 0;
nSendSize = 0; nSendSize = 0;
nSendOffset = 0; nSendOffset = 0;
hashContinue = 0; hashContinue = uint256();
nStartingHeight = -1; nStartingHeight = -1;
fGetAddr = false; fGetAddr = false;
fRelayTxes = false; fRelayTxes = false;

View file

@ -5,6 +5,7 @@
#include "pow.h" #include "pow.h"
#include "arith_uint256.h"
#include "chain.h" #include "chain.h"
#include "chainparams.h" #include "chainparams.h"
#include "primitives/block.h" #include "primitives/block.h"
@ -56,8 +57,8 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
nActualTimespan = Params().TargetTimespan()*4; nActualTimespan = Params().TargetTimespan()*4;
// Retarget // Retarget
uint256 bnNew; arith_uint256 bnNew;
uint256 bnOld; arith_uint256 bnOld;
bnNew.SetCompact(pindexLast->nBits); bnNew.SetCompact(pindexLast->nBits);
bnOld = bnNew; bnOld = bnNew;
bnNew *= nActualTimespan; bnNew *= nActualTimespan;
@ -79,7 +80,7 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits)
{ {
bool fNegative; bool fNegative;
bool fOverflow; bool fOverflow;
uint256 bnTarget; arith_uint256 bnTarget;
if (Params().SkipProofOfWorkCheck()) if (Params().SkipProofOfWorkCheck())
return true; return true;
@ -91,22 +92,22 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits)
return error("CheckProofOfWork() : nBits below minimum work"); return error("CheckProofOfWork() : nBits below minimum work");
// Check proof of work matches claimed amount // Check proof of work matches claimed amount
if (hash > bnTarget) if (UintToArith256(hash) > bnTarget)
return error("CheckProofOfWork() : hash doesn't match nBits"); return error("CheckProofOfWork() : hash doesn't match nBits");
return true; return true;
} }
uint256 GetBlockProof(const CBlockIndex& block) arith_uint256 GetBlockProof(const CBlockIndex& block)
{ {
uint256 bnTarget; arith_uint256 bnTarget;
bool fNegative; bool fNegative;
bool fOverflow; bool fOverflow;
bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
if (fNegative || fOverflow || bnTarget == 0) if (fNegative || fOverflow || bnTarget == 0)
return 0; return 0;
// We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 // 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, // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
// or ~bnTarget / (nTarget+1) + 1. // or ~bnTarget / (nTarget+1) + 1.
return (~bnTarget / (bnTarget + 1)) + 1; return (~bnTarget / (bnTarget + 1)) + 1;

View file

@ -11,11 +11,12 @@
class CBlockHeader; class CBlockHeader;
class CBlockIndex; class CBlockIndex;
class uint256; class uint256;
class arith_uint256;
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock); unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock);
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
bool CheckProofOfWork(uint256 hash, unsigned int nBits); bool CheckProofOfWork(uint256 hash, unsigned int nBits);
uint256 GetBlockProof(const CBlockIndex& block); arith_uint256 GetBlockProof(const CBlockIndex& block);
#endif // BITCOIN_POW_H #endif // BITCOIN_POW_H

View file

@ -74,7 +74,7 @@ uint256 CBlock::BuildMerkleTree(bool* fMutated) const
if (fMutated) { if (fMutated) {
*fMutated = mutated; *fMutated = mutated;
} }
return (vMerkleTree.empty() ? 0 : vMerkleTree.back()); return (vMerkleTree.empty() ? uint256() : vMerkleTree.back());
} }
std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const
@ -96,7 +96,7 @@ std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const
uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex) uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
{ {
if (nIndex == -1) if (nIndex == -1)
return 0; return uint256();
for (std::vector<uint256>::const_iterator it(vMerkleBranch.begin()); it != vMerkleBranch.end(); ++it) for (std::vector<uint256>::const_iterator it(vMerkleBranch.begin()); it != vMerkleBranch.end(); ++it)
{ {
if (nIndex & 1) if (nIndex & 1)

View file

@ -53,8 +53,8 @@ public:
void SetNull() void SetNull()
{ {
nVersion = CBlockHeader::CURRENT_VERSION; nVersion = CBlockHeader::CURRENT_VERSION;
hashPrevBlock = 0; hashPrevBlock.SetNull();
hashMerkleRoot = 0; hashMerkleRoot.SetNull();
nTime = 0; nTime = 0;
nBits = 0; nBits = 0;
nNonce = 0; nNonce = 0;

View file

@ -72,7 +72,7 @@ void CTransaction::UpdateHash() const
*const_cast<uint256*>(&hash) = SerializeHash(*this); *const_cast<uint256*>(&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) { CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {
UpdateHash(); UpdateHash();

View file

@ -28,8 +28,8 @@ public:
READWRITE(FLATDATA(*this)); READWRITE(FLATDATA(*this));
} }
void SetNull() { hash = 0; n = (uint32_t) -1; } void SetNull() { hash.SetNull(); n = (uint32_t) -1; }
bool IsNull() const { return (hash == 0 && n == (uint32_t) -1); } bool IsNull() const { return (hash.IsNull() && n == (uint32_t) -1); }
friend bool operator<(const COutPoint& a, const COutPoint& b) friend bool operator<(const COutPoint& a, const COutPoint& b)
{ {

View file

@ -96,7 +96,7 @@ void CAddress::Init()
CInv::CInv() CInv::CInv()
{ {
type = 0; type = 0;
hash = 0; hash.SetNull();
} }
CInv::CInv(int typeIn, const uint256& hashIn) CInv::CInv(int typeIn, const uint256& hashIn)

View file

@ -27,7 +27,7 @@
class CKeyID : public uint160 class CKeyID : public uint160
{ {
public: public:
CKeyID() : uint160(0) {} CKeyID() : uint160() {}
CKeyID(const uint160& in) : uint160(in) {} CKeyID(const uint160& in) : uint160(in) {}
}; };

View file

@ -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) 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); 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); lockAction->setEnabled(false);
unlockAction->setEnabled(true); unlockAction->setEnabled(true);
@ -272,7 +272,7 @@ void CoinControlDialog::lockCoin()
if (contextMenuItem->checkState(COLUMN_CHECKBOX) == Qt::Checked) if (contextMenuItem->checkState(COLUMN_CHECKBOX) == Qt::Checked)
contextMenuItem->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); 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); model->lockCoin(outpt);
contextMenuItem->setDisabled(true); contextMenuItem->setDisabled(true);
contextMenuItem->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed")); contextMenuItem->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed"));
@ -282,7 +282,7 @@ void CoinControlDialog::lockCoin()
// context menu action: unlock coin // context menu action: unlock coin
void CoinControlDialog::unlockCoin() 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); model->unlockCoin(outpt);
contextMenuItem->setDisabled(false); contextMenuItem->setDisabled(false);
contextMenuItem->setIcon(COLUMN_CHECKBOX, QIcon()); 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) 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) if (item->checkState(COLUMN_CHECKBOX) == Qt::Unchecked)
coinControl->UnSelect(outpt); coinControl->UnSelect(outpt);

View file

@ -240,7 +240,7 @@ static bool rest_tx(AcceptedConnection* conn,
throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
CTransaction tx; CTransaction tx;
uint256 hashBlock = 0; uint256 hashBlock = uint256();
if (!GetTransaction(hash, tx, hashBlock, true)) if (!GetTransaction(hash, tx, hashBlock, true))
throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found"); throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found");

View file

@ -70,7 +70,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDe
if(txDetails) if(txDetails)
{ {
Object objTx; Object objTx;
TxToJSON(tx, uint256(0), objTx); TxToJSON(tx, uint256(), objTx);
txs.push_back(objTx); txs.push_back(objTx);
} }
else else
@ -278,7 +278,7 @@ Value getblock(const Array& params, bool fHelp)
); );
std::string strHash = params[0].get_str(); std::string strHash = params[0].get_str();
uint256 hash(strHash); uint256 hash(uint256S(strHash));
bool fVerbose = true; bool fVerbose = true;
if (params.size() > 1) if (params.size() > 1)
@ -383,7 +383,7 @@ Value gettxout(const Array& params, bool fHelp)
Object ret; Object ret;
std::string strHash = params[0].get_str(); std::string strHash = params[0].get_str();
uint256 hash(strHash); uint256 hash(uint256S(strHash));
int n = params[1].get_int(); int n = params[1].get_int();
bool fMempool = true; bool fMempool = true;
if (params.size() > 2) if (params.size() > 2)
@ -619,7 +619,7 @@ Value invalidateblock(const Array& params, bool fHelp)
); );
std::string strHash = params[0].get_str(); std::string strHash = params[0].get_str();
uint256 hash(strHash); uint256 hash(uint256S(strHash));
CValidationState state; CValidationState state;
{ {
@ -658,7 +658,7 @@ Value reconsiderblock(const Array& params, bool fHelp)
); );
std::string strHash = params[0].get_str(); std::string strHash = params[0].get_str();
uint256 hash(strHash); uint256 hash(uint256S(strHash));
CValidationState state; CValidationState state;
{ {

View file

@ -64,7 +64,7 @@ Value GetNetworkHashPS(int lookup, int height) {
if (minTime == maxTime) if (minTime == maxTime)
return 0; return 0;
uint256 workDiff = pb->nChainWork - pb0->nChainWork; arith_uint256 workDiff = pb->nChainWork - pb0->nChainWork;
int64_t timeDiff = maxTime - minTime; int64_t timeDiff = maxTime - minTime;
return (int64_t)(workDiff.getdouble() / timeDiff); return (int64_t)(workDiff.getdouble() / timeDiff);
@ -562,7 +562,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
Object aux; Object aux;
aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); 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; static Array aMutable;
if (aMutable.empty()) if (aMutable.empty())

View file

@ -89,7 +89,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
} }
entry.push_back(Pair("vout", vout)); entry.push_back(Pair("vout", vout));
if (hashBlock != 0) { if (!hashBlock.IsNull()) {
entry.push_back(Pair("blockhash", hashBlock.GetHex())); entry.push_back(Pair("blockhash", hashBlock.GetHex()));
BlockMap::iterator mi = mapBlockIndex.find(hashBlock); BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
if (mi != mapBlockIndex.end() && (*mi).second) { if (mi != mapBlockIndex.end() && (*mi).second) {
@ -178,7 +178,7 @@ Value getrawtransaction(const Array& params, bool fHelp)
fVerbose = (params[1].get_int() != 0); fVerbose = (params[1].get_int() != 0);
CTransaction tx; CTransaction tx;
uint256 hashBlock = 0; uint256 hashBlock;
if (!GetTransaction(hash, tx, hashBlock, true)) if (!GetTransaction(hash, tx, hashBlock, true))
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); 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"); throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
Object result; Object result;
TxToJSON(tx, 0, result); TxToJSON(tx, uint256(), result);
return result; return result;
} }

View file

@ -1477,7 +1477,7 @@ Value listsinceblock(const Array& params, bool fHelp)
if (params.size() > 0) if (params.size() > 0)
{ {
uint256 blockId = 0; uint256 blockId;
blockId.SetHex(params[0].get_str()); blockId.SetHex(params[0].get_str());
BlockMap::iterator it = mapBlockIndex.find(blockId); 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]; CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms];
uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : 0; uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256();
Object ret; Object ret;
ret.push_back(Pair("transactions", transactions)); ret.push_back(Pair("transactions", transactions));
@ -1902,7 +1902,7 @@ Value lockunspent(const Array& params, bool fHelp)
if (nOutput < 0) if (nOutput < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive"); throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
COutPoint outpt(uint256(txid), nOutput); COutPoint outpt(uint256S(txid), nOutput);
if (fUnlock) if (fUnlock)
pwalletMain->UnlockCoin(outpt); pwalletMain->UnlockCoin(outpt);

View file

@ -1030,16 +1030,17 @@ public:
uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
{ {
static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
if (nIn >= txTo.vin.size()) { if (nIn >= txTo.vin.size()) {
// nIn out of range // nIn out of range
return 1; return one;
} }
// Check for invalid use of SIGHASH_SINGLE // Check for invalid use of SIGHASH_SINGLE
if ((nHashType & 0x1f) == SIGHASH_SINGLE) { if ((nHashType & 0x1f) == SIGHASH_SINGLE) {
if (nIn >= txTo.vout.size()) { if (nIn >= txTo.vout.size()) {
// nOut out of range // nOut out of range
return 1; return one;
} }
} }

View file

@ -20,7 +20,7 @@ class CScript;
class CScriptID : public uint160 class CScriptID : public uint160
{ {
public: public:
CScriptID() : uint160(0) {} CScriptID() : uint160() {}
CScriptID(const CScript& in); CScriptID(const CScript& in);
CScriptID(const uint160& in) : uint160(in) {} CScriptID(const uint160& in) : uint160(in) {}
}; };

View file

@ -18,8 +18,8 @@ BOOST_AUTO_TEST_SUITE(Checkpoints_tests)
BOOST_AUTO_TEST_CASE(sanity) BOOST_AUTO_TEST_CASE(sanity)
{ {
uint256 p11111 = uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"); uint256 p11111 = uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d");
uint256 p134444 = uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"); uint256 p134444 = uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe");
BOOST_CHECK(Checkpoints::CheckBlock(11111, p11111)); BOOST_CHECK(Checkpoints::CheckBlock(11111, p11111));
BOOST_CHECK(Checkpoints::CheckBlock(134444, p134444)); BOOST_CHECK(Checkpoints::CheckBlock(134444, p134444));

View file

@ -0,0 +1,566 @@
// 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 <boost/test/unit_test.hpp>
#include <stdint.h>
#include <sstream>
#include <iomanip>
#include <limits>
#include <cmath>
#include "uint256.h"
#include "arith_uint256.h"
#include <string>
#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<unsigned char>& 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_uint256V(std::vector<unsigned char>(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_uint256V(std::vector<unsigned char>(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_uint256V(std::vector<unsigned char>(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_uint256V(std::vector<unsigned char>(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_uint256V(std::vector<unsigned char>(MaxArray,MaxArray+32));
const arith_uint256 HalfL = (OneL << 255);
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<<std::setw(2)<<std::setfill('0')<<(unsigned int)A[width-i-1];
}
return Stream.str();
}
BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality
{
BOOST_CHECK(1 == 0+1);
// constructor arith_uint256(vector<char>):
BOOST_CHECK(R1L.ToString() == ArrayToString(R1Array,32));
BOOST_CHECK(R2L.ToString() == ArrayToString(R2Array,32));
BOOST_CHECK(ZeroL.ToString() == ArrayToString(ZeroArray,32));
BOOST_CHECK(OneL.ToString() == ArrayToString(OneArray,32));
BOOST_CHECK(MaxL.ToString() == ArrayToString(MaxArray,32));
BOOST_CHECK(OneL.ToString() != ArrayToString(ZeroArray,32));
// == and !=
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);
uint64_t Tmp64 = 0xc4dab720d9c7acaaULL;
for (unsigned int i = 0; i < 256; ++i)
{
BOOST_CHECK(ZeroL != (OneL << i));
BOOST_CHECK((OneL << i) != ZeroL);
BOOST_CHECK(R1L != (R1L ^ (OneL << i)));
BOOST_CHECK(((arith_uint256(Tmp64) ^ (OneL << i) ) != Tmp64 ));
}
BOOST_CHECK(ZeroL == (OneL << 256));
// String Constructor and Copy Constructor
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);
// 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));
// Assignment (from base_uint)
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);
}
void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift)
{
for (unsigned int T=0; T < arrayLength; ++T)
{
unsigned int F = (T+bitsToShift/8);
if (F < arrayLength)
to[T] = from[F] >> (bitsToShift%8);
else
to[T] = 0;
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)
{
for (unsigned int T=0; T < arrayLength; ++T)
{
if (T >= bitsToShift/8)
{
unsigned int F = T-bitsToShift/8;
to[T] = from[F] << (bitsToShift%8);
if (T >= bitsToShift/8+1)
to[T] |= from[F-1] >> (8-bitsToShift%8);
}
else {
to[T] = 0;
}
}
}
BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>="
unsigned char TmpArray[32];
arith_uint256 TmpL;
for (unsigned int i = 0; i < 256; ++i)
{
shiftArrayLeft(TmpArray, OneArray, 32, i);
BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(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(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (R1L << i));
TmpL = R1L; TmpL <<= i;
BOOST_CHECK(TmpL == (R1L << i));
shiftArrayRight(TmpArray, R1Array, 32, i);
BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (R1L >> i));
TmpL = R1L; TmpL >>= i;
BOOST_CHECK(TmpL == (R1L >> i));
shiftArrayLeft(TmpArray, MaxArray, 32, i);
BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (MaxL << i));
TmpL = MaxL; TmpL <<= i;
BOOST_CHECK(TmpL == (MaxL << i));
shiftArrayRight(TmpArray, MaxArray, 32, i);
BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (MaxL >> i));
TmpL = MaxL; TmpL >>= i;
BOOST_CHECK(TmpL == (MaxL >> i));
}
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)));
}
for (unsigned int i = 128; i < 256; ++i) {
BOOST_CHECK((c1L << i) == (c2L << (i-128)));
}
}
BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ -
{
BOOST_CHECK(!ZeroL);
BOOST_CHECK(!(!OneL));
for (unsigned int i = 0; i < 256; ++i)
BOOST_CHECK(!(!(OneL<<i)));
BOOST_CHECK(!(!R1L));
BOOST_CHECK(!(!MaxL));
BOOST_CHECK(~ZeroL == MaxL);
unsigned char TmpArray[32];
for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = ~R1Array[i]; }
BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (~R1L));
BOOST_CHECK(-ZeroL == ZeroL);
BOOST_CHECK(-R1L == (~R1L)+1);
for (unsigned int i = 0; i < 256; ++i)
BOOST_CHECK(-(OneL<<i) == (MaxL << i));
}
// Check if doing _A_ _OP_ _B_ results in the same as applying _OP_ onto each
// 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_uint256V(std::vector<unsigned char>(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));
BOOST_AUTO_TEST_CASE( bitwiseOperators )
{
unsigned char TmpArray[32];
CHECKBITWISEOPERATOR(R1,R2,|)
CHECKBITWISEOPERATOR(R1,R2,^)
CHECKBITWISEOPERATOR(R1,R2,&)
CHECKBITWISEOPERATOR(R1,Zero,|)
CHECKBITWISEOPERATOR(R1,Zero,^)
CHECKBITWISEOPERATOR(R1,Zero,&)
CHECKBITWISEOPERATOR(R1,Max,|)
CHECKBITWISEOPERATOR(R1,Max,^)
CHECKBITWISEOPERATOR(R1,Max,&)
CHECKBITWISEOPERATOR(Zero,R1,|)
CHECKBITWISEOPERATOR(Zero,R1,^)
CHECKBITWISEOPERATOR(Zero,R1,&)
CHECKBITWISEOPERATOR(Max,R1,|)
CHECKBITWISEOPERATOR(Max,R1,^)
CHECKBITWISEOPERATOR(Max,R1,&)
arith_uint256 TmpL;
CHECKASSIGNMENTOPERATOR(R1,R2,|)
CHECKASSIGNMENTOPERATOR(R1,R2,^)
CHECKASSIGNMENTOPERATOR(R1,R2,&)
CHECKASSIGNMENTOPERATOR(R1,Zero,|)
CHECKASSIGNMENTOPERATOR(R1,Zero,^)
CHECKASSIGNMENTOPERATOR(R1,Zero,&)
CHECKASSIGNMENTOPERATOR(R1,Max,|)
CHECKASSIGNMENTOPERATOR(R1,Max,^)
CHECKASSIGNMENTOPERATOR(R1,Max,&)
CHECKASSIGNMENTOPERATOR(Zero,R1,|)
CHECKASSIGNMENTOPERATOR(Zero,R1,^)
CHECKASSIGNMENTOPERATOR(Zero,R1,&)
CHECKASSIGNMENTOPERATOR(Max,R1,|)
CHECKASSIGNMENTOPERATOR(Max,R1,^)
CHECKASSIGNMENTOPERATOR(Max,R1,&)
uint64_t Tmp64 = 0xe1db685c9a0b47a2ULL;
TmpL = R1L; TmpL |= Tmp64; BOOST_CHECK(TmpL == (R1L | arith_uint256(Tmp64)));
TmpL = R1L; TmpL |= 0; BOOST_CHECK(TmpL == R1L);
TmpL ^= 0; BOOST_CHECK(TmpL == R1L);
TmpL ^= Tmp64; BOOST_CHECK(TmpL == (R1L ^ arith_uint256(Tmp64)));
}
BOOST_AUTO_TEST_CASE( comparison ) // <= >= < >
{
arith_uint256 TmpL;
for (unsigned int i = 0; i < 256; ++i) {
TmpL= OneL<< i;
BOOST_CHECK( TmpL >= ZeroL && TmpL > ZeroL && ZeroL < TmpL && ZeroL <= TmpL);
BOOST_CHECK( TmpL >= 0 && TmpL > 0 && 0 < TmpL && 0 <= TmpL);
TmpL |= R1L;
BOOST_CHECK( TmpL >= R1L ); BOOST_CHECK( (TmpL == R1L) != (TmpL > R1L)); BOOST_CHECK( (TmpL == R1L) || !( TmpL <= R1L));
BOOST_CHECK( R1L <= TmpL ); BOOST_CHECK( (R1L == TmpL) != (R1L < TmpL)); BOOST_CHECK( (TmpL == R1L) || !( R1L >= TmpL));
BOOST_CHECK(! (TmpL < R1L)); BOOST_CHECK(! (R1L > TmpL));
}
}
BOOST_AUTO_TEST_CASE( plusMinus )
{
arith_uint256 TmpL = 0;
BOOST_CHECK(R1L+R2L == arith_uint256(R1LplusR2L));
TmpL += R1L;
BOOST_CHECK(TmpL == R1L);
TmpL += R2L;
BOOST_CHECK(TmpL == R1L + R2L);
BOOST_CHECK(OneL+MaxL == ZeroL);
BOOST_CHECK(MaxL+OneL == ZeroL);
for (unsigned int i = 1; i < 256; ++i) {
BOOST_CHECK( (MaxL >> i) + OneL == (HalfL >> (i-1)) );
BOOST_CHECK( OneL + (MaxL >> i) == (HalfL >> (i-1)) );
TmpL = (MaxL>>i); TmpL += OneL;
BOOST_CHECK( TmpL == (HalfL >> (i-1)) );
TmpL = (MaxL>>i); TmpL += 1;
BOOST_CHECK( TmpL == (HalfL >> (i-1)) );
TmpL = (MaxL>>i);
BOOST_CHECK( TmpL++ == (MaxL>>i) );
BOOST_CHECK( TmpL == (HalfL >> (i-1)));
}
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);
BOOST_CHECK(R1L -(-R2L) == R1L+R2L);
BOOST_CHECK(R1L -(-OneL) == R1L+OneL);
BOOST_CHECK(R1L - OneL == R1L+(-OneL));
for (unsigned int i = 1; i < 256; ++i) {
BOOST_CHECK((MaxL>>i) - (-OneL) == (HalfL >> (i-1)));
BOOST_CHECK((HalfL >> (i-1)) - OneL == (MaxL>>i));
TmpL = (HalfL >> (i-1));
BOOST_CHECK(TmpL-- == (HalfL >> (i-1)));
BOOST_CHECK(TmpL == (MaxL >> i));
TmpL = (HalfL >> (i-1));
BOOST_CHECK(--TmpL == (MaxL >> i));
}
TmpL = R1L;
BOOST_CHECK(--TmpL == R1L-1);
}
BOOST_AUTO_TEST_CASE( multiply )
{
BOOST_CHECK((R1L * R1L).ToString() == "62a38c0486f01e45879d7910a7761bf30d5237e9873f9bff3642a732c4d84f10");
BOOST_CHECK((R1L * R2L).ToString() == "de37805e9986996cfba76ff6ba51c008df851987d9dd323f0e5de07760529c40");
BOOST_CHECK((R1L * ZeroL) == ZeroL);
BOOST_CHECK((R1L * OneL) == R1L);
BOOST_CHECK((R1L * MaxL) == -R1L);
BOOST_CHECK((R2L * R1L) == (R1L * R2L));
BOOST_CHECK((R2L * R2L).ToString() == "ac8c010096767d3cae5005dec28bb2b45a1d85ab7996ccd3e102a650f74ff100");
BOOST_CHECK((R2L * ZeroL) == ZeroL);
BOOST_CHECK((R2L * OneL) == R2L);
BOOST_CHECK((R2L * MaxL) == -R2L);
BOOST_CHECK(MaxL * MaxL == OneL);
BOOST_CHECK((R1L * 0) == 0);
BOOST_CHECK((R1L * 1) == R1L);
BOOST_CHECK((R1L * 3).ToString() == "7759b1c0ed14047f961ad09b20ff83687876a0181a367b813634046f91def7d4");
BOOST_CHECK((R2L * 0x87654321UL).ToString() == "23f7816e30c4ae2017257b7a0fa64d60402f5234d46e746b61c960d09a26d070");
}
BOOST_AUTO_TEST_CASE( divide )
{
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);
BOOST_CHECK(R1L / MaxL == ZeroL);
BOOST_CHECK(MaxL / R1L == 2);
BOOST_CHECK_THROW(R1L / ZeroL, uint_error);
BOOST_CHECK((R2L / D1L).ToString() == "000000000000000013e1665895a1cc981de6d93670105a6b3ec3b73141b3a3c5");
BOOST_CHECK((R2L / D2L).ToString() == "000000000e8f0abe753bb0afe2e9437ee85d280be60882cf0bd1aaf7fa3cc2c4");
BOOST_CHECK(R2L / OneL == R2L);
BOOST_CHECK(R2L / MaxL == ZeroL);
BOOST_CHECK(MaxL / R2L == 1);
BOOST_CHECK_THROW(R2L / ZeroL, uint_error);
}
bool almostEqual(double d1, double d2)
{
return fabs(d1-d2) <= 4*fabs(d1)*std::numeric_limits<double>::epsilon();
}
BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex 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());
arith_uint256 TmpL(R1L);
BOOST_CHECK(TmpL == R1L);
TmpL.SetHex(R2L.ToString()); BOOST_CHECK(TmpL == R2L);
TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK(TmpL == 0);
TmpL.SetHex(HalfL.ToString()); BOOST_CHECK(TmpL == HalfL);
TmpL.SetHex(R1L.ToString());
BOOST_CHECK(R1L.size() == 32);
BOOST_CHECK(R2L.size() == 32);
BOOST_CHECK(ZeroL.size() == 32);
BOOST_CHECK(MaxL.size() == 32);
BOOST_CHECK(R1L.GetLow64() == R1LLow64);
BOOST_CHECK(HalfL.GetLow64() ==0x0000000000000000ULL);
BOOST_CHECK(OneL.GetLow64() ==0x0000000000000001ULL);
for (unsigned int i = 0; i < 255; ++i)
{
BOOST_CHECK((OneL << i).getdouble() == ldexp(1.0,i));
}
BOOST_CHECK(ZeroL.getdouble() == 0.0);
for (int i = 256; i > 53; --i)
BOOST_CHECK(almostEqual((R1L>>(256-i)).getdouble(), ldexp(R1Ldouble,i)));
uint64_t R1L64part = (R1L>>192).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_AUTO_TEST_CASE(bignum_SetCompact)
{
arith_uint256 num;
bool fNegative;
bool fOverflow;
num.SetCompact(0, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x00123456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x01003456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x02000056, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x03000000, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x04000000, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x00923456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x01803456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x02800056, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x03800000, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x04800000, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x01123456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000012");
BOOST_CHECK_EQUAL(num.GetCompact(), 0x01120000U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
// Make sure that we don't generate compacts with the 0x00800000 bit set
num = 0x80;
BOOST_CHECK_EQUAL(num.GetCompact(), 0x02008000U);
num.SetCompact(0x01fedcba, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "000000000000000000000000000000000000000000000000000000000000007e");
BOOST_CHECK_EQUAL(num.GetCompact(true), 0x01fe0000U);
BOOST_CHECK_EQUAL(fNegative, true);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x02123456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000001234");
BOOST_CHECK_EQUAL(num.GetCompact(), 0x02123400U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x03123456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000123456");
BOOST_CHECK_EQUAL(num.GetCompact(), 0x03123456U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x04123456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000012345600");
BOOST_CHECK_EQUAL(num.GetCompact(), 0x04123456U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x04923456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000012345600");
BOOST_CHECK_EQUAL(num.GetCompact(true), 0x04923456U);
BOOST_CHECK_EQUAL(fNegative, true);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x05009234, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000092340000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0x05009234U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x20123456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "1234560000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0x20123456U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0xff123456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, true);
}
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((~~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(~~R1L - R2L == R1L - ~~R2L);
BOOST_CHECK(~R1L != R1L); BOOST_CHECK(R1L != ~R1L);
unsigned char TmpArray[32];
CHECKBITWISEOPERATOR(~R1,R2,|)
CHECKBITWISEOPERATOR(~R1,R2,^)
CHECKBITWISEOPERATOR(~R1,R2,&)
CHECKBITWISEOPERATOR(R1,~R2,|)
CHECKBITWISEOPERATOR(R1,~R2,^)
CHECKBITWISEOPERATOR(R1,~R2,&)
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -125,7 +125,7 @@ BOOST_AUTO_TEST_CASE(bloom_match)
spendStream >> spendingTx; spendStream >> spendingTx;
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL); 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"); BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match tx hash");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); 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"); BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match output address");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); 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"); BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match COutPoint");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
COutPoint prevOutPoint(uint256("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0); COutPoint prevOutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0);
{ {
vector<unsigned char> data(32 + sizeof(unsigned int)); vector<unsigned char> data(32 + sizeof(unsigned int));
memcpy(&data[0], prevOutPoint.hash.begin(), 32); 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"); 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 = 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"); BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched random tx hash");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); 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"); BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched random address");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); 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"); 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 = 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"); 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); CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// Match the last transaction // Match the last transaction
filter.insert(uint256("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20")); filter.insert(uint256S("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"));
CMerkleBlock merkleBlock(block, filter); CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1)
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0]; pair<unsigned int, uint256> 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); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 8);
vector<uint256> vMatched; vector<uint256> vMatched;
@ -209,7 +209,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1)
BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second); BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
// Also match the 8th transaction // Also match the 8th transaction
filter.insert(uint256("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053")); filter.insert(uint256S("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053"));
merkleBlock = CMerkleBlock(block, filter); merkleBlock = CMerkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); 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[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.vMatchedTxn[0].first == 7);
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); 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); CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// Match the first transaction // Match the first transaction
filter.insert(uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); filter.insert(uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
CMerkleBlock merkleBlock(block, filter); CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
@ -244,7 +244,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_2)
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0]; pair<unsigned int, uint256> 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); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
vector<uint256> vMatched; vector<uint256> vMatched;
@ -265,13 +265,13 @@ BOOST_AUTO_TEST_CASE(merkle_block_2)
BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]); 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[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[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.vMatchedTxn[3].first == 3);
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); 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); CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_NONE);
// Match the first transaction // Match the first transaction
filter.insert(uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); filter.insert(uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
CMerkleBlock merkleBlock(block, filter); CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); 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); BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0]; pair<unsigned int, uint256> 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); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
vector<uint256> vMatched; vector<uint256> vMatched;
@ -319,10 +319,10 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none)
BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]); 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[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.vMatchedTxn[2].first == 3);
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot); 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); CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// Match the only transaction // Match the only transaction
filter.insert(uint256("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5")); filter.insert(uint256S("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"));
CMerkleBlock merkleBlock(block, filter); CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); 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); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
vector<uint256> vMatched; vector<uint256> vMatched;
@ -379,7 +379,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_4)
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL); CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// Match the last transaction // Match the last transaction
filter.insert(uint256("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154")); filter.insert(uint256S("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154"));
CMerkleBlock merkleBlock(block, filter); CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
@ -387,7 +387,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_4)
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0]; pair<unsigned int, uint256> 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); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 6);
vector<uint256> vMatched; vector<uint256> vMatched;
@ -397,13 +397,13 @@ BOOST_AUTO_TEST_CASE(merkle_block_4)
BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second); BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
// Also match the 4th transaction // Also match the 4th transaction
filter.insert(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041")); filter.insert(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"));
merkleBlock = CMerkleBlock(block, filter); merkleBlock = CMerkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 2); 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[0].first == 3);
BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair); 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()); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
// We should match the generation outpoint // 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) // ... 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) 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()); BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
// We shouldn't match any outpoints (UPDATE_NONE) // We shouldn't match any outpoints (UPDATE_NONE)
BOOST_CHECK(!filter.contains(COutPoint(uint256("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0))); BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0)));
BOOST_CHECK(!filter.contains(COutPoint(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0))); BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0)));
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View file

@ -6,6 +6,7 @@
#include "serialize.h" #include "serialize.h"
#include "streams.h" #include "streams.h"
#include "uint256.h" #include "uint256.h"
#include "arith_uint256.h"
#include "version.h" #include "version.h"
#include <vector> #include <vector>
@ -22,8 +23,7 @@ public:
void Damage() { void Damage() {
unsigned int n = rand() % vHash.size(); unsigned int n = rand() % vHash.size();
int bit = rand() % 256; int bit = rand() % 256;
uint256 &hash = vHash[n]; *(vHash[n].begin() + (bit>>3)) ^= 1<<(bit&7);
hash ^= ((uint256)1 << bit);
} }
}; };
@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
// calculate actual merkle root and height // calculate actual merkle root and height
uint256 merkleRoot1 = block.BuildMerkleTree(); uint256 merkleRoot1 = block.BuildMerkleTree();
std::vector<uint256> vTxid(nTx, 0); std::vector<uint256> vTxid(nTx, uint256());
for (unsigned int j=0; j<nTx; j++) for (unsigned int j=0; j<nTx; j++)
vTxid[j] = block.vtx[j].GetHash(); vTxid[j] = block.vtx[j].GetHash();
int nHeight = 1, nTx_ = nTx; int nHeight = 1, nTx_ = nTx;
@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
// check that it has the same merkle root as the original, and a valid one // check that it has the same merkle root as the original, and a valid one
BOOST_CHECK(merkleRoot1 == merkleRoot2); BOOST_CHECK(merkleRoot1 == merkleRoot2);
BOOST_CHECK(merkleRoot2 != 0); BOOST_CHECK(!merkleRoot2.IsNull());
// check that it contains the matched transactions (in the same order!) // check that it contains the matched transactions (in the same order!)
BOOST_CHECK(vMatchTxid1 == vMatchTxid2); BOOST_CHECK(vMatchTxid1 == vMatchTxid2);
@ -107,12 +107,18 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
BOOST_AUTO_TEST_CASE(pmt_malleability) BOOST_AUTO_TEST_CASE(pmt_malleability)
{ {
std::vector<uint256> vTxid = boost::assign::list_of(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(9)(10); std::vector<uint256> 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<bool> vMatch = boost::assign::list_of(false)(false)(false)(false)(false)(false)(false)(false)(false)(true)(true)(false); std::vector<bool> vMatch = boost::assign::list_of(false)(false)(false)(false)(false)(false)(false)(false)(false)(true)(true)(false);
CPartialMerkleTree tree(vTxid, vMatch); CPartialMerkleTree tree(vTxid, vMatch);
std::vector<uint256> vTxid2; std::vector<uint256> vTxid2;
BOOST_CHECK(tree.ExtractMatches(vTxid) == 0); BOOST_CHECK(tree.ExtractMatches(vTxid).IsNull());
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View file

@ -210,7 +210,7 @@ BOOST_AUTO_TEST_CASE(set)
BOOST_AUTO_TEST_CASE(is) BOOST_AUTO_TEST_CASE(is)
{ {
// Test CScript::IsPayToScriptHash() // Test CScript::IsPayToScriptHash()
uint160 dummy(0); uint160 dummy;
CScript p2sh; CScript p2sh;
p2sh << OP_HASH160 << ToByteVector(dummy) << OP_EQUAL; p2sh << OP_HASH160 << ToByteVector(dummy) << OP_EQUAL;
BOOST_CHECK(p2sh.IsPayToScriptHash()); BOOST_CHECK(p2sh.IsPayToScriptHash());

View file

@ -24,10 +24,11 @@ extern Array read_json(const std::string& jsondata);
// Old script.cpp SignatureHash function // Old script.cpp SignatureHash function
uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
{ {
static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
if (nIn >= txTo.vin.size()) if (nIn >= txTo.vin.size())
{ {
printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn);
return 1; return one;
} }
CMutableTransaction txTmp(txTo); CMutableTransaction txTmp(txTo);
@ -58,7 +59,7 @@ uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, un
if (nOut >= txTmp.vout.size()) if (nOut >= txTmp.vout.size())
{ {
printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut); printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut);
return 1; return one;
} }
txTmp.vout.resize(nOut+1); txTmp.vout.resize(nOut+1);
for (unsigned int i = 0; i < nOut; i++) for (unsigned int i = 0; i < nOut; i++)

View file

@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount)
BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 0U); BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 0U);
BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 0U); BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 0U);
uint160 dummy(0); uint160 dummy;
s1 << OP_1 << ToByteVector(dummy) << ToByteVector(dummy) << OP_2 << OP_CHECKMULTISIG; s1 << OP_1 << ToByteVector(dummy) << ToByteVector(dummy) << OP_2 << OP_CHECKMULTISIG;
BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 2U); BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 2U);
s1 << OP_IF << OP_CHECKSIG << OP_ENDIF; s1 << OP_IF << OP_CHECKSIG << OP_ENDIF;

View file

@ -49,12 +49,12 @@ BOOST_AUTO_TEST_CASE(getlocator_test)
std::vector<uint256> vHashMain(100000); std::vector<uint256> vHashMain(100000);
std::vector<CBlockIndex> vBlocksMain(100000); std::vector<CBlockIndex> vBlocksMain(100000);
for (unsigned int i=0; i<vBlocksMain.size(); i++) { for (unsigned int i=0; i<vBlocksMain.size(); i++) {
vHashMain[i] = i; // Set the hash equal to the height, so we can quickly check the distances. vHashMain[i] = ArithToUint256(i); // Set the hash equal to the height, so we can quickly check the distances.
vBlocksMain[i].nHeight = i; vBlocksMain[i].nHeight = i;
vBlocksMain[i].pprev = i ? &vBlocksMain[i - 1] : NULL; vBlocksMain[i].pprev = i ? &vBlocksMain[i - 1] : NULL;
vBlocksMain[i].phashBlock = &vHashMain[i]; vBlocksMain[i].phashBlock = &vHashMain[i];
vBlocksMain[i].BuildSkip(); vBlocksMain[i].BuildSkip();
BOOST_CHECK_EQUAL((int)vBlocksMain[i].GetBlockHash().GetLow64(), vBlocksMain[i].nHeight); BOOST_CHECK_EQUAL((int)UintToArith256(vBlocksMain[i].GetBlockHash()).GetLow64(), vBlocksMain[i].nHeight);
BOOST_CHECK(vBlocksMain[i].pprev == NULL || vBlocksMain[i].nHeight == vBlocksMain[i].pprev->nHeight + 1); BOOST_CHECK(vBlocksMain[i].pprev == NULL || vBlocksMain[i].nHeight == vBlocksMain[i].pprev->nHeight + 1);
} }
@ -62,12 +62,12 @@ BOOST_AUTO_TEST_CASE(getlocator_test)
std::vector<uint256> vHashSide(50000); std::vector<uint256> vHashSide(50000);
std::vector<CBlockIndex> vBlocksSide(50000); std::vector<CBlockIndex> vBlocksSide(50000);
for (unsigned int i=0; i<vBlocksSide.size(); i++) { for (unsigned int i=0; i<vBlocksSide.size(); i++) {
vHashSide[i] = i + 50000 + (uint256(1) << 128); // Add 1<<128 to the hashes, so GetLow64() still returns the height. vHashSide[i] = ArithToUint256(i + 50000 + (arith_uint256(1) << 128)); // Add 1<<128 to the hashes, so GetLow64() still returns the height.
vBlocksSide[i].nHeight = i + 50000; vBlocksSide[i].nHeight = i + 50000;
vBlocksSide[i].pprev = i ? &vBlocksSide[i - 1] : &vBlocksMain[49999]; vBlocksSide[i].pprev = i ? &vBlocksSide[i - 1] : &vBlocksMain[49999];
vBlocksSide[i].phashBlock = &vHashSide[i]; vBlocksSide[i].phashBlock = &vHashSide[i];
vBlocksSide[i].BuildSkip(); vBlocksSide[i].BuildSkip();
BOOST_CHECK_EQUAL((int)vBlocksSide[i].GetBlockHash().GetLow64(), vBlocksSide[i].nHeight); BOOST_CHECK_EQUAL((int)UintToArith256(vBlocksSide[i].GetBlockHash()).GetLow64(), vBlocksSide[i].nHeight);
BOOST_CHECK(vBlocksSide[i].pprev == NULL || vBlocksSide[i].nHeight == vBlocksSide[i].pprev->nHeight + 1); BOOST_CHECK(vBlocksSide[i].pprev == NULL || vBlocksSide[i].nHeight == vBlocksSide[i].pprev->nHeight + 1);
} }
@ -87,13 +87,13 @@ BOOST_AUTO_TEST_CASE(getlocator_test)
// Entries 1 through 11 (inclusive) go back one step each. // Entries 1 through 11 (inclusive) go back one step each.
for (unsigned int i = 1; i < 12 && i < locator.vHave.size() - 1; i++) { 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. // The further ones (excluding the last one) go back with exponential steps.
unsigned int dist = 2; unsigned int dist = 2;
for (unsigned int i = 12; i < locator.vHave.size() - 1; i++) { 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; dist *= 2;
} }
} }

View file

@ -118,7 +118,7 @@ BOOST_AUTO_TEST_CASE(tx_valid)
break; 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) if (!fValid)
{ {
@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
break; 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) if (!fValid)
{ {

View file

@ -1,6 +1,9 @@
// Copyright (c) 2011-2013 The Bitcoin Core developers // Copyright (c) 2011-2013 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "arith_uint256.h"
#include "uint256.h"
#include "version.h"
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <stdint.h> #include <stdint.h>
@ -8,9 +11,8 @@
#include <iomanip> #include <iomanip>
#include <limits> #include <limits>
#include <cmath> #include <cmath>
#include "uint256.h"
#include <string> #include <string>
#include "version.h" #include <stdio.h>
BOOST_AUTO_TEST_SUITE(uint256_tests) BOOST_AUTO_TEST_SUITE(uint256_tests)
@ -18,11 +20,8 @@ const unsigned char R1Array[] =
"\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2" "\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"; "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d";
const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c"; 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<unsigned char>(R1Array,R1Array+32)); const uint256 R1L = uint256(std::vector<unsigned char>(R1Array,R1Array+32));
const uint160 R1S = uint160(std::vector<unsigned char>(R1Array,R1Array+20)); const uint160 R1S = uint160(std::vector<unsigned char>(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" "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf"
@ -30,8 +29,6 @@ const unsigned char R2Array[] =
const uint256 R2L = uint256(std::vector<unsigned char>(R2Array,R2Array+32)); const uint256 R2L = uint256(std::vector<unsigned char>(R2Array,R2Array+32));
const uint160 R2S = uint160(std::vector<unsigned char>(R2Array,R2Array+20)); const uint160 R2S = uint160(std::vector<unsigned char>(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"
"\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";
@ -50,8 +47,6 @@ const unsigned char MaxArray[] =
const uint256 MaxL = uint256(std::vector<unsigned char>(MaxArray,MaxArray+32)); const uint256 MaxL = uint256(std::vector<unsigned char>(MaxArray,MaxArray+32));
const uint160 MaxS = uint160(std::vector<unsigned char>(MaxArray,MaxArray+20)); const uint160 MaxS = uint160(std::vector<unsigned char>(MaxArray,MaxArray+20));
const uint256 HalfL = (OneL << 255);
const uint160 HalfS = (OneS << 159);
std::string ArrayToString(const unsigned char A[], unsigned int width) std::string ArrayToString(const unsigned char A[], unsigned int width)
{ {
std::stringstream Stream; std::stringstream Stream;
@ -63,6 +58,19 @@ std::string ArrayToString(const unsigned char A[], unsigned int width)
return Stream.str(); return Stream.str();
} }
inline uint160 uint160S(const char *str)
{
uint160 rv;
rv.SetHex(str);
return rv;
}
inline uint160 uint160S(const std::string& str)
{
uint160 rv;
rv.SetHex(str);
return rv;
}
BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality
{ {
BOOST_CHECK(1 == 0+1); BOOST_CHECK(1 == 0+1);
@ -85,477 +93,66 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality
BOOST_CHECK(ZeroL != OneL && ZeroS != OneS); BOOST_CHECK(ZeroL != OneL && ZeroS != OneS);
BOOST_CHECK(OneL != ZeroL && OneS != ZeroS); BOOST_CHECK(OneL != ZeroL && OneS != ZeroS);
BOOST_CHECK(MaxL != ZeroL && MaxS != ZeroS); BOOST_CHECK(MaxL != ZeroL && MaxS != ZeroS);
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)
{
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(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(((uint160(Tmp64) ^ (OneS << i) ) != Tmp64 ));
}
BOOST_CHECK(ZeroS == (OneS << 256));
// String Constructor and Copy Constructor // String Constructor and Copy Constructor
BOOST_CHECK(uint256("0x"+R1L.ToString()) == R1L); BOOST_CHECK(uint256S("0x"+R1L.ToString()) == R1L);
BOOST_CHECK(uint256("0x"+R2L.ToString()) == R2L); BOOST_CHECK(uint256S("0x"+R2L.ToString()) == R2L);
BOOST_CHECK(uint256("0x"+ZeroL.ToString()) == ZeroL); BOOST_CHECK(uint256S("0x"+ZeroL.ToString()) == ZeroL);
BOOST_CHECK(uint256("0x"+OneL.ToString()) == OneL); BOOST_CHECK(uint256S("0x"+OneL.ToString()) == OneL);
BOOST_CHECK(uint256("0x"+MaxL.ToString()) == MaxL); BOOST_CHECK(uint256S("0x"+MaxL.ToString()) == MaxL);
BOOST_CHECK(uint256(R1L.ToString()) == R1L); BOOST_CHECK(uint256S(R1L.ToString()) == R1L);
BOOST_CHECK(uint256(" 0x"+R1L.ToString()+" ") == R1L); BOOST_CHECK(uint256S(" 0x"+R1L.ToString()+" ") == R1L);
BOOST_CHECK(uint256("") == ZeroL); BOOST_CHECK(uint256S("") == ZeroL);
BOOST_CHECK(R1L == uint256(R1ArrayHex)); BOOST_CHECK(R1L == uint256S(R1ArrayHex));
BOOST_CHECK(uint256(R1L) == R1L); BOOST_CHECK(uint256(R1L) == R1L);
BOOST_CHECK((uint256(R1L^R2L)^R2L) == R1L);
BOOST_CHECK(uint256(ZeroL) == ZeroL); BOOST_CHECK(uint256(ZeroL) == ZeroL);
BOOST_CHECK(uint256(OneL) == OneL); BOOST_CHECK(uint256(OneL) == OneL);
BOOST_CHECK(uint160("0x"+R1S.ToString()) == R1S); BOOST_CHECK(uint160S("0x"+R1S.ToString()) == R1S);
BOOST_CHECK(uint160("0x"+R2S.ToString()) == R2S); BOOST_CHECK(uint160S("0x"+R2S.ToString()) == R2S);
BOOST_CHECK(uint160("0x"+ZeroS.ToString()) == ZeroS); BOOST_CHECK(uint160S("0x"+ZeroS.ToString()) == ZeroS);
BOOST_CHECK(uint160("0x"+OneS.ToString()) == OneS); BOOST_CHECK(uint160S("0x"+OneS.ToString()) == OneS);
BOOST_CHECK(uint160("0x"+MaxS.ToString()) == MaxS); BOOST_CHECK(uint160S("0x"+MaxS.ToString()) == MaxS);
BOOST_CHECK(uint160(R1S.ToString()) == R1S); BOOST_CHECK(uint160S(R1S.ToString()) == R1S);
BOOST_CHECK(uint160(" 0x"+R1S.ToString()+" ") == R1S); BOOST_CHECK(uint160S(" 0x"+R1S.ToString()+" ") == R1S);
BOOST_CHECK(uint160("") == ZeroS); BOOST_CHECK(uint160S("") == ZeroS);
BOOST_CHECK(R1S == uint160(R1ArrayHex)); BOOST_CHECK(R1S == uint160S(R1ArrayHex));
BOOST_CHECK(uint160(R1S) == R1S); BOOST_CHECK(uint160(R1S) == R1S);
BOOST_CHECK((uint160(R1S^R2S)^R2S) == R1S);
BOOST_CHECK(uint160(ZeroS) == ZeroS); BOOST_CHECK(uint160(ZeroS) == ZeroS);
BOOST_CHECK(uint160(OneS) == OneS); BOOST_CHECK(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));
// Assignment (from base_uint)
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);
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<unsigned char>(OneArray,OneArray+31)), uint_error);
BOOST_CHECK_THROW(uint256(std::vector<unsigned char>(OneArray,OneArray+20)), uint_error);
BOOST_CHECK_THROW(uint160(std::vector<unsigned char>(OneArray,OneArray+32)), uint_error);
BOOST_CHECK_THROW(uint160(std::vector<unsigned char>(OneArray,OneArray+19)), uint_error);
}
void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift)
{
for (unsigned int T=0; T < arrayLength; ++T)
{
unsigned int F = (T+bitsToShift/8);
if (F < arrayLength)
to[T] = from[F] >> (bitsToShift%8);
else
to[T] = 0;
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)
{
for (unsigned int T=0; T < arrayLength; ++T)
{
if (T >= bitsToShift/8)
{
unsigned int F = T-bitsToShift/8;
to[T] = from[F] << (bitsToShift%8);
if (T >= bitsToShift/8+1)
to[T] |= from[F-1] >> (8-bitsToShift%8);
}
else {
to[T] = 0;
}
}
}
BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>="
unsigned char TmpArray[32];
uint256 TmpL;
for (unsigned int i = 0; i < 256; ++i)
{
shiftArrayLeft(TmpArray, OneArray, 32, i);
BOOST_CHECK(uint256(std::vector<unsigned char>(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<unsigned char>(TmpArray,TmpArray+32)) == (R1L << i));
TmpL = R1L; TmpL <<= i;
BOOST_CHECK(TmpL == (R1L << i));
shiftArrayRight(TmpArray, R1Array, 32, i);
BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (R1L >> i));
TmpL = R1L; TmpL >>= i;
BOOST_CHECK(TmpL == (R1L >> i));
shiftArrayLeft(TmpArray, MaxArray, 32, i);
BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (MaxL << i));
TmpL = MaxL; TmpL <<= i;
BOOST_CHECK(TmpL == (MaxL << i));
shiftArrayRight(TmpArray, MaxArray, 32, i);
BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (MaxL >> i));
TmpL = MaxL; TmpL >>= i;
BOOST_CHECK(TmpL == (MaxL >> i));
}
uint256 c1L = uint256(0x0123456789abcdefULL);
uint256 c2L = c1L << 128;
for (unsigned int i = 0; i < 128; ++i) {
BOOST_CHECK((c1L << i) == (c2L >> (128-i)));
}
for (unsigned int i = 128; i < 256; ++i) {
BOOST_CHECK((c1L << i) == (c2L << (i-128)));
}
uint160 TmpS;
for (unsigned int i = 0; i < 160; ++i)
{
shiftArrayLeft(TmpArray, OneArray, 20, i);
BOOST_CHECK(uint160(std::vector<unsigned char>(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<unsigned char>(TmpArray,TmpArray+20)) == (R1S << i));
TmpS = R1S; TmpS <<= i;
BOOST_CHECK(TmpS == (R1S << i));
shiftArrayRight(TmpArray, R1Array, 20, i);
BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (R1S >> i));
TmpS = R1S; TmpS >>= i;
BOOST_CHECK(TmpS == (R1S >> i));
shiftArrayLeft(TmpArray, MaxArray, 20, i);
BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (MaxS << i));
TmpS = MaxS; TmpS <<= i;
BOOST_CHECK(TmpS == (MaxS << i));
shiftArrayRight(TmpArray, MaxArray, 20, i);
BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (MaxS >> i));
TmpS = MaxS; TmpS >>= i;
BOOST_CHECK(TmpS == (MaxS >> i));
}
uint160 c1S = uint160(0x0123456789abcdefULL);
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));
for (unsigned int i = 0; i < 256; ++i)
BOOST_CHECK(!(!(OneL<<i)));
for (unsigned int i = 0; i < 160; ++i)
BOOST_CHECK(!(!(OneS<<i)));
BOOST_CHECK(!(!R1L));BOOST_CHECK(!(!R1S));
BOOST_CHECK(!(!R2S));BOOST_CHECK(!(!R2S));
BOOST_CHECK(!(!MaxL));BOOST_CHECK(!(!MaxS));
BOOST_CHECK(~ZeroL == MaxL); BOOST_CHECK(~ZeroS == MaxS);
unsigned char TmpArray[32];
for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = ~R1Array[i]; }
BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (~R1L));
BOOST_CHECK(uint160(std::vector<unsigned char>(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)
BOOST_CHECK(-(OneL<<i) == (MaxL << i));
for (unsigned int i = 0; i < 160; ++i)
BOOST_CHECK(-(OneS<<i) == (MaxS << i));
}
// Check if doing _A_ _OP_ _B_ results in the same as applying _OP_ onto each
// element of Aarray and Barray, and then converting the result into a 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(uint256(std::vector<unsigned char>(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<unsigned char>(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 )
{
unsigned char TmpArray[32];
CHECKBITWISEOPERATOR(R1,R2,|)
CHECKBITWISEOPERATOR(R1,R2,^)
CHECKBITWISEOPERATOR(R1,R2,&)
CHECKBITWISEOPERATOR(R1,Zero,|)
CHECKBITWISEOPERATOR(R1,Zero,^)
CHECKBITWISEOPERATOR(R1,Zero,&)
CHECKBITWISEOPERATOR(R1,Max,|)
CHECKBITWISEOPERATOR(R1,Max,^)
CHECKBITWISEOPERATOR(R1,Max,&)
CHECKBITWISEOPERATOR(Zero,R1,|)
CHECKBITWISEOPERATOR(Zero,R1,^)
CHECKBITWISEOPERATOR(Zero,R1,&)
CHECKBITWISEOPERATOR(Max,R1,|)
CHECKBITWISEOPERATOR(Max,R1,^)
CHECKBITWISEOPERATOR(Max,R1,&)
uint256 TmpL;
uint160 TmpS;
CHECKASSIGNMENTOPERATOR(R1,R2,|)
CHECKASSIGNMENTOPERATOR(R1,R2,^)
CHECKASSIGNMENTOPERATOR(R1,R2,&)
CHECKASSIGNMENTOPERATOR(R1,Zero,|)
CHECKASSIGNMENTOPERATOR(R1,Zero,^)
CHECKASSIGNMENTOPERATOR(R1,Zero,&)
CHECKASSIGNMENTOPERATOR(R1,Max,|)
CHECKASSIGNMENTOPERATOR(R1,Max,^)
CHECKASSIGNMENTOPERATOR(R1,Max,&)
CHECKASSIGNMENTOPERATOR(Zero,R1,|)
CHECKASSIGNMENTOPERATOR(Zero,R1,^)
CHECKASSIGNMENTOPERATOR(Zero,R1,&)
CHECKASSIGNMENTOPERATOR(Max,R1,|)
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)));
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)));
} }
BOOST_AUTO_TEST_CASE( comparison ) // <= >= < > BOOST_AUTO_TEST_CASE( comparison ) // <= >= < >
{ {
uint256 LastL;
for (int i = 255; i >= 0; --i) {
uint256 TmpL; uint256 TmpL;
for (unsigned int i = 0; i < 256; ++i) { *(TmpL.begin() + (i>>3)) |= 1<<(7-(i&7));
TmpL= OneL<< i; BOOST_CHECK( LastL < TmpL );
BOOST_CHECK( TmpL >= ZeroL && TmpL > ZeroL && ZeroL < TmpL && ZeroL <= TmpL); LastL = TmpL;
BOOST_CHECK( TmpL >= 0 && TmpL > 0 && 0 < TmpL && 0 <= TmpL);
TmpL |= R1L;
BOOST_CHECK( TmpL >= R1L ); BOOST_CHECK( (TmpL == R1L) != (TmpL > R1L)); BOOST_CHECK( (TmpL == R1L) || !( TmpL <= R1L));
BOOST_CHECK( R1L <= TmpL ); BOOST_CHECK( (R1L == TmpL) != (R1L < TmpL)); BOOST_CHECK( (TmpL == R1L) || !( R1L >= TmpL));
BOOST_CHECK(! (TmpL < R1L)); BOOST_CHECK(! (R1L > 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; uint160 TmpS;
for (unsigned int i = 0; i < 160; ++i) { *(TmpS.begin() + (i>>3)) |= 1<<(7-(i&7));
TmpS= OneS<< i; BOOST_CHECK( LastS < TmpS );
BOOST_CHECK( TmpS >= ZeroS && TmpS > ZeroS && ZeroS < TmpS && ZeroS <= TmpS); LastS = 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_CHECK( ZeroS < R1S );
BOOST_CHECK( R2S < R1S );
BOOST_AUTO_TEST_CASE( plusMinus ) BOOST_CHECK( ZeroS < OneS );
{ BOOST_CHECK( OneS < MaxS );
uint256 TmpL = 0; BOOST_CHECK( R1S < MaxS );
BOOST_CHECK(R1L+R2L == uint256(R1LplusR2L)); BOOST_CHECK( R2S < MaxS );
TmpL += R1L;
BOOST_CHECK(TmpL == R1L);
TmpL += R2L;
BOOST_CHECK(TmpL == R1L + R2L);
BOOST_CHECK(OneL+MaxL == ZeroL);
BOOST_CHECK(MaxL+OneL == ZeroL);
for (unsigned int i = 1; i < 256; ++i) {
BOOST_CHECK( (MaxL >> i) + OneL == (HalfL >> (i-1)) );
BOOST_CHECK( OneL + (MaxL >> i) == (HalfL >> (i-1)) );
TmpL = (MaxL>>i); TmpL += OneL;
BOOST_CHECK( TmpL == (HalfL >> (i-1)) );
TmpL = (MaxL>>i); TmpL += 1;
BOOST_CHECK( TmpL == (HalfL >> (i-1)) );
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));
TmpL -= 0xee8d836fce66fbULL; BOOST_CHECK(TmpL == 0xbedc77e27940a7ULL);
TmpL = R1L;
BOOST_CHECK(++TmpL == R1L+1);
BOOST_CHECK(R1L -(-R2L) == R1L+R2L);
BOOST_CHECK(R1L -(-OneL) == R1L+OneL);
BOOST_CHECK(R1L - OneL == R1L+(-OneL));
for (unsigned int i = 1; i < 256; ++i) {
BOOST_CHECK((MaxL>>i) - (-OneL) == (HalfL >> (i-1)));
BOOST_CHECK((HalfL >> (i-1)) - OneL == (MaxL>>i));
TmpL = (HalfL >> (i-1));
BOOST_CHECK(TmpL-- == (HalfL >> (i-1)));
BOOST_CHECK(TmpL == (MaxL >> i));
TmpL = (HalfL >> (i-1));
BOOST_CHECK(--TmpL == (MaxL >> i));
}
TmpL = R1L;
BOOST_CHECK(--TmpL == R1L-1);
// 160-bit; copy-pasted
uint160 TmpS = 0;
BOOST_CHECK(R1S+R2S == 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(uint160(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == uint160(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL));
TmpS = uint160(0xbedc77e27940a7ULL); TmpS += 0xee8d836fce66fbULL;
BOOST_CHECK(TmpS == 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 )
{
BOOST_CHECK((R1L * R1L).ToString() == "62a38c0486f01e45879d7910a7761bf30d5237e9873f9bff3642a732c4d84f10");
BOOST_CHECK((R1L * R2L).ToString() == "de37805e9986996cfba76ff6ba51c008df851987d9dd323f0e5de07760529c40");
BOOST_CHECK((R1L * ZeroL) == ZeroL);
BOOST_CHECK((R1L * OneL) == R1L);
BOOST_CHECK((R1L * MaxL) == -R1L);
BOOST_CHECK((R2L * R1L) == (R1L * R2L));
BOOST_CHECK((R2L * R2L).ToString() == "ac8c010096767d3cae5005dec28bb2b45a1d85ab7996ccd3e102a650f74ff100");
BOOST_CHECK((R2L * ZeroL) == ZeroL);
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 )
{
uint256 D1L("AD7133AC1977FA2B7");
uint256 D2L("ECD751716");
BOOST_CHECK((R1L / D1L).ToString() == "00000000000000000b8ac01106981635d9ed112290f8895545a7654dde28fb3a");
BOOST_CHECK((R1L / D2L).ToString() == "000000000873ce8efec5b67150bad3aa8c5fcb70e947586153bf2cec7c37c57a");
BOOST_CHECK(R1L / OneL == R1L);
BOOST_CHECK(R1L / MaxL == ZeroL);
BOOST_CHECK(MaxL / R1L == 2);
BOOST_CHECK_THROW(R1L / ZeroL, uint_error);
BOOST_CHECK((R2L / D1L).ToString() == "000000000000000013e1665895a1cc981de6d93670105a6b3ec3b73141b3a3c5");
BOOST_CHECK((R2L / D2L).ToString() == "000000000e8f0abe753bb0afe2e9437ee85d280be60882cf0bd1aaf7fa3cc2c4");
BOOST_CHECK(R2L / OneL == R2L);
BOOST_CHECK(R2L / MaxL == ZeroL);
BOOST_CHECK(MaxL / R2L == 1);
BOOST_CHECK_THROW(R2L / ZeroL, uint_error);
uint160 D1S("D3C5EDCDEA54EB92679F0A4B4");
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);
}
bool almostEqual(double d1, double d2)
{
return fabs(d1-d2) <= 4*fabs(d1)*std::numeric_limits<double>::epsilon();
} }
BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 GetSerializeSize, Serialize, Unserialize BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 GetSerializeSize, Serialize, Unserialize
@ -567,8 +164,7 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
uint256 TmpL(R1L); uint256 TmpL(R1L);
BOOST_CHECK(TmpL == R1L); BOOST_CHECK(TmpL == R1L);
TmpL.SetHex(R2L.ToString()); BOOST_CHECK(TmpL == R2L); TmpL.SetHex(R2L.ToString()); BOOST_CHECK(TmpL == R2L);
TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK(TmpL == 0); TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK(TmpL == uint256());
TmpL.SetHex(HalfL.ToString()); BOOST_CHECK(TmpL == HalfL);
TmpL.SetHex(R1L.ToString()); TmpL.SetHex(R1L.ToString());
BOOST_CHECK(memcmp(R1L.begin(), R1Array, 32)==0); BOOST_CHECK(memcmp(R1L.begin(), R1Array, 32)==0);
@ -576,6 +172,8 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
BOOST_CHECK(memcmp(R2L.begin(), R2Array, 32)==0); BOOST_CHECK(memcmp(R2L.begin(), R2Array, 32)==0);
BOOST_CHECK(memcmp(ZeroL.begin(), ZeroArray, 32)==0); BOOST_CHECK(memcmp(ZeroL.begin(), ZeroArray, 32)==0);
BOOST_CHECK(memcmp(OneL.begin(), OneArray, 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(R1L.size() == 32);
BOOST_CHECK(R2L.size() == 32); BOOST_CHECK(R2L.size() == 32);
BOOST_CHECK(ZeroL.size() == 32); BOOST_CHECK(ZeroL.size() == 32);
@ -585,9 +183,6 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
BOOST_CHECK(OneL.begin() + 32 == OneL.end()); BOOST_CHECK(OneL.begin() + 32 == OneL.end());
BOOST_CHECK(MaxL.begin() + 32 == MaxL.end()); BOOST_CHECK(MaxL.begin() + 32 == MaxL.end());
BOOST_CHECK(TmpL.begin() + 32 == TmpL.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(R1L.GetSerializeSize(0,PROTOCOL_VERSION) == 32);
BOOST_CHECK(ZeroL.GetSerializeSize(0,PROTOCOL_VERSION) == 32); BOOST_CHECK(ZeroL.GetSerializeSize(0,PROTOCOL_VERSION) == 32);
@ -615,8 +210,7 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
uint160 TmpS(R1S); uint160 TmpS(R1S);
BOOST_CHECK(TmpS == R1S); BOOST_CHECK(TmpS == R1S);
TmpS.SetHex(R2S.ToString()); BOOST_CHECK(TmpS == R2S); TmpS.SetHex(R2S.ToString()); BOOST_CHECK(TmpS == R2S);
TmpS.SetHex(ZeroS.ToString()); BOOST_CHECK(TmpS == 0); TmpS.SetHex(ZeroS.ToString()); BOOST_CHECK(TmpS == uint160());
TmpS.SetHex(HalfS.ToString()); BOOST_CHECK(TmpS == HalfS);
TmpS.SetHex(R1S.ToString()); TmpS.SetHex(R1S.ToString());
BOOST_CHECK(memcmp(R1S.begin(), R1Array, 20)==0); BOOST_CHECK(memcmp(R1S.begin(), R1Array, 20)==0);
@ -624,6 +218,8 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
BOOST_CHECK(memcmp(R2S.begin(), R2Array, 20)==0); BOOST_CHECK(memcmp(R2S.begin(), R2Array, 20)==0);
BOOST_CHECK(memcmp(ZeroS.begin(), ZeroArray, 20)==0); BOOST_CHECK(memcmp(ZeroS.begin(), ZeroArray, 20)==0);
BOOST_CHECK(memcmp(OneS.begin(), OneArray, 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(R1S.size() == 20);
BOOST_CHECK(R2S.size() == 20); BOOST_CHECK(R2S.size() == 20);
BOOST_CHECK(ZeroS.size() == 20); BOOST_CHECK(ZeroS.size() == 20);
@ -633,9 +229,6 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
BOOST_CHECK(OneS.begin() + 20 == OneS.end()); BOOST_CHECK(OneS.begin() + 20 == OneS.end());
BOOST_CHECK(MaxS.begin() + 20 == MaxS.end()); BOOST_CHECK(MaxS.begin() + 20 == MaxS.end());
BOOST_CHECK(TmpS.begin() + 20 == TmpS.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(R1S.GetSerializeSize(0,PROTOCOL_VERSION) == 20);
BOOST_CHECK(ZeroS.GetSerializeSize(0,PROTOCOL_VERSION) == 20); BOOST_CHECK(ZeroS.GetSerializeSize(0,PROTOCOL_VERSION) == 20);
@ -654,184 +247,22 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
TmpS.Unserialize(ss,0,PROTOCOL_VERSION); TmpS.Unserialize(ss,0,PROTOCOL_VERSION);
BOOST_CHECK(MaxS == TmpS); BOOST_CHECK(MaxS == TmpS);
ss.str(""); 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)));
}
} }
BOOST_AUTO_TEST_CASE(bignum_SetCompact) BOOST_AUTO_TEST_CASE( conversion )
{ {
uint256 num; BOOST_CHECK(ArithToUint256(UintToArith256(ZeroL)) == ZeroL);
bool fNegative; BOOST_CHECK(ArithToUint256(UintToArith256(OneL)) == OneL);
bool fOverflow; BOOST_CHECK(ArithToUint256(UintToArith256(R1L)) == R1L);
num.SetCompact(0, &fNegative, &fOverflow); BOOST_CHECK(ArithToUint256(UintToArith256(R2L)) == R2L);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000"); BOOST_CHECK(UintToArith256(ZeroL) == 0);
BOOST_CHECK_EQUAL(num.GetCompact(), 0U); BOOST_CHECK(UintToArith256(OneL) == 1);
BOOST_CHECK_EQUAL(fNegative, false); BOOST_CHECK(ArithToUint256(0) == ZeroL);
BOOST_CHECK_EQUAL(fOverflow, false); BOOST_CHECK(ArithToUint256(1) == OneL);
BOOST_CHECK(arith_uint256(R1L.GetHex()) == UintToArith256(R1L));
num.SetCompact(0x00123456, &fNegative, &fOverflow); BOOST_CHECK(arith_uint256(R2L.GetHex()) == UintToArith256(R2L));
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000"); BOOST_CHECK(R1L.GetHex() == UintToArith256(R1L).GetHex());
BOOST_CHECK_EQUAL(num.GetCompact(), 0U); BOOST_CHECK(R2L.GetHex() == UintToArith256(R2L).GetHex());
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x01003456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x02000056, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x03000000, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x04000000, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x00923456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x01803456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x02800056, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x03800000, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x04800000, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x01123456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000012");
BOOST_CHECK_EQUAL(num.GetCompact(), 0x01120000U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
// Make sure that we don't generate compacts with the 0x00800000 bit set
num = 0x80;
BOOST_CHECK_EQUAL(num.GetCompact(), 0x02008000U);
num.SetCompact(0x01fedcba, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "000000000000000000000000000000000000000000000000000000000000007e");
BOOST_CHECK_EQUAL(num.GetCompact(true), 0x01fe0000U);
BOOST_CHECK_EQUAL(fNegative, true);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x02123456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000001234");
BOOST_CHECK_EQUAL(num.GetCompact(), 0x02123400U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x03123456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000123456");
BOOST_CHECK_EQUAL(num.GetCompact(), 0x03123456U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x04123456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000012345600");
BOOST_CHECK_EQUAL(num.GetCompact(), 0x04123456U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x04923456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000012345600");
BOOST_CHECK_EQUAL(num.GetCompact(true), 0x04923456U);
BOOST_CHECK_EQUAL(fNegative, true);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x05009234, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000092340000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0x05009234U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0x20123456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(num.GetHex(), "1234560000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK_EQUAL(num.GetCompact(), 0x20123456U);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, false);
num.SetCompact(0xff123456, &fNegative, &fOverflow);
BOOST_CHECK_EQUAL(fNegative, false);
BOOST_CHECK_EQUAL(fOverflow, true);
}
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 + 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,^)
CHECKBITWISEOPERATOR(~R1,R2,&)
CHECKBITWISEOPERATOR(R1,~R2,|)
CHECKBITWISEOPERATOR(R1,~R2,^)
CHECKBITWISEOPERATOR(R1,~R2,&)
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View file

@ -39,7 +39,7 @@ bool CCoinsViewDB::HaveCoins(const uint256 &txid) const {
uint256 CCoinsViewDB::GetBestBlock() const { uint256 CCoinsViewDB::GetBestBlock() const {
uint256 hashBestChain; uint256 hashBestChain;
if (!db.Read('B', hashBestChain)) if (!db.Read('B', hashBestChain))
return uint256(0); return uint256();
return hashBestChain; return hashBestChain;
} }
@ -56,7 +56,7 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) {
CCoinsMap::iterator itOld = it++; CCoinsMap::iterator itOld = it++;
mapCoins.erase(itOld); mapCoins.erase(itOld);
} }
if (hashBlock != uint256(0)) if (!hashBlock.IsNull())
BatchWriteHashBestChain(batch, hashBlock); BatchWriteHashBestChain(batch, hashBlock);
LogPrint("coindb", "Committing %u changed transactions (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count); 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<leveldb::Iterator> pcursor(NewIterator()); boost::scoped_ptr<leveldb::Iterator> pcursor(NewIterator());
CDataStream ssKeySet(SER_DISK, CLIENT_VERSION); CDataStream ssKeySet(SER_DISK, CLIENT_VERSION);
ssKeySet << make_pair('b', uint256(0)); ssKeySet << make_pair('b', uint256());
pcursor->Seek(ssKeySet.str()); pcursor->Seek(ssKeySet.str());
// Load mapBlockIndex // Load mapBlockIndex

View file

@ -11,158 +11,25 @@
#include <string.h> #include <string.h>
template <unsigned int BITS> template <unsigned int BITS>
base_uint<BITS>::base_uint(const std::string& str) base_blob<BITS>::base_blob(const std::vector<unsigned char>& vch)
{ {
SetHex(str); assert(vch.size() == sizeof(data));
memcpy(data, &vch[0], sizeof(data));
} }
template <unsigned int BITS> template <unsigned int BITS>
base_uint<BITS>::base_uint(const std::vector<unsigned char>& vch) std::string base_blob<BITS>::GetHex() const
{ {
if (vch.size() != sizeof(pn)) char psz[sizeof(data) * 2 + 1];
throw uint_error("Converting vector of wrong size to base_uint"); for (unsigned int i = 0; i < sizeof(data); i++)
memcpy(pn, &vch[0], sizeof(pn)); sprintf(psz + i * 2, "%02x", data[sizeof(data) - i - 1]);
return std::string(psz, psz + sizeof(data) * 2);
} }
template <unsigned int BITS> template <unsigned int BITS>
base_uint<BITS>& base_uint<BITS>::operator<<=(unsigned int shift) void base_blob<BITS>::SetHex(const char* psz)
{ {
base_uint<BITS> a(*this); memset(data, 0, sizeof(data));
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 <unsigned int BITS>
base_uint<BITS>& base_uint<BITS>::operator>>=(unsigned int shift)
{
base_uint<BITS> 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 <unsigned int BITS>
base_uint<BITS>& base_uint<BITS>::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 <unsigned int BITS>
base_uint<BITS>& base_uint<BITS>::operator*=(const base_uint& b)
{
base_uint<BITS> 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 <unsigned int BITS>
base_uint<BITS>& base_uint<BITS>::operator/=(const base_uint& b)
{
base_uint<BITS> div = b; // make a copy, so we can shift.
base_uint<BITS> 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 <unsigned int BITS>
int base_uint<BITS>::CompareTo(const base_uint<BITS>& 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 <unsigned int BITS>
bool base_uint<BITS>::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 <unsigned int BITS>
double base_uint<BITS>::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 <unsigned int BITS>
std::string base_uint<BITS>::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 <unsigned int BITS>
void base_uint<BITS>::SetHex(const char* psz)
{
memset(pn, 0, sizeof(pn));
// skip leading spaces // skip leading spaces
while (isspace(*psz)) while (isspace(*psz))
@ -177,7 +44,7 @@ void base_uint<BITS>::SetHex(const char* psz)
while (::HexDigit(*psz) != -1) while (::HexDigit(*psz) != -1)
psz++; psz++;
psz--; psz--;
unsigned char* p1 = (unsigned char*)pn; unsigned char* p1 = (unsigned char*)data;
unsigned char* pend = p1 + WIDTH * 4; unsigned char* pend = p1 + WIDTH * 4;
while (psz >= pbegin && p1 < pend) { while (psz >= pbegin && p1 < pend) {
*p1 = ::HexDigit(*psz--); *p1 = ::HexDigit(*psz--);
@ -189,110 +56,30 @@ void base_uint<BITS>::SetHex(const char* psz)
} }
template <unsigned int BITS> template <unsigned int BITS>
void base_uint<BITS>::SetHex(const std::string& str) void base_blob<BITS>::SetHex(const std::string& str)
{ {
SetHex(str.c_str()); SetHex(str.c_str());
} }
template <unsigned int BITS> template <unsigned int BITS>
std::string base_uint<BITS>::ToString() const std::string base_blob<BITS>::ToString() const
{ {
return (GetHex()); return (GetHex());
} }
template <unsigned int BITS> // Explicit instantiations for base_blob<160>
unsigned int base_uint<BITS>::bits() const template base_blob<160>::base_blob(const std::vector<unsigned char>&);
{ template std::string base_blob<160>::GetHex() const;
for (int pos = WIDTH - 1; pos >= 0; pos--) { template std::string base_blob<160>::ToString() const;
if (pn[pos]) { template void base_blob<160>::SetHex(const char*);
for (int bits = 31; bits > 0; bits--) { template void base_blob<160>::SetHex(const std::string&);
if (pn[pos] & 1 << bits)
return 32 * pos + bits + 1;
}
return 32 * pos + 1;
}
}
return 0;
}
// Explicit instantiations for base_uint<160> // Explicit instantiations for base_blob<256>
template base_uint<160>::base_uint(const std::string&); template base_blob<256>::base_blob(const std::vector<unsigned char>&);
template base_uint<160>::base_uint(const std::vector<unsigned char>&); template std::string base_blob<256>::GetHex() const;
template base_uint<160>& base_uint<160>::operator<<=(unsigned int); template std::string base_blob<256>::ToString() const;
template base_uint<160>& base_uint<160>::operator>>=(unsigned int); template void base_blob<256>::SetHex(const char*);
template base_uint<160>& base_uint<160>::operator*=(uint32_t b32); template void base_blob<256>::SetHex(const std::string&);
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<unsigned char>&);
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;
}
static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c) 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 uint64_t uint256::GetHash(const uint256& salt) const
{ {
uint32_t a, b, c; 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 = b = c = 0xdeadbeef + (WIDTH << 2);
a += pn[0] ^ salt.pn[0]; a += pn[0] ^ salt_pn[0];
b += pn[1] ^ salt.pn[1]; b += pn[1] ^ salt_pn[1];
c += pn[2] ^ salt.pn[2]; c += pn[2] ^ salt_pn[2];
HashMix(a, b, c); HashMix(a, b, c);
a += pn[3] ^ salt.pn[3]; a += pn[3] ^ salt_pn[3];
b += pn[4] ^ salt.pn[4]; b += pn[4] ^ salt_pn[4];
c += pn[5] ^ salt.pn[5]; c += pn[5] ^ salt_pn[5];
HashMix(a, b, c); HashMix(a, b, c);
a += pn[6] ^ salt.pn[6]; a += pn[6] ^ salt_pn[6];
b += pn[7] ^ salt.pn[7]; b += pn[7] ^ salt_pn[7];
HashFinal(a, b, c); HashFinal(a, b, c);
return ((((uint64_t)b) << 32) | c); return ((((uint64_t)b) << 32) | c);

View file

@ -13,217 +13,37 @@
#include <string> #include <string>
#include <vector> #include <vector>
class uint_error : public std::runtime_error { /** Template base class for fixed-sized opaque blobs. */
public:
explicit uint_error(const std::string& str) : std::runtime_error(str) {}
};
/** Template base class for unsigned big integers. */
template<unsigned int BITS> template<unsigned int BITS>
class base_uint class base_blob
{ {
protected: protected:
enum { WIDTH=BITS/32 }; enum { WIDTH=BITS/8 };
uint32_t pn[WIDTH]; uint8_t data[WIDTH];
public: public:
base_blob()
base_uint()
{ {
for (int i = 0; i < WIDTH; i++) memset(data, 0, sizeof(data));
pn[i] = 0;
} }
base_uint(const base_uint& b) explicit base_blob(const std::vector<unsigned char>& vch);
bool IsNull() const
{ {
for (int i = 0; i < WIDTH; i++) for (int i = 0; i < WIDTH; i++)
pn[i] = b.pn[i]; if (data[i] != 0)
}
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<unsigned char>& vch);
bool operator!() const
{
for (int i = 0; i < WIDTH; i++)
if (pn[i] != 0)
return false; return false;
return true; return true;
} }
const base_uint operator~() const void SetNull()
{ {
base_uint ret; memset(data, 0, sizeof(data));
for (int i = 0; i < WIDTH; i++)
ret.pn[i] = ~pn[i];
return ret;
} }
const base_uint operator-() const 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; }
base_uint ret; friend inline bool operator<(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) < 0; }
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; std::string GetHex() const;
void SetHex(const char* psz); void SetHex(const char* psz);
@ -232,102 +52,107 @@ public:
unsigned char* begin() unsigned char* begin()
{ {
return (unsigned char*)&pn[0]; return &data[0];
} }
unsigned char* end() unsigned char* end()
{ {
return (unsigned char*)&pn[WIDTH]; return &data[WIDTH];
} }
const unsigned char* begin() const const unsigned char* begin() const
{ {
return (unsigned char*)&pn[0]; return &data[0];
} }
const unsigned char* end() const const unsigned char* end() const
{ {
return (unsigned char*)&pn[WIDTH]; return &data[WIDTH];
} }
unsigned int size() const unsigned int size() const
{ {
return sizeof(pn); return sizeof(data);
}
/**
* 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 unsigned int GetSerializeSize(int nType, int nVersion) const
{ {
return sizeof(pn); return sizeof(data);
} }
template<typename Stream> template<typename Stream>
void Serialize(Stream& s, int nType, int nVersion) const void Serialize(Stream& s, int nType, int nVersion) const
{ {
s.write((char*)pn, sizeof(pn)); s.write((char*)data, sizeof(data));
} }
template<typename Stream> template<typename Stream>
void Unserialize(Stream& s, int nType, int nVersion) void Unserialize(Stream& s, int nType, int nVersion)
{ {
s.read((char*)pn, sizeof(pn)); s.read((char*)data, sizeof(data));
} }
}; };
/** 160-bit unsigned big integer. */ /** 160-bit opaque blob.
class uint160 : public base_uint<160> { * @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: public:
uint160() {} uint160() {}
uint160(const base_uint<160>& b) : base_uint<160>(b) {} uint160(const base_blob<160>& b) : base_blob<160>(b) {}
uint160(uint64_t b) : base_uint<160>(b) {} explicit uint160(const std::vector<unsigned char>& vch) : base_blob<160>(vch) {}
explicit uint160(const std::string& str) : base_uint<160>(str) {}
explicit uint160(const std::vector<unsigned char>& vch) : base_uint<160>(vch) {}
}; };
/** 256-bit unsigned big integer. */ /** 256-bit opaque blob.
class uint256 : public base_uint<256> { * @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: public:
uint256() {} uint256() {}
uint256(const base_uint<256>& b) : base_uint<256>(b) {} uint256(const base_blob<256>& b) : base_blob<256>(b) {}
uint256(uint64_t b) : base_uint<256>(b) {} explicit uint256(const std::vector<unsigned char>& vch) : base_blob<256>(vch) {}
explicit uint256(const std::string& str) : base_uint<256>(str) {}
explicit uint256(const std::vector<unsigned char>& vch) : base_uint<256>(vch) {}
/** /** A cheap hash function that just returns 64 bits from the result, it can be
* The "compact" format is a representation of a whole * used when the contents are considered uniformly random. It is not appropriate
* number N using an unsigned 32bit number similar to a * when the value can easily be influenced from outside as e.g. a network adversary could
* floating point format. * provide values to trigger worst-case behavior.
* The most significant 8 bits are the unsigned exponent of base 256. * @note The result of this function is not stable between little and big endian.
* 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& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL); uint64_t GetCheapHash() const
uint32_t GetCompact(bool fNegative = false) 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; uint64_t GetHash(const uint256& salt) const;
}; };
/* 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 #endif // BITCOIN_UINT256_H

View file

@ -579,7 +579,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet)
wtx.nOrderPos = IncOrderPosNext(); wtx.nOrderPos = IncOrderPosNext();
wtx.nTimeSmart = wtx.nTimeReceived; wtx.nTimeSmart = wtx.nTimeReceived;
if (wtxIn.hashBlock != 0) if (!wtxIn.hashBlock.IsNull())
{ {
if (mapBlockIndex.count(wtxIn.hashBlock)) if (mapBlockIndex.count(wtxIn.hashBlock))
{ {
@ -630,7 +630,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet)
if (!fInsertedNew) if (!fInsertedNew)
{ {
// Merge // Merge
if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock) if (!wtxIn.hashBlock.IsNull() && wtxIn.hashBlock != wtx.hashBlock)
{ {
wtx.hashBlock = wtxIn.hashBlock; wtx.hashBlock = wtxIn.hashBlock;
fUpdated = true; fUpdated = true;
@ -795,7 +795,7 @@ int CWalletTx::GetRequestCount() const
if (IsCoinBase()) if (IsCoinBase())
{ {
// Generated block // Generated block
if (hashBlock != 0) if (!hashBlock.IsNull())
{ {
map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
if (mi != pwallet->mapRequestCount.end()) if (mi != pwallet->mapRequestCount.end())
@ -811,7 +811,7 @@ int CWalletTx::GetRequestCount() const
nRequests = (*mi).second; nRequests = (*mi).second;
// How about the block it's in? // How about the block it's in?
if (nRequests == 0 && hashBlock != 0) if (nRequests == 0 && !hashBlock.IsNull())
{ {
map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
if (mi != pwallet->mapRequestCount.end()) if (mi != pwallet->mapRequestCount.end())
@ -2317,7 +2317,7 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block)
int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const
{ {
if (hashBlock == 0 || nIndex == -1) if (hashBlock.IsNull() || nIndex == -1)
return 0; return 0;
AssertLockHeld(cs_main); AssertLockHeld(cs_main);

View file

@ -519,7 +519,7 @@ public:
void Init() void Init()
{ {
hashBlock = 0; hashBlock = uint256();
nIndex = -1; nIndex = -1;
fMerkleVerified = false; fMerkleVerified = false;
} }

View file

@ -439,7 +439,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
} }
CKey key; CKey key;
CPrivKey pkey; CPrivKey pkey;
uint256 hash = 0; uint256 hash;
if (strType == "key") if (strType == "key")
{ {
@ -464,7 +464,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
bool fSkipCheck = false; bool fSkipCheck = false;
if (hash != 0) if (!hash.IsNull())
{ {
// hash pubkey/privkey to accelerate wallet load // hash pubkey/privkey to accelerate wallet load
std::vector<unsigned char> vchKey; std::vector<unsigned char> vchKey;