Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14864295
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
49 KB
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
rABC Bitcoin ABC
Event Timeline
Log In to Comment