Page MenuHomePhabricator

No OneTemporary

diff --git a/src/Makefile.am b/src/Makefile.am
index 215d0319f..a49ad5871 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,203 +1,203 @@
include Makefile.include
AM_CPPFLAGS += -I$(builddir)
noinst_LIBRARIES = \
libbitcoin_server.a \
libbitcoin_common.a \
libbitcoin_cli.a
if ENABLE_WALLET
noinst_LIBRARIES += libbitcoin_wallet.a
endif
bin_PROGRAMS =
if BUILD_BITCOIND
bin_PROGRAMS += bitcoind
endif
if BUILD_BITCOIN_CLI
bin_PROGRAMS += bitcoin-cli
endif
SUBDIRS = . $(BUILD_QT) $(BUILD_TEST)
DIST_SUBDIRS = . qt test
.PHONY: FORCE
# bitcoin core #
BITCOIN_CORE_H = \
addrman.h \
alert.h \
allocators.h \
- base58.h bignum.h \
+ base58.h \
bloom.h \
chainparams.h \
checkpoints.h \
checkqueue.h \
clientversion.h \
coincontrol.h \
coins.h \
compat.h \
core.h \
crypter.h \
db.h \
hash.h \
init.h \
key.h \
keystore.h \
leveldbwrapper.h \
limitedmap.h \
main.h \
miner.h \
mruset.h \
netbase.h \
net.h \
noui.h \
protocol.h \
rpcclient.h \
rpcprotocol.h \
rpcserver.h \
script.h \
serialize.h \
sync.h \
threadsafety.h \
tinyformat.h \
txdb.h \
txmempool.h \
ui_interface.h \
uint256.h \
util.h \
version.h \
walletdb.h \
wallet.h
JSON_H = \
json/json_spirit.h \
json/json_spirit_error_position.h \
json/json_spirit_reader.h \
json/json_spirit_reader_template.h \
json/json_spirit_stream_reader.h \
json/json_spirit_utils.h \
json/json_spirit_value.h \
json/json_spirit_writer.h \
json/json_spirit_writer_template.h
obj/build.h: FORCE
@$(MKDIR_P) $(abs_top_builddir)/src/obj
@$(top_srcdir)/share/genbuild.sh $(abs_top_builddir)/src/obj/build.h \
$(abs_top_srcdir)
version.o: obj/build.h
libbitcoin_server_a_SOURCES = \
addrman.cpp \
alert.cpp \
bloom.cpp \
checkpoints.cpp \
coins.cpp \
init.cpp \
keystore.cpp \
leveldbwrapper.cpp \
main.cpp \
miner.cpp \
net.cpp \
noui.cpp \
rpcblockchain.cpp \
rpcmining.cpp \
rpcmisc.cpp \
rpcnet.cpp \
rpcrawtransaction.cpp \
rpcserver.cpp \
txdb.cpp \
txmempool.cpp \
$(JSON_H) \
$(BITCOIN_CORE_H)
libbitcoin_wallet_a_SOURCES = \
db.cpp \
crypter.cpp \
rpcdump.cpp \
rpcwallet.cpp \
wallet.cpp \
walletdb.cpp \
$(BITCOIN_CORE_H)
libbitcoin_common_a_SOURCES = \
base58.cpp \
allocators.cpp \
chainparams.cpp \
core.cpp \
hash.cpp \
key.cpp \
netbase.cpp \
protocol.cpp \
rpcprotocol.cpp \
script.cpp \
sync.cpp \
util.cpp \
version.cpp \
$(BITCOIN_CORE_H)
if GLIBC_BACK_COMPAT
libbitcoin_common_a_SOURCES += compat/glibc_compat.cpp
libbitcoin_common_a_SOURCES += compat/glibcxx_compat.cpp
endif
libbitcoin_cli_a_SOURCES = \
rpcclient.cpp \
$(BITCOIN_CORE_H)
nodist_libbitcoin_common_a_SOURCES = $(top_srcdir)/src/obj/build.h
#
# bitcoind binary #
bitcoind_LDADD = \
libbitcoin_server.a \
libbitcoin_cli.a \
libbitcoin_common.a \
$(LIBLEVELDB) \
$(LIBMEMENV)
if ENABLE_WALLET
bitcoind_LDADD += libbitcoin_wallet.a
endif
bitcoind_SOURCES = bitcoind.cpp
#
if TARGET_WINDOWS
bitcoind_SOURCES += bitcoind-res.rc
endif
AM_CPPFLAGS += $(BDB_CPPFLAGS)
bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS)
# bitcoin-cli binary #
bitcoin_cli_LDADD = \
libbitcoin_cli.a \
libbitcoin_common.a \
$(BOOST_LIBS)
bitcoin_cli_SOURCES = bitcoin-cli.cpp
#
if TARGET_WINDOWS
bitcoin_cli_SOURCES += bitcoin-cli-res.rc
endif
# NOTE: This dependency is not strictly necessary, but without it make may try to build both in parallel, which breaks the LevelDB build system in a race
leveldb/libleveldb.a: leveldb/libmemenv.a
leveldb/%.a:
@echo "Building LevelDB ..." && $(MAKE) -C $(@D) $(@F) CXX="$(CXX)" \
CC="$(CC)" PLATFORM=$(TARGET_OS) AR="$(AR)" $(LEVELDB_TARGET_FLAGS) \
OPT="$(CXXFLAGS) $(CPPFLAGS)"
qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_common_a_SOURCES) $(libbitcoin_cli_a_SOURCES)
@test -n $(XGETTEXT) || echo "xgettext is required for updating translations"
@cd $(top_srcdir); XGETTEXT=$(XGETTEXT) share/qt/extract_strings_qt.py
CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno
DISTCLEANFILES = obj/build.h
EXTRA_DIST = leveldb Makefile.include
clean-local:
-$(MAKE) -C leveldb clean
rm -f leveldb/*/*.gcno leveldb/helpers/memenv/*.gcno
diff --git a/src/bignum.h b/src/bignum.h
deleted file mode 100644
index 6b77462d8..000000000
--- a/src/bignum.h
+++ /dev/null
@@ -1,530 +0,0 @@
-// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#ifndef BITCOIN_BIGNUM_H
-#define BITCOIN_BIGNUM_H
-
-#include "serialize.h"
-#include "uint256.h"
-#include "version.h"
-
-#include <stdexcept>
-#include <stdint.h>
-#include <vector>
-
-#include <openssl/bn.h>
-
-/** Errors thrown by the bignum class */
-class bignum_error : public std::runtime_error
-{
-public:
- explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
-};
-
-
-/** RAII encapsulated BN_CTX (OpenSSL bignum context) */
-class CAutoBN_CTX
-{
-protected:
- BN_CTX* pctx;
- BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; }
-
-public:
- CAutoBN_CTX()
- {
- pctx = BN_CTX_new();
- if (pctx == NULL)
- throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL");
- }
-
- ~CAutoBN_CTX()
- {
- if (pctx != NULL)
- BN_CTX_free(pctx);
- }
-
- operator BN_CTX*() { return pctx; }
- BN_CTX& operator*() { return *pctx; }
- BN_CTX** operator&() { return &pctx; }
- bool operator!() { return (pctx == NULL); }
-};
-
-
-/** C++ wrapper for BIGNUM (OpenSSL bignum) */
-class CBigNum : public BIGNUM
-{
-public:
- CBigNum()
- {
- BN_init(this);
- }
-
- CBigNum(const CBigNum& b)
- {
- BN_init(this);
- if (!BN_copy(this, &b))
- {
- BN_clear_free(this);
- throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
- }
- }
-
- CBigNum& operator=(const CBigNum& b)
- {
- if (!BN_copy(this, &b))
- throw bignum_error("CBigNum::operator= : BN_copy failed");
- return (*this);
- }
-
- ~CBigNum()
- {
- BN_clear_free(this);
- }
-
- //CBigNum(char n) is not portable. Use 'signed char' or 'unsigned char'.
- CBigNum(signed char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
- CBigNum(short n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
- CBigNum(int n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
- CBigNum(long n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
- CBigNum(long long n) { BN_init(this); setint64(n); }
- CBigNum(unsigned char n) { BN_init(this); setulong(n); }
- CBigNum(unsigned short n) { BN_init(this); setulong(n); }
- CBigNum(unsigned int n) { BN_init(this); setulong(n); }
- CBigNum(unsigned long n) { BN_init(this); setulong(n); }
- CBigNum(unsigned long long n) { BN_init(this); setuint64(n); }
- explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); }
-
- explicit CBigNum(const std::vector<unsigned char>& vch)
- {
- BN_init(this);
- setvch(vch);
- }
-
- void setulong(unsigned long n)
- {
- if (!BN_set_word(this, n))
- throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");
- }
-
- unsigned long getulong() const
- {
- return BN_get_word(this);
- }
-
- unsigned int getuint() const
- {
- return BN_get_word(this);
- }
-
- int getint() const
- {
- unsigned long n = BN_get_word(this);
- if (!BN_is_negative(this))
- return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
- else
- return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n);
- }
-
- void setint64(int64_t sn)
- {
- unsigned char pch[sizeof(sn) + 6];
- unsigned char* p = pch + 4;
- bool fNegative;
- uint64_t n;
-
- if (sn < (int64_t)0)
- {
- // Since the minimum signed integer cannot be represented as positive so long as its type is signed,
- // and it's not well-defined what happens if you make it unsigned before negating it,
- // we instead increment the negative integer by 1, convert it, then increment the (now positive) unsigned integer by 1 to compensate
- n = -(sn + 1);
- ++n;
- fNegative = true;
- } else {
- n = sn;
- fNegative = false;
- }
-
- bool fLeadingZeroes = true;
- for (int i = 0; i < 8; i++)
- {
- unsigned char c = (n >> 56) & 0xff;
- n <<= 8;
- if (fLeadingZeroes)
- {
- if (c == 0)
- continue;
- if (c & 0x80)
- *p++ = (fNegative ? 0x80 : 0);
- else if (fNegative)
- c |= 0x80;
- fLeadingZeroes = false;
- }
- *p++ = c;
- }
- unsigned int nSize = p - (pch + 4);
- pch[0] = (nSize >> 24) & 0xff;
- pch[1] = (nSize >> 16) & 0xff;
- pch[2] = (nSize >> 8) & 0xff;
- pch[3] = (nSize) & 0xff;
- BN_mpi2bn(pch, p - pch, this);
- }
-
- void setuint64(uint64_t n)
- {
- unsigned char pch[sizeof(n) + 6];
- unsigned char* p = pch + 4;
- bool fLeadingZeroes = true;
- for (int i = 0; i < 8; i++)
- {
- unsigned char c = (n >> 56) & 0xff;
- n <<= 8;
- if (fLeadingZeroes)
- {
- if (c == 0)
- continue;
- if (c & 0x80)
- *p++ = 0;
- fLeadingZeroes = false;
- }
- *p++ = c;
- }
- unsigned int nSize = p - (pch + 4);
- pch[0] = (nSize >> 24) & 0xff;
- pch[1] = (nSize >> 16) & 0xff;
- pch[2] = (nSize >> 8) & 0xff;
- pch[3] = (nSize) & 0xff;
- BN_mpi2bn(pch, p - pch, this);
- }
-
- void setuint256(uint256 n)
- {
- unsigned char pch[sizeof(n) + 6];
- unsigned char* p = pch + 4;
- bool fLeadingZeroes = true;
- unsigned char* pbegin = (unsigned char*)&n;
- unsigned char* psrc = pbegin + sizeof(n);
- while (psrc != pbegin)
- {
- unsigned char c = *(--psrc);
- if (fLeadingZeroes)
- {
- if (c == 0)
- continue;
- if (c & 0x80)
- *p++ = 0;
- fLeadingZeroes = false;
- }
- *p++ = c;
- }
- unsigned int nSize = p - (pch + 4);
- pch[0] = (nSize >> 24) & 0xff;
- pch[1] = (nSize >> 16) & 0xff;
- pch[2] = (nSize >> 8) & 0xff;
- pch[3] = (nSize >> 0) & 0xff;
- BN_mpi2bn(pch, p - pch, this);
- }
-
- uint256 getuint256() const
- {
- unsigned int nSize = BN_bn2mpi(this, NULL);
- if (nSize < 4)
- return 0;
- std::vector<unsigned char> vch(nSize);
- BN_bn2mpi(this, &vch[0]);
- if (vch.size() > 4)
- vch[4] &= 0x7f;
- uint256 n = 0;
- for (unsigned int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
- ((unsigned char*)&n)[i] = vch[j];
- return n;
- }
-
- void setvch(const std::vector<unsigned char>& vch)
- {
- std::vector<unsigned char> vch2(vch.size() + 4);
- unsigned int nSize = vch.size();
- // BIGNUM's byte stream format expects 4 bytes of
- // big endian size data info at the front
- vch2[0] = (nSize >> 24) & 0xff;
- vch2[1] = (nSize >> 16) & 0xff;
- vch2[2] = (nSize >> 8) & 0xff;
- vch2[3] = (nSize >> 0) & 0xff;
- // swap data to big endian
- reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
- BN_mpi2bn(&vch2[0], vch2.size(), this);
- }
-
- std::vector<unsigned char> getvch() const
- {
- unsigned int nSize = BN_bn2mpi(this, NULL);
- if (nSize <= 4)
- return std::vector<unsigned char>();
- std::vector<unsigned char> vch(nSize);
- BN_bn2mpi(this, &vch[0]);
- vch.erase(vch.begin(), vch.begin() + 4);
- reverse(vch.begin(), vch.end());
- return vch;
- }
-
- void SetHex(const std::string& str)
- {
- // skip 0x
- const char* psz = str.c_str();
- while (isspace(*psz))
- psz++;
- bool fNegative = false;
- if (*psz == '-')
- {
- fNegative = true;
- psz++;
- }
- if (psz[0] == '0' && tolower(psz[1]) == 'x')
- psz += 2;
- while (isspace(*psz))
- psz++;
-
- // hex string to bignum
- *this = 0;
- int n;
- while ((n = HexDigit(*psz)) != -1)
- {
- *this <<= 4;
- *this += n;
- ++psz;
- }
- if (fNegative)
- *this = 0 - *this;
- }
-
- std::string ToString(int nBase=10) const
- {
- CAutoBN_CTX pctx;
- CBigNum bnBase = nBase;
- CBigNum bn0 = 0;
- std::string str;
- CBigNum bn = *this;
- BN_set_negative(&bn, false);
- CBigNum dv;
- CBigNum rem;
- if (BN_cmp(&bn, &bn0) == 0)
- return "0";
- while (BN_cmp(&bn, &bn0) > 0)
- {
- if (!BN_div(&dv, &rem, &bn, &bnBase, pctx))
- throw bignum_error("CBigNum::ToString() : BN_div failed");
- bn = dv;
- unsigned int c = rem.getulong();
- str += "0123456789abcdef"[c];
- }
- if (BN_is_negative(this))
- str += "-";
- reverse(str.begin(), str.end());
- return str;
- }
-
- std::string GetHex() const
- {
- return ToString(16);
- }
-
- unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const
- {
- return ::GetSerializeSize(getvch(), nType, nVersion);
- }
-
- template<typename Stream>
- void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const
- {
- ::Serialize(s, getvch(), nType, nVersion);
- }
-
- template<typename Stream>
- void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION)
- {
- std::vector<unsigned char> vch;
- ::Unserialize(s, vch, nType, nVersion);
- setvch(vch);
- }
-
-
- bool operator!() const
- {
- return BN_is_zero(this);
- }
-
- CBigNum& operator+=(const CBigNum& b)
- {
- if (!BN_add(this, this, &b))
- throw bignum_error("CBigNum::operator+= : BN_add failed");
- return *this;
- }
-
- CBigNum& operator-=(const CBigNum& b)
- {
- *this = *this - b;
- return *this;
- }
-
- CBigNum& operator*=(const CBigNum& b)
- {
- CAutoBN_CTX pctx;
- if (!BN_mul(this, this, &b, pctx))
- throw bignum_error("CBigNum::operator*= : BN_mul failed");
- return *this;
- }
-
- CBigNum& operator/=(const CBigNum& b)
- {
- *this = *this / b;
- return *this;
- }
-
- CBigNum& operator%=(const CBigNum& b)
- {
- *this = *this % b;
- return *this;
- }
-
- CBigNum& operator<<=(unsigned int shift)
- {
- if (!BN_lshift(this, this, shift))
- throw bignum_error("CBigNum:operator<<= : BN_lshift failed");
- return *this;
- }
-
- CBigNum& operator>>=(unsigned int shift)
- {
- // Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number
- // if built on ubuntu 9.04 or 9.10, probably depends on version of OpenSSL
- CBigNum a = 1;
- a <<= shift;
- if (BN_cmp(&a, this) > 0)
- {
- *this = 0;
- return *this;
- }
-
- if (!BN_rshift(this, this, shift))
- throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
- return *this;
- }
-
-
- CBigNum& operator++()
- {
- // prefix operator
- if (!BN_add(this, this, BN_value_one()))
- throw bignum_error("CBigNum::operator++ : BN_add failed");
- return *this;
- }
-
- const CBigNum operator++(int)
- {
- // postfix operator
- const CBigNum ret = *this;
- ++(*this);
- return ret;
- }
-
- CBigNum& operator--()
- {
- // prefix operator
- CBigNum r;
- if (!BN_sub(&r, this, BN_value_one()))
- throw bignum_error("CBigNum::operator-- : BN_sub failed");
- *this = r;
- return *this;
- }
-
- const CBigNum operator--(int)
- {
- // postfix operator
- const CBigNum ret = *this;
- --(*this);
- return ret;
- }
-
-
- friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
- friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
- friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);
-};
-
-
-
-inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
-{
- CBigNum r;
- if (!BN_add(&r, &a, &b))
- throw bignum_error("CBigNum::operator+ : BN_add failed");
- return r;
-}
-
-inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
-{
- CBigNum r;
- if (!BN_sub(&r, &a, &b))
- throw bignum_error("CBigNum::operator- : BN_sub failed");
- return r;
-}
-
-inline const CBigNum operator-(const CBigNum& a)
-{
- CBigNum r(a);
- BN_set_negative(&r, !BN_is_negative(&r));
- return r;
-}
-
-inline const CBigNum operator*(const CBigNum& a, const CBigNum& b)
-{
- CAutoBN_CTX pctx;
- CBigNum r;
- if (!BN_mul(&r, &a, &b, pctx))
- throw bignum_error("CBigNum::operator* : BN_mul failed");
- return r;
-}
-
-inline const CBigNum operator/(const CBigNum& a, const CBigNum& b)
-{
- CAutoBN_CTX pctx;
- CBigNum r;
- if (!BN_div(&r, NULL, &a, &b, pctx))
- throw bignum_error("CBigNum::operator/ : BN_div failed");
- return r;
-}
-
-inline const CBigNum operator%(const CBigNum& a, const CBigNum& b)
-{
- CAutoBN_CTX pctx;
- CBigNum r;
- if (!BN_mod(&r, &a, &b, pctx))
- throw bignum_error("CBigNum::operator% : BN_div failed");
- return r;
-}
-
-inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
-{
- CBigNum r;
- if (!BN_lshift(&r, &a, shift))
- throw bignum_error("CBigNum:operator<< : BN_lshift failed");
- return r;
-}
-
-inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
-{
- CBigNum r = a;
- r >>= shift;
- return r;
-}
-
-inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); }
-inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); }
-inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); }
-inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); }
-inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); }
-inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); }
-
-#endif
diff --git a/src/chainparams.h b/src/chainparams.h
index f3f24efd9..5600b904c 100644
--- a/src/chainparams.h
+++ b/src/chainparams.h
@@ -1,109 +1,108 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2013 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_CHAIN_PARAMS_H
#define BITCOIN_CHAIN_PARAMS_H
-#include "bignum.h"
#include "uint256.h"
#include <vector>
using namespace std;
#define MESSAGE_START_SIZE 4
typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
class CAddress;
class CBlock;
struct CDNSSeedData {
string name, host;
CDNSSeedData(const string &strName, const string &strHost) : name(strName), host(strHost) {}
};
/**
* CChainParams defines various tweakable parameters of a given instance of the
* Bitcoin system. There are three: the main network on which people trade goods
* and services, the public test network which gets reset from time to time and
* a regression test mode which is intended for private networks only. It has
* minimal difficulty to ensure that blocks can be found instantly.
*/
class CChainParams
{
public:
enum Network {
MAIN,
TESTNET,
REGTEST,
MAX_NETWORK_TYPES
};
enum Base58Type {
PUBKEY_ADDRESS,
SCRIPT_ADDRESS,
SECRET_KEY,
EXT_PUBLIC_KEY,
EXT_SECRET_KEY,
MAX_BASE58_TYPES
};
const uint256& HashGenesisBlock() const { return hashGenesisBlock; }
const MessageStartChars& MessageStart() const { return pchMessageStart; }
const vector<unsigned char>& AlertKey() const { return vAlertPubKey; }
int GetDefaultPort() const { return nDefaultPort; }
const uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; }
int SubsidyHalvingInterval() const { return nSubsidyHalvingInterval; }
virtual const CBlock& GenesisBlock() const = 0;
virtual bool RequireRPCPassword() const { return true; }
const string& DataDir() const { return strDataDir; }
virtual Network NetworkID() const = 0;
const vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; }
const std::vector<unsigned char> &Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
virtual const vector<CAddress>& FixedSeeds() const = 0;
int RPCPort() const { return nRPCPort; }
protected:
CChainParams() {}
uint256 hashGenesisBlock;
MessageStartChars pchMessageStart;
// Raw pub key bytes for the broadcast alert signing key.
vector<unsigned char> vAlertPubKey;
int nDefaultPort;
int nRPCPort;
uint256 bnProofOfWorkLimit;
int nSubsidyHalvingInterval;
string strDataDir;
vector<CDNSSeedData> vSeeds;
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
};
/**
* Return the currently selected parameters. This won't change after app startup
* outside of the unit tests.
*/
const CChainParams &Params();
/** Sets the params returned by Params() to those for the given network. */
void SelectParams(CChainParams::Network network);
/**
* Looks for -regtest or -testnet and then calls SelectParams as appropriate.
* Returns false if an invalid combination is given.
*/
bool SelectParamsFromCommandLine();
inline bool TestNet() {
// Note: it's deliberate that this returns "false" for regression test mode.
return Params().NetworkID() == CChainParams::TESTNET;
}
inline bool RegTest() {
return Params().NetworkID() == CChainParams::REGTEST;
}
#endif
diff --git a/src/protocol.h b/src/protocol.h
index 86e08ddcf..e6f105fe5 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -1,140 +1,141 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2013 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef __cplusplus
# error This header can only be compiled as C++.
#endif
#ifndef __INCLUDED_PROTOCOL_H__
#define __INCLUDED_PROTOCOL_H__
#include "chainparams.h"
#include "netbase.h"
#include "serialize.h"
#include "uint256.h"
+#include "version.h"
#include <stdint.h>
#include <string>
/** Message header.
* (4) message start.
* (12) command.
* (4) size.
* (4) checksum.
*/
class CMessageHeader
{
public:
CMessageHeader();
CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn);
std::string GetCommand() const;
bool IsValid() const;
IMPLEMENT_SERIALIZE
(
READWRITE(FLATDATA(pchMessageStart));
READWRITE(FLATDATA(pchCommand));
READWRITE(nMessageSize);
READWRITE(nChecksum);
)
// TODO: make private (improves encapsulation)
public:
enum {
COMMAND_SIZE=12,
MESSAGE_SIZE_SIZE=sizeof(int),
CHECKSUM_SIZE=sizeof(int),
MESSAGE_SIZE_OFFSET=MESSAGE_START_SIZE+COMMAND_SIZE,
CHECKSUM_OFFSET=MESSAGE_SIZE_OFFSET+MESSAGE_SIZE_SIZE,
HEADER_SIZE=MESSAGE_START_SIZE+COMMAND_SIZE+MESSAGE_SIZE_SIZE+CHECKSUM_SIZE
};
char pchMessageStart[MESSAGE_START_SIZE];
char pchCommand[COMMAND_SIZE];
unsigned int nMessageSize;
unsigned int nChecksum;
};
/** nServices flags */
enum
{
NODE_NETWORK = (1 << 0),
};
/** A CService with information about it as peer */
class CAddress : public CService
{
public:
CAddress();
explicit CAddress(CService ipIn, uint64_t nServicesIn=NODE_NETWORK);
void Init();
IMPLEMENT_SERIALIZE
(
CAddress* pthis = const_cast<CAddress*>(this);
CService* pip = (CService*)pthis;
if (fRead)
pthis->Init();
if (nType & SER_DISK)
READWRITE(nVersion);
if ((nType & SER_DISK) ||
(nVersion >= CADDR_TIME_VERSION && !(nType & SER_GETHASH)))
READWRITE(nTime);
READWRITE(nServices);
READWRITE(*pip);
)
void print() const;
// TODO: make private (improves encapsulation)
public:
uint64_t nServices;
// disk and network only
unsigned int nTime;
// memory only
int64_t nLastTry;
};
/** inv message data */
class CInv
{
public:
CInv();
CInv(int typeIn, const uint256& hashIn);
CInv(const std::string& strType, const uint256& hashIn);
IMPLEMENT_SERIALIZE
(
READWRITE(type);
READWRITE(hash);
)
friend bool operator<(const CInv& a, const CInv& b);
bool IsKnownType() const;
const char* GetCommand() const;
std::string ToString() const;
void print() const;
// TODO: make private (improves encapsulation)
public:
int type;
uint256 hash;
};
enum
{
MSG_TX = 1,
MSG_BLOCK,
// Nodes may always request a MSG_FILTERED_BLOCK in a getdata, however,
// MSG_FILTERED_BLOCK should not appear in any invs except as a part of getdata.
MSG_FILTERED_BLOCK,
};
#endif // __INCLUDED_PROTOCOL_H__
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp
index 897fb87e4..fb06fb343 100644
--- a/src/test/DoS_tests.cpp
+++ b/src/test/DoS_tests.cpp
@@ -1,321 +1,320 @@
// Copyright (c) 2011-2014 The Bitcoin Core developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
//
// Unit tests for denial-of-service detection/prevention code
//
-#include "bignum.h"
#include "keystore.h"
#include "main.h"
#include "net.h"
#include "script.h"
#include "serialize.h"
#include <stdint.h>
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
// Tests this internal-to-main.cpp method:
extern bool AddOrphanTx(const CTransaction& tx);
extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans);
extern std::map<uint256, CTransaction> mapOrphanTransactions;
extern std::map<uint256, std::set<uint256> > mapOrphanTransactionsByPrev;
CService ip(uint32_t i)
{
struct in_addr s;
s.s_addr = i;
return CService(CNetAddr(s), Params().GetDefaultPort());
}
BOOST_AUTO_TEST_SUITE(DoS_tests)
BOOST_AUTO_TEST_CASE(DoS_banning)
{
CNode::ClearBanned();
CAddress addr1(ip(0xa0b0c001));
CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
dummyNode1.nVersion = 1;
Misbehaving(dummyNode1.GetId(), 100); // Should get banned
SendMessages(&dummyNode1, false);
BOOST_CHECK(CNode::IsBanned(addr1));
BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned
CAddress addr2(ip(0xa0b0c002));
CNode dummyNode2(INVALID_SOCKET, addr2, "", true);
dummyNode2.nVersion = 1;
Misbehaving(dummyNode2.GetId(), 50);
SendMessages(&dummyNode2, false);
BOOST_CHECK(!CNode::IsBanned(addr2)); // 2 not banned yet...
BOOST_CHECK(CNode::IsBanned(addr1)); // ... but 1 still should be
Misbehaving(dummyNode2.GetId(), 50);
SendMessages(&dummyNode2, false);
BOOST_CHECK(CNode::IsBanned(addr2));
}
BOOST_AUTO_TEST_CASE(DoS_banscore)
{
CNode::ClearBanned();
mapArgs["-banscore"] = "111"; // because 11 is my favorite number
CAddress addr1(ip(0xa0b0c001));
CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
dummyNode1.nVersion = 1;
Misbehaving(dummyNode1.GetId(), 100);
SendMessages(&dummyNode1, false);
BOOST_CHECK(!CNode::IsBanned(addr1));
Misbehaving(dummyNode1.GetId(), 10);
SendMessages(&dummyNode1, false);
BOOST_CHECK(!CNode::IsBanned(addr1));
Misbehaving(dummyNode1.GetId(), 1);
SendMessages(&dummyNode1, false);
BOOST_CHECK(CNode::IsBanned(addr1));
mapArgs.erase("-banscore");
}
BOOST_AUTO_TEST_CASE(DoS_bantime)
{
CNode::ClearBanned();
int64_t nStartTime = GetTime();
SetMockTime(nStartTime); // Overrides future calls to GetTime()
CAddress addr(ip(0xa0b0c001));
CNode dummyNode(INVALID_SOCKET, addr, "", true);
dummyNode.nVersion = 1;
Misbehaving(dummyNode.GetId(), 100);
SendMessages(&dummyNode, false);
BOOST_CHECK(CNode::IsBanned(addr));
SetMockTime(nStartTime+60*60);
BOOST_CHECK(CNode::IsBanned(addr));
SetMockTime(nStartTime+60*60*24+1);
BOOST_CHECK(!CNode::IsBanned(addr));
}
static bool CheckNBits(unsigned int nbits1, int64_t time1, unsigned int nbits2, int64_t time2)\
{
if (time1 > time2)
return CheckNBits(nbits2, time2, nbits1, time1);
int64_t deltaTime = time2-time1;
uint256 required;
required.SetCompact(ComputeMinWork(nbits1, deltaTime));
uint256 have;
have.SetCompact(nbits2);
return (have <= required);
}
BOOST_AUTO_TEST_CASE(DoS_checknbits)
{
using namespace boost::assign; // for 'map_list_of()'
// Timestamps,nBits from the bitcoin block chain.
// These are the block-chain checkpoint blocks
typedef std::map<int64_t, unsigned int> BlockData;
BlockData chainData =
map_list_of(1239852051,486604799)(1262749024,486594666)
(1279305360,469854461)(1280200847,469830746)(1281678674,469809688)
(1296207707,453179945)(1302624061,453036989)(1309640330,437004818)
(1313172719,436789733);
// Make sure CheckNBits considers every combination of block-chain-lock-in-points
// "sane":
BOOST_FOREACH(const BlockData::value_type& i, chainData)
{
BOOST_FOREACH(const BlockData::value_type& j, chainData)
{
BOOST_CHECK(CheckNBits(i.second, i.first, j.second, j.first));
}
}
// Test a couple of insane combinations:
BlockData::value_type firstcheck = *(chainData.begin());
BlockData::value_type lastcheck = *(chainData.rbegin());
// First checkpoint difficulty at or a while after the last checkpoint time should fail when
// compared to last checkpoint
BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*10, lastcheck.second, lastcheck.first));
BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*60*24*14, lastcheck.second, lastcheck.first));
// ... but OK if enough time passed for difficulty to adjust downward:
BOOST_CHECK(CheckNBits(firstcheck.second, lastcheck.first+60*60*24*365*4, lastcheck.second, lastcheck.first));
}
CTransaction RandomOrphan()
{
std::map<uint256, CTransaction>::iterator it;
it = mapOrphanTransactions.lower_bound(GetRandHash());
if (it == mapOrphanTransactions.end())
it = mapOrphanTransactions.begin();
return it->second;
}
BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
{
CKey key;
key.MakeNewKey(true);
CBasicKeyStore keystore;
keystore.AddKey(key);
// 50 orphan transactions:
for (int i = 0; i < 50; i++)
{
CTransaction tx;
tx.vin.resize(1);
tx.vin[0].prevout.n = 0;
tx.vin[0].prevout.hash = GetRandHash();
tx.vin[0].scriptSig << OP_1;
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
AddOrphanTx(tx);
}
// ... and 50 that depend on other orphans:
for (int i = 0; i < 50; i++)
{
CTransaction txPrev = RandomOrphan();
CTransaction tx;
tx.vin.resize(1);
tx.vin[0].prevout.n = 0;
tx.vin[0].prevout.hash = txPrev.GetHash();
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
SignSignature(keystore, txPrev, tx, 0);
AddOrphanTx(tx);
}
// This really-big orphan should be ignored:
for (int i = 0; i < 10; i++)
{
CTransaction txPrev = RandomOrphan();
CTransaction tx;
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
tx.vin.resize(500);
for (unsigned int j = 0; j < tx.vin.size(); j++)
{
tx.vin[j].prevout.n = j;
tx.vin[j].prevout.hash = txPrev.GetHash();
}
SignSignature(keystore, txPrev, tx, 0);
// Re-use same signature for other inputs
// (they don't have to be valid for this test)
for (unsigned int j = 1; j < tx.vin.size(); j++)
tx.vin[j].scriptSig = tx.vin[0].scriptSig;
BOOST_CHECK(!AddOrphanTx(tx));
}
// Test LimitOrphanTxSize() function:
LimitOrphanTxSize(40);
BOOST_CHECK(mapOrphanTransactions.size() <= 40);
LimitOrphanTxSize(10);
BOOST_CHECK(mapOrphanTransactions.size() <= 10);
LimitOrphanTxSize(0);
BOOST_CHECK(mapOrphanTransactions.empty());
BOOST_CHECK(mapOrphanTransactionsByPrev.empty());
}
BOOST_AUTO_TEST_CASE(DoS_checkSig)
{
// Test signature caching code (see key.cpp Verify() methods)
CKey key;
key.MakeNewKey(true);
CBasicKeyStore keystore;
keystore.AddKey(key);
unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
// 100 orphan transactions:
static const int NPREV=100;
CTransaction orphans[NPREV];
for (int i = 0; i < NPREV; i++)
{
CTransaction& tx = orphans[i];
tx.vin.resize(1);
tx.vin[0].prevout.n = 0;
tx.vin[0].prevout.hash = GetRandHash();
tx.vin[0].scriptSig << OP_1;
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
AddOrphanTx(tx);
}
// Create a transaction that depends on orphans:
CTransaction tx;
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
tx.vin.resize(NPREV);
for (unsigned int j = 0; j < tx.vin.size(); j++)
{
tx.vin[j].prevout.n = 0;
tx.vin[j].prevout.hash = orphans[j].GetHash();
}
// Creating signatures primes the cache:
boost::posix_time::ptime mst1 = boost::posix_time::microsec_clock::local_time();
for (unsigned int j = 0; j < tx.vin.size(); j++)
BOOST_CHECK(SignSignature(keystore, orphans[j], tx, j));
boost::posix_time::ptime mst2 = boost::posix_time::microsec_clock::local_time();
boost::posix_time::time_duration msdiff = mst2 - mst1;
long nOneValidate = msdiff.total_milliseconds();
if (fDebug) printf("DoS_Checksig sign: %ld\n", nOneValidate);
// ... now validating repeatedly should be quick:
// 2.8GHz machine, -g build: Sign takes ~760ms,
// uncached Verify takes ~250ms, cached Verify takes ~50ms
// (for 100 single-signature inputs)
mst1 = boost::posix_time::microsec_clock::local_time();
for (unsigned int i = 0; i < 5; i++)
for (unsigned int j = 0; j < tx.vin.size(); j++)
BOOST_CHECK(VerifySignature(CCoins(orphans[j], MEMPOOL_HEIGHT), tx, j, flags, SIGHASH_ALL));
mst2 = boost::posix_time::microsec_clock::local_time();
msdiff = mst2 - mst1;
long nManyValidate = msdiff.total_milliseconds();
if (fDebug) printf("DoS_Checksig five: %ld\n", nManyValidate);
BOOST_CHECK_MESSAGE(nManyValidate < nOneValidate, "Signature cache timing failed");
// Empty a signature, validation should fail:
CScript save = tx.vin[0].scriptSig;
tx.vin[0].scriptSig = CScript();
BOOST_CHECK(!VerifySignature(CCoins(orphans[0], MEMPOOL_HEIGHT), tx, 0, flags, SIGHASH_ALL));
tx.vin[0].scriptSig = save;
// Swap signatures, validation should fail:
std::swap(tx.vin[0].scriptSig, tx.vin[1].scriptSig);
BOOST_CHECK(!VerifySignature(CCoins(orphans[0], MEMPOOL_HEIGHT), tx, 0, flags, SIGHASH_ALL));
BOOST_CHECK(!VerifySignature(CCoins(orphans[1], MEMPOOL_HEIGHT), tx, 1, flags, SIGHASH_ALL));
std::swap(tx.vin[0].scriptSig, tx.vin[1].scriptSig);
// Exercise -maxsigcachesize code:
mapArgs["-maxsigcachesize"] = "10";
// Generate a new, different signature for vin[0] to trigger cache clear:
CScript oldSig = tx.vin[0].scriptSig;
BOOST_CHECK(SignSignature(keystore, orphans[0], tx, 0));
BOOST_CHECK(tx.vin[0].scriptSig != oldSig);
for (unsigned int j = 0; j < tx.vin.size(); j++)
BOOST_CHECK(VerifySignature(CCoins(orphans[j], MEMPOOL_HEIGHT), tx, j, flags, SIGHASH_ALL));
mapArgs.erase("-maxsigcachesize");
LimitOrphanTxSize(0);
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/Makefile.am b/src/test/Makefile.am
index e12f4904f..cde3a31e2 100644
--- a/src/test/Makefile.am
+++ b/src/test/Makefile.am
@@ -1,77 +1,77 @@
include $(top_srcdir)/src/Makefile.include
AM_CPPFLAGS += -I$(top_srcdir)/src
bin_PROGRAMS = test_bitcoin
TESTS = test_bitcoin
JSON_TEST_FILES = \
data/script_valid.json \
data/base58_keys_valid.json \
data/sig_canonical.json \
data/sig_noncanonical.json \
data/base58_encode_decode.json \
data/base58_keys_invalid.json \
data/script_invalid.json \
data/tx_invalid.json \
data/tx_valid.json \
data/sighash.json
RAW_TEST_FILES = data/alertTests.raw
BUILT_SOURCES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h)
# test_bitcoin binary #
test_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(TESTDEFS)
test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBLEVELDB) $(LIBMEMENV) \
$(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB)
if ENABLE_WALLET
test_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
endif
test_bitcoin_LDADD += $(BDB_LIBS)
test_bitcoin_SOURCES = \
+ bignum.h \
alert_tests.cpp \
allocator_tests.cpp \
base32_tests.cpp \
base58_tests.cpp \
base64_tests.cpp \
- bignum_tests.cpp \
bloom_tests.cpp \
canonical_tests.cpp \
checkblock_tests.cpp \
Checkpoints_tests.cpp \
compress_tests.cpp \
DoS_tests.cpp \
getarg_tests.cpp \
key_tests.cpp \
main_tests.cpp \
miner_tests.cpp \
mruset_tests.cpp \
multisig_tests.cpp \
netbase_tests.cpp \
pmt_tests.cpp \
rpc_tests.cpp \
script_P2SH_tests.cpp \
script_tests.cpp \
serialize_tests.cpp \
sigopcount_tests.cpp \
test_bitcoin.cpp \
transaction_tests.cpp \
uint256_tests.cpp \
util_tests.cpp \
scriptnum_tests.cpp \
sighash_tests.cpp \
$(JSON_TEST_FILES) $(RAW_TEST_FILES)
if ENABLE_WALLET
test_bitcoin_SOURCES += \
accounting_tests.cpp \
wallet_tests.cpp \
rpc_wallet_tests.cpp
endif
nodist_test_bitcoin_SOURCES = $(BUILT_SOURCES)
CLEANFILES = *.gcda *.gcno $(BUILT_SOURCES)
diff --git a/src/test/bignum.h b/src/test/bignum.h
new file mode 100644
index 000000000..b57800f37
--- /dev/null
+++ b/src/test/bignum.h
@@ -0,0 +1,179 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_BIGNUM_H
+#define BITCOIN_BIGNUM_H
+
+#include <algorithm>
+#include <limits>
+#include <stdexcept>
+#include <stdint.h>
+#include <vector>
+
+#include <openssl/bn.h>
+
+class bignum_error : public std::runtime_error
+{
+public:
+ explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
+};
+
+
+/** C++ wrapper for BIGNUM (OpenSSL bignum) */
+class CBigNum : public BIGNUM
+{
+public:
+ CBigNum()
+ {
+ BN_init(this);
+ }
+
+ CBigNum(const CBigNum& b)
+ {
+ BN_init(this);
+ if (!BN_copy(this, &b))
+ {
+ BN_clear_free(this);
+ throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
+ }
+ }
+
+ CBigNum& operator=(const CBigNum& b)
+ {
+ if (!BN_copy(this, &b))
+ throw bignum_error("CBigNum::operator= : BN_copy failed");
+ return (*this);
+ }
+
+ ~CBigNum()
+ {
+ BN_clear_free(this);
+ }
+
+ CBigNum(long long n) { BN_init(this); setint64(n); }
+
+ explicit CBigNum(const std::vector<unsigned char>& vch)
+ {
+ BN_init(this);
+ setvch(vch);
+ }
+
+ int getint() const
+ {
+ unsigned long n = BN_get_word(this);
+ if (!BN_is_negative(this))
+ return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
+ else
+ return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n);
+ }
+
+ void setint64(int64_t sn)
+ {
+ unsigned char pch[sizeof(sn) + 6];
+ unsigned char* p = pch + 4;
+ bool fNegative;
+ uint64_t n;
+
+ if (sn < (int64_t)0)
+ {
+ // Since the minimum signed integer cannot be represented as positive so long as its type is signed,
+ // and it's not well-defined what happens if you make it unsigned before negating it,
+ // we instead increment the negative integer by 1, convert it, then increment the (now positive) unsigned integer by 1 to compensate
+ n = -(sn + 1);
+ ++n;
+ fNegative = true;
+ } else {
+ n = sn;
+ fNegative = false;
+ }
+
+ bool fLeadingZeroes = true;
+ for (int i = 0; i < 8; i++)
+ {
+ unsigned char c = (n >> 56) & 0xff;
+ n <<= 8;
+ if (fLeadingZeroes)
+ {
+ if (c == 0)
+ continue;
+ if (c & 0x80)
+ *p++ = (fNegative ? 0x80 : 0);
+ else if (fNegative)
+ c |= 0x80;
+ fLeadingZeroes = false;
+ }
+ *p++ = c;
+ }
+ unsigned int nSize = p - (pch + 4);
+ pch[0] = (nSize >> 24) & 0xff;
+ pch[1] = (nSize >> 16) & 0xff;
+ pch[2] = (nSize >> 8) & 0xff;
+ pch[3] = (nSize) & 0xff;
+ BN_mpi2bn(pch, p - pch, this);
+ }
+
+ void setvch(const std::vector<unsigned char>& vch)
+ {
+ std::vector<unsigned char> vch2(vch.size() + 4);
+ unsigned int nSize = vch.size();
+ // BIGNUM's byte stream format expects 4 bytes of
+ // big endian size data info at the front
+ vch2[0] = (nSize >> 24) & 0xff;
+ vch2[1] = (nSize >> 16) & 0xff;
+ vch2[2] = (nSize >> 8) & 0xff;
+ vch2[3] = (nSize >> 0) & 0xff;
+ // swap data to big endian
+ reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
+ BN_mpi2bn(&vch2[0], vch2.size(), this);
+ }
+
+ std::vector<unsigned char> getvch() const
+ {
+ unsigned int nSize = BN_bn2mpi(this, NULL);
+ if (nSize <= 4)
+ return std::vector<unsigned char>();
+ std::vector<unsigned char> vch(nSize);
+ BN_bn2mpi(this, &vch[0]);
+ vch.erase(vch.begin(), vch.begin() + 4);
+ reverse(vch.begin(), vch.end());
+ return vch;
+ }
+
+ friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
+};
+
+
+
+inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
+{
+ CBigNum r;
+ if (!BN_add(&r, &a, &b))
+ throw bignum_error("CBigNum::operator+ : BN_add failed");
+ return r;
+}
+
+inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
+{
+ CBigNum r;
+ if (!BN_sub(&r, &a, &b))
+ throw bignum_error("CBigNum::operator- : BN_sub failed");
+ return r;
+}
+
+inline const CBigNum operator-(const CBigNum& a)
+{
+ CBigNum r(a);
+ BN_set_negative(&r, !BN_is_negative(&r));
+ return r;
+}
+
+inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); }
+inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); }
+inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); }
+inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); }
+inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); }
+inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); }
+
+#endif
diff --git a/src/test/bignum_tests.cpp b/src/test/bignum_tests.cpp
deleted file mode 100644
index 01967c768..000000000
--- a/src/test/bignum_tests.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2012-2014 The Bitcoin Core developers
-// Distributed under the MIT/X11 software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#include "bignum.h"
-
-#include <limits>
-#include <stdint.h>
-
-#include <boost/test/unit_test.hpp>
-
-BOOST_AUTO_TEST_SUITE(bignum_tests)
-
-// Unfortunately there's no standard way of preventing a function from being
-// inlined, so we define a macro for it.
-//
-// You should use it like this:
-// NOINLINE void function() {...}
-#if defined(__GNUC__)
-// This also works and will be defined for any compiler implementing GCC
-// extensions, such as Clang and ICC.
-#define NOINLINE __attribute__((noinline))
-#elif defined(_MSC_VER)
-#define NOINLINE __declspec(noinline)
-#else
-// We give out a warning because it impacts the correctness of one bignum test.
-#warning You should define NOINLINE for your compiler.
-#define NOINLINE
-#endif
-
-// For the following test case, it is useful to use additional tools.
-//
-// The simplest one to use is the compiler flag -ftrapv, which detects integer
-// overflows and similar errors. However, due to optimizations and compilers
-// taking advantage of undefined behavior sometimes it may not actually detect
-// anything.
-//
-// You can also use compiler-based stack protection to possibly detect possible
-// stack buffer overruns.
-//
-// For more accurate diagnostics, you can use an undefined arithmetic operation
-// detector such as the clang's undefined behaviour checker.
-// See also: http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation
-//
-// It might also be useful to use Google's AddressSanitizer to detect
-// stack buffer overruns, which valgrind can't currently detect.
-
-// Let's force this code not to be inlined, in order to actually
-// test a generic version of the function. This increases the chance
-// that -ftrapv will detect overflows.
-NOINLINE void mysetint64(CBigNum& num, int64_t n)
-{
- num.setint64(n);
-}
-
-// For each number, we do 2 tests: one with inline code, then we reset the
-// value to 0, then the second one with a non-inlined function.
-BOOST_AUTO_TEST_CASE(bignum_setint64)
-{
- int64_t n;
-
- {
- n = 0;
- CBigNum num(n);
- BOOST_CHECK(num.ToString() == "0");
- num.setulong(0);
- BOOST_CHECK(num.ToString() == "0");
- mysetint64(num, n);
- BOOST_CHECK(num.ToString() == "0");
- }
- {
- n = 1;
- CBigNum num(n);
- BOOST_CHECK(num.ToString() == "1");
- num.setulong(0);
- BOOST_CHECK(num.ToString() == "0");
- mysetint64(num, n);
- BOOST_CHECK(num.ToString() == "1");
- }
- {
- n = -1;
- CBigNum num(n);
- BOOST_CHECK(num.ToString() == "-1");
- num.setulong(0);
- BOOST_CHECK(num.ToString() == "0");
- mysetint64(num, n);
- BOOST_CHECK(num.ToString() == "-1");
- }
- {
- n = 5;
- CBigNum num(n);
- BOOST_CHECK(num.ToString() == "5");
- num.setulong(0);
- BOOST_CHECK(num.ToString() == "0");
- mysetint64(num, n);
- BOOST_CHECK(num.ToString() == "5");
- }
- {
- n = -5;
- CBigNum num(n);
- BOOST_CHECK(num.ToString() == "-5");
- num.setulong(0);
- BOOST_CHECK(num.ToString() == "0");
- mysetint64(num, n);
- BOOST_CHECK(num.ToString() == "-5");
- }
- {
- n = std::numeric_limits<int64_t>::min();
- CBigNum num(n);
- BOOST_CHECK(num.ToString() == "-9223372036854775808");
- num.setulong(0);
- BOOST_CHECK(num.ToString() == "0");
- mysetint64(num, n);
- BOOST_CHECK(num.ToString() == "-9223372036854775808");
- }
- {
- n = std::numeric_limits<int64_t>::max();
- CBigNum num(n);
- BOOST_CHECK(num.ToString() == "9223372036854775807");
- num.setulong(0);
- BOOST_CHECK(num.ToString() == "0");
- mysetint64(num, n);
- BOOST_CHECK(num.ToString() == "9223372036854775807");
- }
-}
-
-
-BOOST_AUTO_TEST_CASE(bignum_SetHex)
-{
- std::string hexStr = "deecf97fd890808b9cc0f1b6a3e7a60b400f52710e6ad075b1340755bfa58cc9";
- CBigNum num;
- num.SetHex(hexStr);
- BOOST_CHECK_EQUAL(num.GetHex(), hexStr);
-}
-
-BOOST_AUTO_TEST_SUITE_END()

File Metadata

Mime Type
text/x-diff
Expires
Wed, May 21, 18:29 (22 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5865703
Default Alt Text
(49 KB)

Event Timeline