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:
commit
ec20fd74b8
50 changed files with 1518 additions and 1341 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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
259
src/arith_uint256.cpp
Normal 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
290
src/arith_uint256.h
Normal 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
|
|
@ -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());
|
||||||
|
|
11
src/chain.h
11
src/chain.h
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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".
|
||||||
|
|
|
@ -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);
|
||||||
|
|
35
src/main.cpp
35
src/main.cpp
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
15
src/pow.cpp
15
src/pow.cpp
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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");
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
566
src/test/arith_uint256_tests.cpp
Normal file
566
src/test/arith_uint256_tests.cpp
Normal 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()
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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++)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
281
src/uint256.cpp
281
src/uint256.cpp
|
@ -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);
|
||||||
|
|
321
src/uint256.h
321
src/uint256.h
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -519,7 +519,7 @@ public:
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
hashBlock = 0;
|
hashBlock = uint256();
|
||||||
nIndex = -1;
|
nIndex = -1;
|
||||||
fMerkleVerified = false;
|
fMerkleVerified = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue