aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am26
-rw-r--r--src/Makefile.test.include2
-rw-r--r--src/addrman.cpp3
-rw-r--r--src/base58.h1
-rw-r--r--src/chainparams.cpp46
-rw-r--r--src/chainparams.h25
-rw-r--r--src/chainparamsbase.cpp3
-rw-r--r--src/chainparamsbase.h1
-rw-r--r--src/crypter.h2
-rw-r--r--src/init.cpp61
-rw-r--r--src/key.h2
-rw-r--r--src/main.cpp26
-rw-r--r--src/miner.cpp2
-rw-r--r--src/net.h19
-rw-r--r--src/pow.cpp3
-rw-r--r--src/primitives/transaction.h9
-rw-r--r--src/qt/addresstablemodel.cpp2
-rw-r--r--src/qt/askpassphrasedialog.cpp2
-rw-r--r--src/qt/bitcoin.cpp2
-rw-r--r--src/qt/bitcoingui.cpp2
-rw-r--r--src/qt/coincontroldialog.cpp25
-rw-r--r--src/qt/coincontroldialog.h1
-rw-r--r--src/qt/forms/sendcoinsentry.ui16
-rw-r--r--src/qt/macdockiconhandler.h9
-rw-r--r--src/qt/macdockiconhandler.mm61
-rw-r--r--src/qt/optionsdialog.cpp2
-rw-r--r--src/qt/optionsmodel.cpp4
-rw-r--r--src/qt/paymentserver.cpp2
-rw-r--r--src/qt/sendcoinsdialog.cpp70
-rw-r--r--src/qt/sendcoinsentry.cpp6
-rw-r--r--src/qt/sendcoinsentry.h1
-rw-r--r--src/qt/signverifymessagedialog.cpp2
-rw-r--r--src/qt/splashscreen.cpp2
-rw-r--r--src/qt/transactiondesc.cpp4
-rw-r--r--src/qt/transactionrecord.cpp2
-rw-r--r--src/qt/transactiontablemodel.cpp2
-rw-r--r--src/qt/walletmodel.cpp28
-rw-r--r--src/qt/walletmodel.h8
-rw-r--r--src/qt/walletmodeltransaction.cpp34
-rw-r--r--src/qt/walletmodeltransaction.h4
-rw-r--r--src/rpcclient.cpp2
-rw-r--r--src/rpcmining.cpp4
-rw-r--r--src/rpcmisc.cpp4
-rw-r--r--src/rpcrawtransaction.cpp2
-rw-r--r--src/rpcserver.cpp2
-rw-r--r--src/streams.h2
-rw-r--r--src/support/allocators/secure.h62
-rw-r--r--src/support/allocators/zeroafterfree.h48
-rw-r--r--src/support/pagelocker.cpp (renamed from src/allocators.cpp)6
-rw-r--r--src/support/pagelocker.h (renamed from src/allocators.h)96
-rw-r--r--src/test/Checkpoints_tests.cpp3
-rw-r--r--src/test/accounting_tests.cpp4
-rw-r--r--src/test/allocator_tests.cpp5
-rw-r--r--src/test/arith_uint256_tests.cpp3
-rw-r--r--src/test/base32_tests.cpp3
-rw-r--r--src/test/base58_tests.cpp7
-rw-r--r--src/test/base64_tests.cpp3
-rw-r--r--src/test/bip32_tests.cpp3
-rw-r--r--src/test/bloom_tests.cpp3
-rw-r--r--src/test/checkblock_tests.cpp3
-rw-r--r--src/test/coins_tests.cpp3
-rw-r--r--src/test/compress_tests.cpp3
-rw-r--r--src/test/crypto_tests.cpp3
-rw-r--r--src/test/getarg_tests.cpp3
-rw-r--r--src/test/hash_tests.cpp3
-rw-r--r--src/test/key_tests.cpp3
-rw-r--r--src/test/main_tests.cpp17
-rw-r--r--src/test/mruset_tests.cpp3
-rw-r--r--src/test/multisig_tests.cpp5
-rw-r--r--src/test/netbase_tests.cpp3
-rw-r--r--src/test/pmt_tests.cpp3
-rw-r--r--src/test/pow_tests.cpp3
-rw-r--r--src/test/rpc_wallet_tests.cpp2
-rw-r--r--src/test/sanity_tests.cpp4
-rw-r--r--src/test/script_P2SH_tests.cpp5
-rw-r--r--src/test/script_tests.cpp3
-rw-r--r--src/test/scriptnum_tests.cpp5
-rw-r--r--src/test/serialize_tests.cpp3
-rw-r--r--src/test/sighash_tests.cpp3
-rw-r--r--src/test/sigopcount_tests.cpp3
-rw-r--r--src/test/skiplist_tests.cpp3
-rw-r--r--src/test/test_bitcoin.cpp16
-rw-r--r--src/test/test_bitcoin.h14
-rw-r--r--src/test/timedata_tests.cpp3
-rw-r--r--src/test/transaction_tests.cpp3
-rw-r--r--src/test/uint256_tests.cpp3
-rw-r--r--src/test/univalue_tests.cpp3
-rw-r--r--src/test/util_tests.cpp3
-rw-r--r--src/uint256.cpp4
-rw-r--r--src/wallet/db.cpp (renamed from src/db.cpp)0
-rw-r--r--src/wallet/db.h (renamed from src/db.h)0
-rw-r--r--src/wallet/rpcdump.cpp (renamed from src/rpcdump.cpp)0
-rw-r--r--src/wallet/rpcwallet.cpp (renamed from src/rpcwallet.cpp)61
-rw-r--r--src/wallet/test/wallet_tests.cpp (renamed from src/test/wallet_tests.cpp)2
-rw-r--r--src/wallet/wallet.cpp (renamed from src/wallet.cpp)142
-rw-r--r--src/wallet/wallet.h (renamed from src/wallet.h)22
-rw-r--r--src/wallet/wallet_ismine.cpp (renamed from src/wallet_ismine.cpp)0
-rw-r--r--src/wallet/wallet_ismine.h (renamed from src/wallet_ismine.h)0
-rw-r--r--src/wallet/walletdb.cpp (renamed from src/walletdb.cpp)4
-rw-r--r--src/wallet/walletdb.h (renamed from src/walletdb.h)2
100 files changed, 694 insertions, 458 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index da65efa71..d1a8efaa6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -72,7 +72,6 @@ endif
BITCOIN_CORE_H = \
addrman.h \
alert.h \
- allocators.h \
amount.h \
arith_uint256.h \
base58.h \
@@ -90,7 +89,7 @@ BITCOIN_CORE_H = \
compressor.h \
core_io.h \
crypter.h \
- db.h \
+ wallet/db.h \
eccryptoverify.h \
ecwrapper.h \
hash.h \
@@ -123,7 +122,10 @@ BITCOIN_CORE_H = \
script/standard.h \
serialize.h \
streams.h \
+ support/allocators/secure.h \
+ support/allocators/zeroafterfree.h \
support/cleanse.h \
+ support/pagelocker.h \
sync.h \
threadsafety.h \
timedata.h \
@@ -138,9 +140,9 @@ BITCOIN_CORE_H = \
utilstrencodings.h \
utiltime.h \
version.h \
- walletdb.h \
- wallet.h \
- wallet_ismine.h \
+ wallet/walletdb.h \
+ wallet/wallet.h \
+ wallet/wallet_ismine.h \
compat/byteswap.h \
compat/endian.h \
compat/sanity.h
@@ -196,13 +198,13 @@ libbitcoin_server_a_SOURCES = \
# when wallet enabled
libbitcoin_wallet_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_wallet_a_SOURCES = \
- db.cpp \
+ wallet/db.cpp \
crypter.cpp \
- rpcdump.cpp \
- rpcwallet.cpp \
- wallet.cpp \
- wallet_ismine.cpp \
- walletdb.cpp \
+ wallet/rpcdump.cpp \
+ wallet/rpcwallet.cpp \
+ wallet/wallet.cpp \
+ wallet/wallet_ismine.cpp \
+ wallet/walletdb.cpp \
$(BITCOIN_CORE_H)
# crypto primitives library
@@ -233,7 +235,6 @@ univalue_libbitcoin_univalue_a_SOURCES = \
# common: shared between bitcoind, and bitcoin-qt and non-server tools
libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_common_a_SOURCES = \
- allocators.cpp \
arith_uint256.cpp \
amount.cpp \
base58.cpp \
@@ -264,6 +265,7 @@ libbitcoin_common_a_SOURCES = \
# backward-compatibility objects and their sanity checks are linked.
libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_util_a_SOURCES = \
+ support/pagelocker.cpp \
chainparamsbase.cpp \
clientversion.cpp \
compat/glibc_sanity.cpp \
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index e9d99323c..8dd0a2845 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -76,7 +76,7 @@ BITCOIN_TESTS =\
if ENABLE_WALLET
BITCOIN_TESTS += \
test/accounting_tests.cpp \
- test/wallet_tests.cpp \
+ wallet/test/wallet_tests.cpp \
test/rpc_wallet_tests.cpp
endif
diff --git a/src/addrman.cpp b/src/addrman.cpp
index 1e08ae772..4b7e4d51b 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -272,8 +272,9 @@ void CAddrMan::Good_(const CService& addr, int64_t nTime)
// update info
info.nLastSuccess = nTime;
info.nLastTry = nTime;
- info.nTime = nTime;
info.nAttempts = 0;
+ // nTime is not updated here, to avoid leaking information about
+ // currently-connected peers.
// if it is already in the tried set, don't do anything else
if (info.fInTried)
diff --git a/src/base58.h b/src/base58.h
index ed134e6e7..8de90046a 100644
--- a/src/base58.h
+++ b/src/base58.h
@@ -19,6 +19,7 @@
#include "pubkey.h"
#include "script/script.h"
#include "script/standard.h"
+#include "support/allocators/zeroafterfree.h"
#include <string>
#include <vector>
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 1fd3b0168..2bc897651 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -170,7 +170,6 @@ public:
fAllowMinDifficultyBlocks = false;
fRequireStandard = true;
fMineBlocksOnDemand = false;
- fSkipProofOfWorkCheck = false;
fTestnetToBeDeprecatedFieldRPC = false;
}
@@ -281,51 +280,8 @@ public:
};
static CRegTestParams regTestParams;
-/**
- * Unit test
- */
-class CUnitTestParams : public CMainParams, public CModifiableParams {
-public:
- CUnitTestParams() {
- strNetworkID = "unittest";
- nDefaultPort = 18445;
- vFixedSeeds.clear(); //! Unit test mode doesn't have any fixed seeds.
- vSeeds.clear(); //! Unit test mode doesn't have any DNS seeds.
-
- fRequireRPCPassword = false;
- fMiningRequiresPeers = false;
- fDefaultCheckMemPool = true;
- fAllowMinDifficultyBlocks = false;
- fMineBlocksOnDemand = true;
- }
-
- const Checkpoints::CCheckpointData& Checkpoints() const
- {
- // UnitTest share the same checkpoints as MAIN
- return data;
- }
-
- //! Published setters to allow changing values in unit test cases
- virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) { nSubsidyHalvingInterval=anSubsidyHalvingInterval; }
- virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority) { nEnforceBlockUpgradeMajority=anEnforceBlockUpgradeMajority; }
- virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority) { nRejectBlockOutdatedMajority=anRejectBlockOutdatedMajority; }
- virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority) { nToCheckBlockUpgradeMajority=anToCheckBlockUpgradeMajority; }
- virtual void setDefaultCheckMemPool(bool afDefaultCheckMemPool) { fDefaultCheckMemPool=afDefaultCheckMemPool; }
- virtual void setAllowMinDifficultyBlocks(bool afAllowMinDifficultyBlocks) { fAllowMinDifficultyBlocks=afAllowMinDifficultyBlocks; }
- virtual void setSkipProofOfWorkCheck(bool afSkipProofOfWorkCheck) { fSkipProofOfWorkCheck = afSkipProofOfWorkCheck; }
-};
-static CUnitTestParams unitTestParams;
-
-
static CChainParams *pCurrentParams = 0;
-CModifiableParams *ModifiableParams()
-{
- assert(pCurrentParams);
- assert(pCurrentParams==&unitTestParams);
- return (CModifiableParams*)&unitTestParams;
-}
-
const CChainParams &Params() {
assert(pCurrentParams);
return *pCurrentParams;
@@ -339,8 +295,6 @@ CChainParams &Params(CBaseChainParams::Network network) {
return testNetParams;
case CBaseChainParams::REGTEST:
return regTestParams;
- case CBaseChainParams::UNITTEST:
- return unitTestParams;
default:
assert(false && "Unimplemented network");
return mainParams;
diff --git a/src/chainparams.h b/src/chainparams.h
index 78b575d8f..134dcd655 100644
--- a/src/chainparams.h
+++ b/src/chainparams.h
@@ -60,8 +60,6 @@ public:
bool DefaultCheckMemPool() const { return fDefaultCheckMemPool; }
/** Allow mining of a min-difficulty block */
bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; }
- /** Skip proof-of-work check: allow mining of any difficulty block */
- bool SkipProofOfWorkCheck() const { return fSkipProofOfWorkCheck; }
/** Make standard checks */
bool RequireStandard() const { return fRequireStandard; }
int64_t TargetTimespan() const { return nTargetTimespan; }
@@ -104,29 +102,9 @@ protected:
bool fAllowMinDifficultyBlocks;
bool fRequireStandard;
bool fMineBlocksOnDemand;
- bool fSkipProofOfWorkCheck;
bool fTestnetToBeDeprecatedFieldRPC;
};
-/**
- * Modifiable parameters interface is used by test cases to adapt the parameters in order
- * to test specific features more easily. Test cases should always restore the previous
- * values after finalization.
- */
-
-class CModifiableParams {
-public:
- //! Published setters to allow changing values in unit test cases
- virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) =0;
- virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority)=0;
- virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority)=0;
- virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority)=0;
- virtual void setDefaultCheckMemPool(bool aDefaultCheckMemPool)=0;
- virtual void setAllowMinDifficultyBlocks(bool aAllowMinDifficultyBlocks)=0;
- virtual void setSkipProofOfWorkCheck(bool aSkipProofOfWorkCheck)=0;
-};
-
-
/**
* Return the currently selected parameters. This won't change after app startup
* outside of the unit tests.
@@ -136,9 +114,6 @@ const CChainParams &Params();
/** Return parameters for the given network. */
CChainParams &Params(CBaseChainParams::Network network);
-/** Get modifiable network parameters (UNITTEST only) */
-CModifiableParams *ModifiableParams();
-
/** Sets the params returned by Params() to those for the given network. */
void SelectParams(CBaseChainParams::Network network);
diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp
index c42fd106b..7d82d689e 100644
--- a/src/chainparamsbase.cpp
+++ b/src/chainparamsbase.cpp
@@ -82,9 +82,6 @@ void SelectBaseParams(CBaseChainParams::Network network)
case CBaseChainParams::REGTEST:
pCurrentBaseParams = &regTestParams;
break;
- case CBaseChainParams::UNITTEST:
- pCurrentBaseParams = &unitTestParams;
- break;
default:
assert(false && "Unimplemented network");
return;
diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h
index cebe7aa01..421a3a06f 100644
--- a/src/chainparamsbase.h
+++ b/src/chainparamsbase.h
@@ -19,7 +19,6 @@ public:
MAIN,
TESTNET,
REGTEST,
- UNITTEST,
MAX_NETWORK_TYPES
};
diff --git a/src/crypter.h b/src/crypter.h
index 8a91498e2..32746b00d 100644
--- a/src/crypter.h
+++ b/src/crypter.h
@@ -5,9 +5,9 @@
#ifndef BITCOIN_CRYPTER_H
#define BITCOIN_CRYPTER_H
-#include "allocators.h"
#include "keystore.h"
#include "serialize.h"
+#include "support/allocators/secure.h"
class uint256;
diff --git a/src/init.cpp b/src/init.cpp
index 1e3cc1d89..95ec45015 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -24,9 +24,8 @@
#include "util.h"
#include "utilmoneystr.h"
#ifdef ENABLE_WALLET
-#include "db.h"
-#include "wallet.h"
-#include "walletdb.h"
+#include "wallet/wallet.h"
+#include "wallet/walletdb.h"
#endif
#include <stdint.h>
@@ -151,7 +150,7 @@ void Shutdown()
StopRPCThreads();
#ifdef ENABLE_WALLET
if (pwalletMain)
- bitdb.Flush(false);
+ pwalletMain->Flush(false);
GenerateBitcoins(false, NULL, 0);
#endif
StopNode();
@@ -184,7 +183,7 @@ void Shutdown()
}
#ifdef ENABLE_WALLET
if (pwalletMain)
- bitdb.Flush(true);
+ pwalletMain->Flush(true);
#endif
#ifndef WIN32
boost::filesystem::remove(GetPidFile());
@@ -852,47 +851,17 @@ bool AppInit2(boost::thread_group& threadGroup)
LogPrintf("Using wallet %s\n", strWalletFile);
uiInterface.InitMessage(_("Verifying wallet..."));
- if (!bitdb.Open(GetDataDir()))
- {
- // try moving the database env out of the way
- boost::filesystem::path pathDatabase = GetDataDir() / "database";
- boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime());
- try {
- boost::filesystem::rename(pathDatabase, pathDatabaseBak);
- LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string());
- } catch (const boost::filesystem::filesystem_error&) {
- // failure is ok (well, not really, but it's not worse than what we started with)
- }
-
- // try again
- if (!bitdb.Open(GetDataDir())) {
- // if it still fails, it probably means we can't even create the database env
- string msg = strprintf(_("Error initializing wallet database environment %s!"), strDataDir);
- return InitError(msg);
- }
- }
-
- if (GetBoolArg("-salvagewallet", false))
- {
- // Recover readable keypairs:
- if (!CWalletDB::Recover(bitdb, strWalletFile, true))
- return false;
- }
-
- if (boost::filesystem::exists(GetDataDir() / strWalletFile))
- {
- CDBEnv::VerifyResult r = bitdb.Verify(strWalletFile, CWalletDB::Recover);
- if (r == CDBEnv::RECOVER_OK)
- {
- string msg = strprintf(_("Warning: wallet.dat corrupt, data salvaged!"
- " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if"
- " your balance or transactions are incorrect you should"
- " restore from a backup."), strDataDir);
- InitWarning(msg);
- }
- if (r == CDBEnv::RECOVER_FAIL)
- return InitError(_("wallet.dat corrupt, salvage failed"));
- }
+ std::string warningString;
+ std::string errorString;
+
+ if (!CWallet::Verify(strWalletFile, warningString, errorString))
+ return false;
+
+ if (!warningString.empty())
+ InitWarning(warningString);
+ if (!errorString.empty())
+ return InitError(warningString);
+
} // (!fDisableWallet)
#endif // ENABLE_WALLET
// ********************************************************* Step 6: network initialization
diff --git a/src/key.h b/src/key.h
index 85cc1e55d..1f1d14288 100644
--- a/src/key.h
+++ b/src/key.h
@@ -6,8 +6,8 @@
#ifndef BITCOIN_KEY_H
#define BITCOIN_KEY_H
-#include "allocators.h"
#include "serialize.h"
+#include "support/allocators/secure.h"
#include "uint256.h"
#include <stdexcept>
diff --git a/src/main.cpp b/src/main.cpp
index e16887fa4..94cf21349 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -238,6 +238,10 @@ struct CBlockReject {
* and we're no longer holding the node's locks.
*/
struct CNodeState {
+ //! The peer's address
+ CService address;
+ //! Whether we have a fully established connection.
+ bool fCurrentlyConnected;
//! Accumulated misbehaviour score for this peer.
int nMisbehavior;
//! Whether this peer should be disconnected and banned (unless whitelisted).
@@ -262,6 +266,7 @@ struct CNodeState {
bool fPreferredDownload;
CNodeState() {
+ fCurrentlyConnected = false;
nMisbehavior = 0;
fShouldBan = false;
pindexBestKnownBlock = NULL;
@@ -305,6 +310,7 @@ void InitializeNode(NodeId nodeid, const CNode *pnode) {
LOCK(cs_main);
CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
state.name = pnode->addrName;
+ state.address = pnode->addr;
}
void FinalizeNode(NodeId nodeid) {
@@ -314,6 +320,10 @@ void FinalizeNode(NodeId nodeid) {
if (state->fSyncStarted)
nSyncStarted--;
+ if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
+ AddressCurrentlyConnected(state->address);
+ }
+
BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
mapBlocksInFlight.erase(entry.hash);
EraseOrphansFor(nodeid);
@@ -2311,7 +2321,7 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
BlockMap::iterator it = mapBlockIndex.begin();
while (it != mapBlockIndex.end()) {
if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
- setBlockIndexCandidates.insert(pindex);
+ setBlockIndexCandidates.insert(it->second);
}
it++;
}
@@ -2596,8 +2606,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
int nHeight = pindexPrev->nHeight+1;
// Check proof of work
- if ((!Params().SkipProofOfWorkCheck()) &&
- (block.nBits != GetNextWorkRequired(pindexPrev, &block)))
+ if ((block.nBits != GetNextWorkRequired(pindexPrev, &block)))
return state.DoS(100, error("%s: incorrect proof of work", __func__),
REJECT_INVALID, "bad-diffbits");
@@ -3628,6 +3637,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
else if (strCommand == "verack")
{
pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
+
+ // Mark this node as currently connected, so we update its timestamp later.
+ if (pfrom->fNetworkNode) {
+ LOCK(cs_main);
+ State(pfrom->GetId())->fCurrentlyConnected = true;
+ }
}
@@ -4272,11 +4287,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
- // Update the last seen time for this node's address
- if (pfrom->fNetworkNode)
- if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping")
- AddressCurrentlyConnected(pfrom->addr);
-
return true;
}
diff --git a/src/miner.cpp b/src/miner.cpp
index e359654d7..01212b19c 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -15,7 +15,7 @@
#include "util.h"
#include "utilmoneystr.h"
#ifdef ENABLE_WALLET
-#include "wallet.h"
+#include "wallet/wallet.h"
#endif
#include <boost/thread.hpp>
diff --git a/src/net.h b/src/net.h
index 7dd02b84e..9fc6ce68d 100644
--- a/src/net.h
+++ b/src/net.h
@@ -78,12 +78,27 @@ void SocketSendData(CNode *pnode);
typedef int NodeId;
+struct CombinerAll
+{
+ typedef bool result_type;
+
+ template<typename I>
+ bool operator()(I first, I last) const
+ {
+ while (first != last) {
+ if (!(*first)) return false;
+ ++first;
+ }
+ return true;
+ }
+};
+
// Signals for message handling
struct CNodeSignals
{
boost::signals2::signal<int ()> GetHeight;
- boost::signals2::signal<bool (CNode*)> ProcessMessages;
- boost::signals2::signal<bool (CNode*, bool)> SendMessages;
+ boost::signals2::signal<bool (CNode*), CombinerAll> ProcessMessages;
+ boost::signals2::signal<bool (CNode*, bool), CombinerAll> SendMessages;
boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
boost::signals2::signal<void (NodeId)> FinalizeNode;
};
diff --git a/src/pow.cpp b/src/pow.cpp
index b75b293c9..eb899ffc9 100644
--- a/src/pow.cpp
+++ b/src/pow.cpp
@@ -87,9 +87,6 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits)
bool fOverflow;
arith_uint256 bnTarget;
- if (Params().SkipProofOfWorkCheck())
- return true;
-
bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
// Check range
diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h
index 0ba9affed..6cfd93a9a 100644
--- a/src/primitives/transaction.h
+++ b/src/primitives/transaction.h
@@ -135,7 +135,7 @@ public:
uint256 GetHash() const;
- bool IsDust(CFeeRate minRelayTxFee) const
+ CAmount GetDustThreshold(const CFeeRate &minRelayTxFee) const
{
// "Dust" is defined in terms of CTransaction::minRelayTxFee,
// which has units satoshis-per-kilobyte.
@@ -146,7 +146,12 @@ public:
// so dust is a txout less than 546 satoshis
// with default minRelayTxFee.
size_t nSize = GetSerializeSize(SER_DISK,0)+148u;
- return (nValue < 3*minRelayTxFee.GetFee(nSize));
+ return 3*minRelayTxFee.GetFee(nSize);
+ }
+
+ bool IsDust(const CFeeRate &minRelayTxFee) const
+ {
+ return (nValue < GetDustThreshold(minRelayTxFee));
}
friend bool operator==(const CTxOut& a, const CTxOut& b)
diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp
index 162ecdba4..9573fe43d 100644
--- a/src/qt/addresstablemodel.cpp
+++ b/src/qt/addresstablemodel.cpp
@@ -8,7 +8,7 @@
#include "walletmodel.h"
#include "base58.h"
-#include "wallet.h"
+#include "wallet/wallet.h"
#include <QFont>
#include <QDebug>
diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp
index 9b7b59c0d..229139e65 100644
--- a/src/qt/askpassphrasedialog.cpp
+++ b/src/qt/askpassphrasedialog.cpp
@@ -8,7 +8,7 @@
#include "guiconstants.h"
#include "walletmodel.h"
-#include "allocators.h"
+#include "support/allocators/secure.h"
#include <QKeyEvent>
#include <QMessageBox>
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 73c684e48..3ae780abf 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -30,7 +30,7 @@
#include "util.h"
#ifdef ENABLE_WALLET
-#include "wallet.h"
+#include "wallet/wallet.h"
#endif
#include <stdint.h>
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 1ec968ff2..58c005ae7 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -237,7 +237,7 @@ BitcoinGUI::~BitcoinGUI()
trayIcon->hide();
#ifdef Q_OS_MAC
delete appMenuBar;
- MacDockIconHandler::instance()->setMainWindow(NULL);
+ MacDockIconHandler::cleanup();
#endif
delete rpcConsole;
diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
index 3f4f082b8..e4e9015c8 100644
--- a/src/qt/coincontroldialog.cpp
+++ b/src/qt/coincontroldialog.cpp
@@ -15,7 +15,7 @@
#include "coincontrol.h"
#include "main.h"
-#include "wallet.h"
+#include "wallet/wallet.h"
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
@@ -33,6 +33,7 @@
using namespace std;
QList<CAmount> CoinControlDialog::payAmounts;
CCoinControl* CoinControlDialog::coinControl = new CCoinControl();
+bool CoinControlDialog::fSubtractFeeFromAmount = false;
CoinControlDialog::CoinControlDialog(QWidget *parent) :
QDialog(parent),
@@ -541,6 +542,11 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
dPriority = dPriorityInputs / (nBytes - nBytesInputs + (nQuantityUncompressed * 29)); // 29 = 180 - 151 (uncompressed public keys are over the limit. max 151 bytes of the input are ignored for priority)
sPriorityLabel = CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority);
+ // in the subtract fee from amount case, we can tell if zero change already and subtract the bytes, so that fee calculation afterwards is accurate
+ if (CoinControlDialog::fSubtractFeeFromAmount)
+ if (nAmount - nPayAmount == 0)
+ nBytes -= 34;
+
// Fee
nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
@@ -556,7 +562,9 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
if (nPayAmount > 0)
{
- nChange = nAmount - nPayFee - nPayAmount;
+ nChange = nAmount - nPayAmount;
+ if (!CoinControlDialog::fSubtractFeeFromAmount)
+ nChange -= nPayFee;
// Never create dust outputs; if we would, just add the dust to the fee.
if (nChange > 0 && nChange < CENT)
@@ -564,12 +572,17 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
CTxOut txout(nChange, (CScript)vector<unsigned char>(24, 0));
if (txout.IsDust(::minRelayTxFee))
{
- nPayFee += nChange;
- nChange = 0;
+ if (CoinControlDialog::fSubtractFeeFromAmount) // dust-change will be raised until no dust
+ nChange = txout.GetDustThreshold(::minRelayTxFee);
+ else
+ {
+ nPayFee += nChange;
+ nChange = 0;
+ }
}
}
- if (nChange == 0)
+ if (nChange == 0 && !CoinControlDialog::fSubtractFeeFromAmount)
nBytes -= 34;
}
@@ -612,7 +625,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
{
l3->setText(ASYMP_UTF8 + l3->text());
l4->setText(ASYMP_UTF8 + l4->text());
- if (nChange > 0)
+ if (nChange > 0 && !CoinControlDialog::fSubtractFeeFromAmount)
l8->setText(ASYMP_UTF8 + l8->text());
}
diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h
index 5a91876f1..5ec382838 100644
--- a/src/qt/coincontroldialog.h
+++ b/src/qt/coincontroldialog.h
@@ -43,6 +43,7 @@ public:
static QList<CAmount> payAmounts;
static CCoinControl *coinControl;
+ static bool fSubtractFeeFromAmount;
private:
Ui::CoinControlDialog *ui;
diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui
index 9f8c0a484..b36292843 100644
--- a/src/qt/forms/sendcoinsentry.ui
+++ b/src/qt/forms/sendcoinsentry.ui
@@ -157,7 +157,21 @@
</widget>
</item>
<item row="2" column="1">
- <widget class="BitcoinAmountField" name="payAmount"/>
+ <layout class="QHBoxLayout" name="horizontalLayoutAmount" stretch="0,1">
+ <item>
+ <widget class="BitcoinAmountField" name="payAmount"/>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkboxSubtractFeeFromAmount">
+ <property name="toolTip">
+ <string>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</string>
+ </property>
+ <property name="text">
+ <string>S&amp;ubtract fee from amount</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="messageLabel">
diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h
index 1217bd8e8..15a6583ca 100644
--- a/src/qt/macdockiconhandler.h
+++ b/src/qt/macdockiconhandler.h
@@ -14,12 +14,6 @@ class QMenu;
class QWidget;
QT_END_NAMESPACE
-#ifdef __OBJC__
-@class DockIconClickEventHandler;
-#else
-class DockIconClickEventHandler;
-#endif
-
/** Macintosh-specific dock icon handler.
*/
class MacDockIconHandler : public QObject
@@ -33,7 +27,7 @@ public:
void setIcon(const QIcon &icon);
void setMainWindow(QMainWindow *window);
static MacDockIconHandler *instance();
-
+ static void cleanup();
void handleDockIconClickEvent();
signals:
@@ -42,7 +36,6 @@ signals:
private:
MacDockIconHandler();
- DockIconClickEventHandler *m_dockIconClickEventHandler;
QWidget *m_dummyWidget;
QMenu *m_dockMenu;
QMainWindow *mainWindow;
diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm
index e7b58b9cc..58a0365d3 100644
--- a/src/qt/macdockiconhandler.mm
+++ b/src/qt/macdockiconhandler.mm
@@ -11,52 +11,46 @@
#undef slots
#include <Cocoa/Cocoa.h>
+#include <objc/objc.h>
+#include <objc/message.h>
#if QT_VERSION < 0x050000
extern void qt_mac_set_dock_menu(QMenu *);
#endif
-@interface DockIconClickEventHandler : NSObject
-{
- MacDockIconHandler* dockIconHandler;
-}
-
-@end
+static MacDockIconHandler *s_instance = NULL;
-@implementation DockIconClickEventHandler
-
-- (id)initWithDockIconHandler:(MacDockIconHandler *)aDockIconHandler
-{
- self = [super init];
- if (self) {
- dockIconHandler = aDockIconHandler;
-
- [[NSAppleEventManager sharedAppleEventManager]
- setEventHandler:self
- andSelector:@selector(handleDockClickEvent:withReplyEvent:)
- forEventClass:kCoreEventClass
- andEventID:kAEReopenApplication];
- }
- return self;
+bool dockClickHandler(id self,SEL _cmd,...) {
+ Q_UNUSED(self)
+ Q_UNUSED(_cmd)
+
+ s_instance->handleDockIconClickEvent();
+
+ // Return NO (false) to suppress the default OS X actions
+ return false;
}
-- (void)handleDockClickEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
-{
- Q_UNUSED(event)
- Q_UNUSED(replyEvent)
-
- if (dockIconHandler) {
- dockIconHandler->handleDockIconClickEvent();
+void setupDockClickHandler() {
+ Class cls = objc_getClass("NSApplication");
+ id appInst = objc_msgSend((id)cls, sel_registerName("sharedApplication"));
+
+ if (appInst != NULL) {
+ id delegate = objc_msgSend(appInst, sel_registerName("delegate"));
+ Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class"));
+ SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
+ if (class_getInstanceMethod(delClass, shouldHandle))
+ class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:");
+ else
+ class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler,"B@:");
}
}
-@end
MacDockIconHandler::MacDockIconHandler() : QObject()
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- this->m_dockIconClickEventHandler = [[DockIconClickEventHandler alloc] initWithDockIconHandler:this];
+ setupDockClickHandler();
this->m_dummyWidget = new QWidget();
this->m_dockMenu = new QMenu(this->m_dummyWidget);
this->setMainWindow(NULL);
@@ -74,7 +68,6 @@ void MacDockIconHandler::setMainWindow(QMainWindow *window) {
MacDockIconHandler::~MacDockIconHandler()
{
- [this->m_dockIconClickEventHandler release];
delete this->m_dummyWidget;
this->setMainWindow(NULL);
}
@@ -119,12 +112,16 @@ void MacDockIconHandler::setIcon(const QIcon &icon)
MacDockIconHandler *MacDockIconHandler::instance()
{
- static MacDockIconHandler *s_instance = NULL;
if (!s_instance)
s_instance = new MacDockIconHandler();
return s_instance;
}
+void MacDockIconHandler::cleanup()
+{
+ delete s_instance;
+}
+
void MacDockIconHandler::handleDockIconClickEvent()
{
if (this->mainWindow)
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index a342b4bfe..a9e4b339e 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -18,7 +18,7 @@
#include "txdb.h" // for -dbcache defaults
#ifdef ENABLE_WALLET
-#include "wallet.h" // for CWallet::minTxFee
+#include "wallet/wallet.h" // for CWallet::minTxFee
#endif
#include <boost/thread.hpp>
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
index 7d2dbd96d..a169ed6b5 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -18,8 +18,8 @@
#include "txdb.h" // for -dbcache defaults
#ifdef ENABLE_WALLET
-#include "wallet.h"
-#include "walletdb.h"
+#include "wallet/wallet.h"
+#include "wallet/walletdb.h"
#endif
#include <QNetworkProxy>
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index 96ceeb18a..40d6e16f5 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -12,7 +12,7 @@
#include "chainparams.h"
#include "ui_interface.h"
#include "util.h"
-#include "wallet.h"
+#include "wallet/wallet.h"
#include <cstdlib>
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 4f3230a8c..28c8fb95f 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -18,7 +18,7 @@
#include "base58.h"
#include "coincontrol.h"
#include "ui_interface.h"
-#include "wallet.h"
+#include "wallet/wallet.h"
#include <QMessageBox>
#include <QScrollBar>
@@ -220,9 +220,37 @@ void SendCoinsDialog::on_sendButton_clicked()
return;
}
+ fNewRecipientAllowed = false;
+ WalletModel::UnlockContext ctx(model->requestUnlock());
+ if(!ctx.isValid())
+ {
+ // Unlock wallet was cancelled
+ fNewRecipientAllowed = true;
+ return;
+ }
+
+ // prepare transaction for getting txFee earlier
+ WalletModelTransaction currentTransaction(recipients);
+ WalletModel::SendCoinsReturn prepareStatus;
+ if (model->getOptionsModel()->getCoinControlFeatures()) // coin control enabled
+ prepareStatus = model->prepareTransaction(currentTransaction, CoinControlDialog::coinControl);
+ else
+ prepareStatus = model->prepareTransaction(currentTransaction);
+
+ // process prepareStatus and on error generate message shown to user
+ processSendCoinsReturn(prepareStatus,
+ BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), currentTransaction.getTransactionFee()));
+
+ if(prepareStatus.status != WalletModel::OK) {
+ fNewRecipientAllowed = true;
+ return;
+ }
+
+ CAmount txFee = currentTransaction.getTransactionFee();
+
// Format confirmation message
QStringList formatted;
- foreach(const SendCoinsRecipient &rcp, recipients)
+ foreach(const SendCoinsRecipient &rcp, currentTransaction.getRecipients())
{
// generate bold amount string
QString amount = "<b>" + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount);
@@ -257,35 +285,6 @@ void SendCoinsDialog::on_sendButton_clicked()
formatted.append(recipientElement);
}
- fNewRecipientAllowed = false;
-
-
- WalletModel::UnlockContext ctx(model->requestUnlock());
- if(!ctx.isValid())
- {
- // Unlock wallet was cancelled
- fNewRecipientAllowed = true;
- return;
- }
-
- // prepare transaction for getting txFee earlier
- WalletModelTransaction currentTransaction(recipients);
- WalletModel::SendCoinsReturn prepareStatus;
- if (model->getOptionsModel()->getCoinControlFeatures()) // coin control enabled
- prepareStatus = model->prepareTransaction(currentTransaction, CoinControlDialog::coinControl);
- else
- prepareStatus = model->prepareTransaction(currentTransaction);
-
- // process prepareStatus and on error generate message shown to user
- processSendCoinsReturn(prepareStatus,
- BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), currentTransaction.getTransactionFee()));
-
- if(prepareStatus.status != WalletModel::OK) {
- fNewRecipientAllowed = true;
- return;
- }
-
- CAmount txFee = currentTransaction.getTransactionFee();
QString questionString = tr("Are you sure you want to send?");
questionString.append("<br /><br />%1");
@@ -368,6 +367,7 @@ SendCoinsEntry *SendCoinsDialog::addEntry()
ui->entries->addWidget(entry);
connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*)));
connect(entry, SIGNAL(payAmountChanged()), this, SLOT(coinControlUpdateLabels()));
+ connect(entry, SIGNAL(subtractFeeFromAmountChanged()), this, SLOT(coinControlUpdateLabels()));
updateTabsAndLabels();
@@ -783,11 +783,17 @@ void SendCoinsDialog::coinControlUpdateLabels()
// set pay amounts
CoinControlDialog::payAmounts.clear();
+ CoinControlDialog::fSubtractFeeFromAmount = false;
for(int i = 0; i < ui->entries->count(); ++i)
{
SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
if(entry)
- CoinControlDialog::payAmounts.append(entry->getValue().amount);
+ {
+ SendCoinsRecipient rcp = entry->getValue();
+ CoinControlDialog::payAmounts.append(rcp.amount);
+ if (rcp.fSubtractFeeFromAmount)
+ CoinControlDialog::fSubtractFeeFromAmount = true;
+ }
}
if (CoinControlDialog::coinControl->HasSelected())
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index 6db6eee75..6ac650e74 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -44,6 +44,7 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) :
// Connect signals
connect(ui->payAmount, SIGNAL(valueChanged()), this, SIGNAL(payAmountChanged()));
+ connect(ui->checkboxSubtractFeeFromAmount, SIGNAL(toggled(bool)), this, SIGNAL(subtractFeeFromAmountChanged()));
connect(ui->deleteButton, SIGNAL(clicked()), this, SLOT(deleteClicked()));
connect(ui->deleteButton_is, SIGNAL(clicked()), this, SLOT(deleteClicked()));
connect(ui->deleteButton_s, SIGNAL(clicked()), this, SLOT(deleteClicked()));
@@ -94,6 +95,7 @@ void SendCoinsEntry::clear()
ui->payTo->clear();
ui->addAsLabel->clear();
ui->payAmount->clear();
+ ui->checkboxSubtractFeeFromAmount->setCheckState(Qt::Unchecked);
ui->messageTextLabel->clear();
ui->messageTextLabel->hide();
ui->messageLabel->hide();
@@ -165,6 +167,7 @@ SendCoinsRecipient SendCoinsEntry::getValue()
recipient.label = ui->addAsLabel->text();
recipient.amount = ui->payAmount->value();
recipient.message = ui->messageTextLabel->text();
+ recipient.fSubtractFeeFromAmount = (ui->checkboxSubtractFeeFromAmount->checkState() == Qt::Checked);
return recipient;
}
@@ -174,7 +177,8 @@ QWidget *SendCoinsEntry::setupTabChain(QWidget *prev)
QWidget::setTabOrder(prev, ui->payTo);
QWidget::setTabOrder(ui->payTo, ui->addAsLabel);
QWidget *w = ui->payAmount->setupTabChain(ui->addAsLabel);
- QWidget::setTabOrder(w, ui->addressBookButton);
+ QWidget::setTabOrder(w, ui->checkboxSubtractFeeFromAmount);
+ QWidget::setTabOrder(ui->checkboxSubtractFeeFromAmount, ui->addressBookButton);
QWidget::setTabOrder(ui->addressBookButton, ui->pasteButton);
QWidget::setTabOrder(ui->pasteButton, ui->deleteButton);
return ui->deleteButton;
diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h
index 4cb00cd36..c2d1185bd 100644
--- a/src/qt/sendcoinsentry.h
+++ b/src/qt/sendcoinsentry.h
@@ -51,6 +51,7 @@ public slots:
signals:
void removeEntry(SendCoinsEntry *entry);
void payAmountChanged();
+ void subtractFeeFromAmountChanged();
private slots:
void deleteClicked();
diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp
index 970f6a520..76da6904a 100644
--- a/src/qt/signverifymessagedialog.cpp
+++ b/src/qt/signverifymessagedialog.cpp
@@ -12,7 +12,7 @@
#include "base58.h"
#include "init.h"
-#include "wallet.h"
+#include "wallet/wallet.h"
#include <string>
#include <vector>
diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp
index e6a7fcaec..414fe02ff 100644
--- a/src/qt/splashscreen.cpp
+++ b/src/qt/splashscreen.cpp
@@ -12,7 +12,7 @@
#include "version.h"
#ifdef ENABLE_WALLET
-#include "wallet.h"
+#include "wallet/wallet.h"
#endif
#include <QApplication>
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp
index 68c275d49..9b235f913 100644
--- a/src/qt/transactiondesc.cpp
+++ b/src/qt/transactiondesc.cpp
@@ -10,13 +10,13 @@
#include "transactionrecord.h"
#include "base58.h"
-#include "db.h"
+#include "wallet/db.h"
#include "main.h"
#include "script/script.h"
#include "timedata.h"
#include "ui_interface.h"
#include "util.h"
-#include "wallet.h"
+#include "wallet/wallet.h"
#include <stdint.h>
#include <string>
diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp
index fea436806..19e3fc0dc 100644
--- a/src/qt/transactionrecord.cpp
+++ b/src/qt/transactionrecord.cpp
@@ -6,7 +6,7 @@
#include "base58.h"
#include "timedata.h"
-#include "wallet.h"
+#include "wallet/wallet.h"
#include <stdint.h>
diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
index df1afbfaa..dff2676b1 100644
--- a/src/qt/transactiontablemodel.cpp
+++ b/src/qt/transactiontablemodel.cpp
@@ -17,7 +17,7 @@
#include "sync.h"
#include "uint256.h"
#include "util.h"
-#include "wallet.h"
+#include "wallet/wallet.h"
#include <QColor>
#include <QDateTime>
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 79f5191fc..09ed8ce9f 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -6,18 +6,19 @@
#include "addresstablemodel.h"
#include "guiconstants.h"
+#include "guiutil.h"
#include "paymentserver.h"
#include "recentrequeststablemodel.h"
#include "transactiontablemodel.h"
#include "base58.h"
-#include "db.h"
+#include "wallet/db.h"
#include "keystore.h"
#include "main.h"
#include "sync.h"
#include "ui_interface.h"
-#include "wallet.h"
-#include "walletdb.h" // for BackupWallet
+#include "wallet/wallet.h"
+#include "wallet/walletdb.h" // for BackupWallet
#include <stdint.h>
@@ -192,8 +193,9 @@ bool WalletModel::validateAddress(const QString &address)
WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl)
{
CAmount total = 0;
+ bool fSubtractFeeFromAmount = false;
QList<SendCoinsRecipient> recipients = transaction.getRecipients();
- std::vector<std::pair<CScript, CAmount> > vecSend;
+ std::vector<CRecipient> vecSend;
if(recipients.empty())
{
@@ -206,6 +208,9 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
// Pre-check input data for validity
foreach(const SendCoinsRecipient &rcp, recipients)
{
+ if (rcp.fSubtractFeeFromAmount)
+ fSubtractFeeFromAmount = true;
+
if (rcp.paymentRequest.IsInitialized())
{ // PaymentRequest...
CAmount subtotal = 0;
@@ -217,7 +222,9 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
subtotal += out.amount();
const unsigned char* scriptStr = (const unsigned char*)out.script().data();
CScript scriptPubKey(scriptStr, scriptStr+out.script().size());
- vecSend.push_back(std::pair<CScript, CAmount>(scriptPubKey, out.amount()));
+ CAmount nAmount = out.amount();
+ CRecipient recipient = {scriptPubKey, nAmount, rcp.fSubtractFeeFromAmount};
+ vecSend.push_back(recipient);
}
if (subtotal <= 0)
{
@@ -239,7 +246,8 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
++nAddresses;
CScript scriptPubKey = GetScriptForDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
- vecSend.push_back(std::pair<CScript, CAmount>(scriptPubKey, rcp.amount));
+ CRecipient recipient = {scriptPubKey, rcp.amount, rcp.fSubtractFeeFromAmount};
+ vecSend.push_back(recipient);
total += rcp.amount;
}
@@ -260,17 +268,21 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
LOCK2(cs_main, wallet->cs_wallet);
transaction.newPossibleKeyChange(wallet);
+
CAmount nFeeRequired = 0;
+ int nChangePosRet = -1;
std::string strFailReason;
CWalletTx *newTx = transaction.getTransaction();
CReserveKey *keyChange = transaction.getPossibleKeyChange();
- bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, strFailReason, coinControl);
+ bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl);
transaction.setTransactionFee(nFeeRequired);
+ if (fSubtractFeeFromAmount && fCreated)
+ transaction.reassignAmounts(nChangePosRet);
if(!fCreated)
{
- if((total + nFeeRequired) > nBalance)
+ if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance)
{
return SendCoinsReturn(AmountWithFeeExceedsBalance);
}
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index 4a9a12bea..e26343888 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -8,7 +8,7 @@
#include "paymentrequestplus.h"
#include "walletmodeltransaction.h"
-#include "allocators.h" /* for SecureString */
+#include "support/allocators/secure.h"
#include <map>
#include <vector>
@@ -36,9 +36,9 @@ QT_END_NAMESPACE
class SendCoinsRecipient
{
public:
- explicit SendCoinsRecipient() : amount(0), nVersion(SendCoinsRecipient::CURRENT_VERSION) { }
+ explicit SendCoinsRecipient() : amount(0), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) { }
explicit SendCoinsRecipient(const QString &addr, const QString &label, const CAmount& amount, const QString &message):
- address(addr), label(label), amount(amount), message(message), nVersion(SendCoinsRecipient::CURRENT_VERSION) {}
+ address(addr), label(label), amount(amount), message(message), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) {}
// If from an unauthenticated payment request, this is used for storing
// the addresses, e.g. address-A<br />address-B<br />address-C.
@@ -56,6 +56,8 @@ public:
// Empty if no authentication or invalid signature/cert/etc.
QString authenticatedMerchant;
+ bool fSubtractFeeFromAmount; // memory only
+
static const int CURRENT_VERSION = 1;
int nVersion;
diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp
index 8f32e4614..206bb7c77 100644
--- a/src/qt/walletmodeltransaction.cpp
+++ b/src/qt/walletmodeltransaction.cpp
@@ -4,7 +4,7 @@
#include "walletmodeltransaction.h"
-#include "wallet.h"
+#include "wallet/wallet.h"
WalletModelTransaction::WalletModelTransaction(const QList<SendCoinsRecipient> &recipients) :
recipients(recipients),
@@ -46,6 +46,38 @@ void WalletModelTransaction::setTransactionFee(const CAmount& newFee)
fee = newFee;
}
+void WalletModelTransaction::reassignAmounts(int nChangePosRet)
+{
+ int i = 0;
+ for (QList<SendCoinsRecipient>::iterator it = recipients.begin(); it != recipients.end(); ++it)
+ {
+ SendCoinsRecipient& rcp = (*it);
+
+ if (rcp.paymentRequest.IsInitialized())
+ {
+ CAmount subtotal = 0;
+ const payments::PaymentDetails& details = rcp.paymentRequest.getDetails();
+ for (int j = 0; j < details.outputs_size(); j++)
+ {
+ const payments::Output& out = details.outputs(j);
+ if (out.amount() <= 0) continue;
+ if (i == nChangePosRet)
+ i++;
+ subtotal += walletTransaction->vout[i].nValue;
+ i++;
+ }
+ rcp.amount = subtotal;
+ }
+ else // normal recipient (no payment request)
+ {
+ if (i == nChangePosRet)
+ i++;
+ rcp.amount = walletTransaction->vout[i].nValue;
+ i++;
+ }
+ }
+}
+
CAmount WalletModelTransaction::getTotalTransactionAmount()
{
CAmount totalTransactionAmount = 0;
diff --git a/src/qt/walletmodeltransaction.h b/src/qt/walletmodeltransaction.h
index b6bb6d67f..7765fea4a 100644
--- a/src/qt/walletmodeltransaction.h
+++ b/src/qt/walletmodeltransaction.h
@@ -35,8 +35,10 @@ public:
void newPossibleKeyChange(CWallet *wallet);
CReserveKey *getPossibleKeyChange();
+ void reassignAmounts(int nChangePosRet); // needed for the subtract-fee-from-amount feature
+
private:
- const QList<SendCoinsRecipient> recipients;
+ QList<SendCoinsRecipient> recipients;
CWalletTx *walletTransaction;
CReserveKey *keyChange;
CAmount fee;
diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp
index 4e45bc32a..a45ea9839 100644
--- a/src/rpcclient.cpp
+++ b/src/rpcclient.cpp
@@ -32,6 +32,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "getnetworkhashps", 0 },
{ "getnetworkhashps", 1 },
{ "sendtoaddress", 1 },
+ { "sendtoaddress", 4 },
{ "settxfee", 0 },
{ "getreceivedbyaddress", 1 },
{ "getreceivedbyaccount", 1 },
@@ -59,6 +60,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "listsinceblock", 2 },
{ "sendmany", 1 },
{ "sendmany", 2 },
+ { "sendmany", 4 },
{ "addmultisigaddress", 0 },
{ "addmultisigaddress", 1 },
{ "createmultisig", 0 },
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index 165a9df69..a07acea9a 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -14,8 +14,8 @@
#include "rpcserver.h"
#include "util.h"
#ifdef ENABLE_WALLET
-#include "db.h"
-#include "wallet.h"
+#include "wallet/db.h"
+#include "wallet/wallet.h"
#endif
#include <stdint.h>
diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp
index 2eda4d335..938d79513 100644
--- a/src/rpcmisc.cpp
+++ b/src/rpcmisc.cpp
@@ -13,8 +13,8 @@
#include "timedata.h"
#include "util.h"
#ifdef ENABLE_WALLET
-#include "wallet.h"
-#include "walletdb.h"
+#include "wallet/wallet.h"
+#include "wallet/walletdb.h"
#endif
#include <stdint.h>
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
index 4a079f5c8..a79b4e339 100644
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -16,7 +16,7 @@
#include "script/standard.h"
#include "uint256.h"
#ifdef ENABLE_WALLET
-#include "wallet.h"
+#include "wallet/wallet.h"
#endif
#include <stdint.h>
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index 20e9252d7..ba7172522 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -13,7 +13,7 @@
#include "util.h"
#include "utilstrencodings.h"
#ifdef ENABLE_WALLET
-#include "wallet.h"
+#include "wallet/wallet.h"
#endif
#include <boost/algorithm/string.hpp>
diff --git a/src/streams.h b/src/streams.h
index 9999c2341..fa1e18def 100644
--- a/src/streams.h
+++ b/src/streams.h
@@ -6,7 +6,7 @@
#ifndef BITCOIN_STREAMS_H
#define BITCOIN_STREAMS_H
-#include "allocators.h"
+#include "support/allocators/zeroafterfree.h"
#include "serialize.h"
#include <algorithm>
diff --git a/src/support/allocators/secure.h b/src/support/allocators/secure.h
new file mode 100644
index 000000000..7a74d87bb
--- /dev/null
+++ b/src/support/allocators/secure.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-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.
+
+#ifndef BITCOIN_ALLOCATORS_SECURE_H
+#define BITCOIN_ALLOCATORS_SECURE_H
+
+#include "support/pagelocker.h"
+
+#include <string>
+
+//
+// Allocator that locks its contents from being paged
+// out of memory and clears its contents before deletion.
+//
+template <typename T>
+struct secure_allocator : public std::allocator<T> {
+ // MSVC8 default copy constructor is broken
+ typedef std::allocator<T> base;
+ typedef typename base::size_type size_type;
+ typedef typename base::difference_type difference_type;
+ typedef typename base::pointer pointer;
+ typedef typename base::const_pointer const_pointer;
+ typedef typename base::reference reference;
+ typedef typename base::const_reference const_reference;
+ typedef typename base::value_type value_type;
+ secure_allocator() throw() {}
+ secure_allocator(const secure_allocator& a) throw() : base(a) {}
+ template <typename U>
+ secure_allocator(const secure_allocator<U>& a) throw() : base(a)
+ {
+ }
+ ~secure_allocator() throw() {}
+ template <typename _Other>
+ struct rebind {
+ typedef secure_allocator<_Other> other;
+ };
+
+ T* allocate(std::size_t n, const void* hint = 0)
+ {
+ T* p;
+ p = std::allocator<T>::allocate(n, hint);
+ if (p != NULL)
+ LockedPageManager::Instance().LockRange(p, sizeof(T) * n);
+ return p;
+ }
+
+ void deallocate(T* p, std::size_t n)
+ {
+ if (p != NULL) {
+ memory_cleanse(p, sizeof(T) * n);
+ LockedPageManager::Instance().UnlockRange(p, sizeof(T) * n);
+ }
+ std::allocator<T>::deallocate(p, n);
+ }
+};
+
+// This is exactly like std::string, but with a custom allocator.
+typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
+
+#endif // BITCOIN_ALLOCATORS_SECURE_H
diff --git a/src/support/allocators/zeroafterfree.h b/src/support/allocators/zeroafterfree.h
new file mode 100644
index 000000000..b01fcd088
--- /dev/null
+++ b/src/support/allocators/zeroafterfree.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-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.
+
+#ifndef BITCOIN_ALLOCATORS_ZEROAFTERFREE_H
+#define BITCOIN_ALLOCATORS_ZEROAFTERFREE_H
+
+#include "support/cleanse.h"
+
+#include <memory>
+#include <vector>
+
+template <typename T>
+struct zero_after_free_allocator : public std::allocator<T> {
+ // MSVC8 default copy constructor is broken
+ typedef std::allocator<T> base;
+ typedef typename base::size_type size_type;
+ typedef typename base::difference_type difference_type;
+ typedef typename base::pointer pointer;
+ typedef typename base::const_pointer const_pointer;
+ typedef typename base::reference reference;
+ typedef typename base::const_reference const_reference;
+ typedef typename base::value_type value_type;
+ zero_after_free_allocator() throw() {}
+ zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {}
+ template <typename U>
+ zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a)
+ {
+ }
+ ~zero_after_free_allocator() throw() {}
+ template <typename _Other>
+ struct rebind {
+ typedef zero_after_free_allocator<_Other> other;
+ };
+
+ void deallocate(T* p, std::size_t n)
+ {
+ if (p != NULL)
+ memory_cleanse(p, sizeof(T) * n);
+ std::allocator<T>::deallocate(p, n);
+ }
+};
+
+// Byte-vector that clears its contents before deletion.
+typedef std::vector<char, zero_after_free_allocator<char> > CSerializeData;
+
+#endif // BITCOIN_ALLOCATORS_ZEROAFTERFREE_H
diff --git a/src/allocators.cpp b/src/support/pagelocker.cpp
index d3958aa4d..440e0a519 100644
--- a/src/allocators.cpp
+++ b/src/support/pagelocker.cpp
@@ -2,7 +2,11 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "allocators.h"
+#include "support/pagelocker.h"
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
#ifdef WIN32
#ifdef _WIN32_WINNT
diff --git a/src/allocators.h b/src/support/pagelocker.h
index 8ffe015b9..964be1aec 100644
--- a/src/allocators.h
+++ b/src/support/pagelocker.h
@@ -3,15 +3,12 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#ifndef BITCOIN_ALLOCATORS_H
-#define BITCOIN_ALLOCATORS_H
+#ifndef BITCOIN_ALLOCATORS_PAGELOCKER_H
+#define BITCOIN_ALLOCATORS_PAGELOCKER_H
#include "support/cleanse.h"
#include <map>
-#include <string>
-#include <string.h>
-#include <vector>
#include <boost/thread/mutex.hpp>
#include <boost/thread/once.hpp>
@@ -178,91 +175,4 @@ void UnlockObject(const T& t)
LockedPageManager::Instance().UnlockRange((void*)(&t), sizeof(T));
}
-//
-// Allocator that locks its contents from being paged
-// out of memory and clears its contents before deletion.
-//
-template <typename T>
-struct secure_allocator : public std::allocator<T> {
- // MSVC8 default copy constructor is broken
- typedef std::allocator<T> base;
- typedef typename base::size_type size_type;
- typedef typename base::difference_type difference_type;
- typedef typename base::pointer pointer;
- typedef typename base::const_pointer const_pointer;
- typedef typename base::reference reference;
- typedef typename base::const_reference const_reference;
- typedef typename base::value_type value_type;
- secure_allocator() throw() {}
- secure_allocator(const secure_allocator& a) throw() : base(a) {}
- template <typename U>
- secure_allocator(const secure_allocator<U>& a) throw() : base(a)
- {
- }
- ~secure_allocator() throw() {}
- template <typename _Other>
- struct rebind {
- typedef secure_allocator<_Other> other;
- };
-
- T* allocate(std::size_t n, const void* hint = 0)
- {
- T* p;
- p = std::allocator<T>::allocate(n, hint);
- if (p != NULL)
- LockedPageManager::Instance().LockRange(p, sizeof(T) * n);
- return p;
- }
-
- void deallocate(T* p, std::size_t n)
- {
- if (p != NULL) {
- memory_cleanse(p, sizeof(T) * n);
- LockedPageManager::Instance().UnlockRange(p, sizeof(T) * n);
- }
- std::allocator<T>::deallocate(p, n);
- }
-};
-
-
-//
-// Allocator that clears its contents before deletion.
-//
-template <typename T>
-struct zero_after_free_allocator : public std::allocator<T> {
- // MSVC8 default copy constructor is broken
- typedef std::allocator<T> base;
- typedef typename base::size_type size_type;
- typedef typename base::difference_type difference_type;
- typedef typename base::pointer pointer;
- typedef typename base::const_pointer const_pointer;
- typedef typename base::reference reference;
- typedef typename base::const_reference const_reference;
- typedef typename base::value_type value_type;
- zero_after_free_allocator() throw() {}
- zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {}
- template <typename U>
- zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a)
- {
- }
- ~zero_after_free_allocator() throw() {}
- template <typename _Other>
- struct rebind {
- typedef zero_after_free_allocator<_Other> other;
- };
-
- void deallocate(T* p, std::size_t n)
- {
- if (p != NULL)
- memory_cleanse(p, sizeof(T) * n);
- std::allocator<T>::deallocate(p, n);
- }
-};
-
-// This is exactly like std::string, but with a custom allocator.
-typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
-
-// Byte-vector that clears its contents before deletion.
-typedef std::vector<char, zero_after_free_allocator<char> > CSerializeData;
-
-#endif // BITCOIN_ALLOCATORS_H
+#endif // BITCOIN_ALLOCATORS_PAGELOCKER_H
diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp
index a9b6cd44a..c3125d76d 100644
--- a/src/test/Checkpoints_tests.cpp
+++ b/src/test/Checkpoints_tests.cpp
@@ -9,12 +9,13 @@
#include "checkpoints.h"
#include "uint256.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
using namespace std;
-BOOST_AUTO_TEST_SUITE(Checkpoints_tests)
+BOOST_FIXTURE_TEST_SUITE(Checkpoints_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(sanity)
{
diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp
index 36499f01a..0c2ade48d 100644
--- a/src/test/accounting_tests.cpp
+++ b/src/test/accounting_tests.cpp
@@ -2,8 +2,8 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "wallet.h"
-#include "walletdb.h"
+#include "wallet/wallet.h"
+#include "wallet/walletdb.h"
#include "test/test_bitcoin.h"
diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp
index 991b4ac09..2108efece 100644
--- a/src/test/allocator_tests.cpp
+++ b/src/test/allocator_tests.cpp
@@ -4,11 +4,12 @@
#include "util.h"
-#include "allocators.h"
+#include "support/allocators/secure.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(allocator_tests)
+BOOST_FIXTURE_TEST_SUITE(allocator_tests, BasicTestingSetup)
// Dummy memory page locker for platform independent tests
static const void *last_lock_addr, *last_unlock_addr;
diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp
index 565b02ae6..17d6bed6d 100644
--- a/src/test/arith_uint256_tests.cpp
+++ b/src/test/arith_uint256_tests.cpp
@@ -12,8 +12,9 @@
#include "arith_uint256.h"
#include <string>
#include "version.h"
+#include "test/test_bitcoin.h"
-BOOST_AUTO_TEST_SUITE(arith_uint256_tests)
+BOOST_FIXTURE_TEST_SUITE(arith_uint256_tests, BasicTestingSetup)
/// Convert vector to arith_uint256, via uint256 blob
inline arith_uint256 arith_uint256V(const std::vector<unsigned char>& vch)
diff --git a/src/test/base32_tests.cpp b/src/test/base32_tests.cpp
index 5d20a90ad..8ec886142 100644
--- a/src/test/base32_tests.cpp
+++ b/src/test/base32_tests.cpp
@@ -3,10 +3,11 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(base32_tests)
+BOOST_FIXTURE_TEST_SUITE(base32_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(base32_testvectors)
{
diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp
index e7d028188..f07dd7a7d 100644
--- a/src/test/base58_tests.cpp
+++ b/src/test/base58_tests.cpp
@@ -13,6 +13,7 @@
#include "uint256.h"
#include "util.h"
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
@@ -23,7 +24,7 @@
using namespace json_spirit;
extern Array read_json(const std::string& jsondata);
-BOOST_AUTO_TEST_SUITE(base58_tests)
+BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup)
// Goal: test low-level base58 encoding functionality
BOOST_AUTO_TEST_CASE(base58_EncodeBase58)
@@ -127,6 +128,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
std::vector<unsigned char> result;
CBitcoinSecret secret;
CBitcoinAddress addr;
+ SelectParams(CBaseChainParams::MAIN);
BOOST_FOREACH(Value& tv, tests)
{
@@ -176,7 +178,6 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest);
}
}
- SelectParams(CBaseChainParams::UNITTEST);
}
// Goal: check that generated keys match test vectors
@@ -244,7 +245,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
CTxDestination nodest = CNoDestination();
BOOST_CHECK(!dummyAddr.Set(nodest));
- SelectParams(CBaseChainParams::UNITTEST);
+ SelectParams(CBaseChainParams::MAIN);
}
// Goal: check that base58 parsing code is robust against a variety of corrupted data
diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp
index 9e6cb342c..54c081b0e 100644
--- a/src/test/base64_tests.cpp
+++ b/src/test/base64_tests.cpp
@@ -3,10 +3,11 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(base64_tests)
+BOOST_FIXTURE_TEST_SUITE(base64_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(base64_testvectors)
{
diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp
index 3d28e06ff..d738851c1 100644
--- a/src/test/bip32_tests.cpp
+++ b/src/test/bip32_tests.cpp
@@ -8,6 +8,7 @@
#include "key.h"
#include "uint256.h"
#include "util.h"
+#include "test/test_bitcoin.h"
#include <string>
#include <vector>
@@ -107,7 +108,7 @@ void RunTest(const TestVector &test) {
}
}
-BOOST_AUTO_TEST_SUITE(bip32_tests)
+BOOST_FIXTURE_TEST_SUITE(bip32_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(bip32_test1) {
RunTest(test1);
diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp
index 64d9909b9..73a146f05 100644
--- a/src/test/bloom_tests.cpp
+++ b/src/test/bloom_tests.cpp
@@ -13,6 +13,7 @@
#include "uint256.h"
#include "util.h"
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <vector>
@@ -21,7 +22,7 @@
using namespace std;
-BOOST_AUTO_TEST_SUITE(bloom_tests)
+BOOST_FIXTURE_TEST_SUITE(bloom_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize)
{
diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp
index a4121caa8..7abfad151 100644
--- a/src/test/checkblock_tests.cpp
+++ b/src/test/checkblock_tests.cpp
@@ -11,6 +11,7 @@
#include "clientversion.h"
#include "main.h"
#include "utiltime.h"
+#include "test/test_bitcoin.h"
#include <cstdio>
@@ -19,7 +20,7 @@
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(CheckBlock_tests)
+BOOST_FIXTURE_TEST_SUITE(CheckBlock_tests, BasicTestingSetup)
bool read_block(const std::string& filename, CBlock& block)
{
diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp
index 3ecd301bc..2e2cc2214 100644
--- a/src/test/coins_tests.cpp
+++ b/src/test/coins_tests.cpp
@@ -5,6 +5,7 @@
#include "coins.h"
#include "random.h"
#include "uint256.h"
+#include "test/test_bitcoin.h"
#include <vector>
#include <map>
@@ -60,7 +61,7 @@ public:
};
}
-BOOST_AUTO_TEST_SUITE(coins_tests)
+BOOST_FIXTURE_TEST_SUITE(coins_tests, BasicTestingSetup)
static const unsigned int NUM_SIMULATION_ITERATIONS = 40000;
diff --git a/src/test/compress_tests.cpp b/src/test/compress_tests.cpp
index b4e4f2046..376ae9368 100644
--- a/src/test/compress_tests.cpp
+++ b/src/test/compress_tests.cpp
@@ -4,6 +4,7 @@
#include "compressor.h"
#include "util.h"
+#include "test/test_bitcoin.h"
#include <stdint.h>
@@ -21,7 +22,7 @@
// amounts 50 .. 21000000
#define NUM_MULTIPLES_50BTC 420000
-BOOST_AUTO_TEST_SUITE(compress_tests)
+BOOST_FIXTURE_TEST_SUITE(compress_tests, BasicTestingSetup)
bool static TestEncode(uint64_t in) {
return in == CTxOutCompressor::DecompressAmount(CTxOutCompressor::CompressAmount(in));
diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp
index d5e595cd8..aeb2a5caa 100644
--- a/src/test/crypto_tests.cpp
+++ b/src/test/crypto_tests.cpp
@@ -10,13 +10,14 @@
#include "crypto/hmac_sha512.h"
#include "random.h"
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <vector>
#include <boost/assign/list_of.hpp>
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(crypto_tests)
+BOOST_FIXTURE_TEST_SUITE(crypto_tests, BasicTestingSetup)
template<typename Hasher, typename In, typename Out>
void TestVector(const Hasher &h, const In &in, const Out &out) {
diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp
index 5fb0f4ccd..a0c5592a9 100644
--- a/src/test/getarg_tests.cpp
+++ b/src/test/getarg_tests.cpp
@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "util.h"
+#include "test/test_bitcoin.h"
#include <string>
#include <vector>
@@ -11,7 +12,7 @@
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(getarg_tests)
+BOOST_FIXTURE_TEST_SUITE(getarg_tests, BasicTestingSetup)
static void ResetArgs(const std::string& strArg)
{
diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp
index f1ad25e6e..e5d2e5a43 100644
--- a/src/test/hash_tests.cpp
+++ b/src/test/hash_tests.cpp
@@ -4,6 +4,7 @@
#include "hash.h"
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <vector>
@@ -11,7 +12,7 @@
using namespace std;
-BOOST_AUTO_TEST_SUITE(hash_tests)
+BOOST_FIXTURE_TEST_SUITE(hash_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(murmurhash3)
{
diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp
index 1333aba47..13ca94946 100644
--- a/src/test/key_tests.cpp
+++ b/src/test/key_tests.cpp
@@ -9,6 +9,7 @@
#include "uint256.h"
#include "util.h"
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <string>
#include <vector>
@@ -58,7 +59,7 @@ void dumpKeyInfo(uint256 privkey)
#endif
-BOOST_AUTO_TEST_SUITE(key_tests)
+BOOST_FIXTURE_TEST_SUITE(key_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(key_test1)
{
diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp
index 1927f3dea..9ec533bcc 100644
--- a/src/test/main_tests.cpp
+++ b/src/test/main_tests.cpp
@@ -23,4 +23,21 @@ BOOST_AUTO_TEST_CASE(subsidy_limit_test)
BOOST_CHECK(nSum == 2099999997690000ULL);
}
+bool ReturnFalse() { return false; }
+bool ReturnTrue() { return true; }
+
+BOOST_AUTO_TEST_CASE(test_combiner_all)
+{
+ boost::signals2::signal<bool (), CombinerAll> Test;
+ BOOST_CHECK(Test());
+ Test.connect(&ReturnFalse);
+ BOOST_CHECK(!Test());
+ Test.connect(&ReturnTrue);
+ BOOST_CHECK(!Test());
+ Test.disconnect(&ReturnFalse);
+ BOOST_CHECK(Test());
+ Test.disconnect(&ReturnTrue);
+ BOOST_CHECK(Test());
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/mruset_tests.cpp b/src/test/mruset_tests.cpp
index 813ec9b8b..bd4e9c1d3 100644
--- a/src/test/mruset_tests.cpp
+++ b/src/test/mruset_tests.cpp
@@ -6,6 +6,7 @@
#include "random.h"
#include "util.h"
+#include "test/test_bitcoin.h"
#include <set>
@@ -34,7 +35,7 @@ public:
}
};
-BOOST_AUTO_TEST_SUITE(mruset_tests)
+BOOST_FIXTURE_TEST_SUITE(mruset_tests, BasicTestingSetup)
// Test that an mruset behaves like a set, as long as no more than MAX_SIZE elements are in it
BOOST_AUTO_TEST_CASE(mruset_like_set)
diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp
index 2168a5fef..6b189a6b5 100644
--- a/src/test/multisig_tests.cpp
+++ b/src/test/multisig_tests.cpp
@@ -10,9 +10,10 @@
#include "script/interpreter.h"
#include "script/sign.h"
#include "uint256.h"
+#include "test/test_bitcoin.h"
#ifdef ENABLE_WALLET
-#include "wallet_ismine.h"
+#include "wallet/wallet_ismine.h"
#endif
#include <boost/foreach.hpp>
@@ -22,7 +23,7 @@ using namespace std;
typedef vector<unsigned char> valtype;
-BOOST_AUTO_TEST_SUITE(multisig_tests)
+BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup)
CScript
sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction, int whichIn)
diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp
index 936145994..cb357d295 100644
--- a/src/test/netbase_tests.cpp
+++ b/src/test/netbase_tests.cpp
@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "netbase.h"
+#include "test/test_bitcoin.h"
#include <string>
@@ -10,7 +11,7 @@
using namespace std;
-BOOST_AUTO_TEST_SUITE(netbase_tests)
+BOOST_FIXTURE_TEST_SUITE(netbase_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(netbase_networks)
{
diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp
index 4406b08e5..f6d06d680 100644
--- a/src/test/pmt_tests.cpp
+++ b/src/test/pmt_tests.cpp
@@ -9,6 +9,7 @@
#include "arith_uint256.h"
#include "version.h"
#include "random.h"
+#include "test/test_bitcoin.h"
#include <vector>
@@ -28,7 +29,7 @@ public:
}
};
-BOOST_AUTO_TEST_SUITE(pmt_tests)
+BOOST_FIXTURE_TEST_SUITE(pmt_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(pmt_test1)
{
diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp
index e42c1b0a8..7b197c527 100644
--- a/src/test/pow_tests.cpp
+++ b/src/test/pow_tests.cpp
@@ -5,12 +5,13 @@
#include "main.h"
#include "pow.h"
#include "util.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
using namespace std;
-BOOST_AUTO_TEST_SUITE(pow_tests)
+BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup)
/* Test calculation of next difficulty target with no constraints applying */
BOOST_AUTO_TEST_CASE(get_next_work)
diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp
index 44475076b..d97bea8bd 100644
--- a/src/test/rpc_wallet_tests.cpp
+++ b/src/test/rpc_wallet_tests.cpp
@@ -6,7 +6,7 @@
#include "rpcclient.h"
#include "base58.h"
-#include "wallet.h"
+#include "wallet/wallet.h"
#include "test/test_bitcoin.h"
diff --git a/src/test/sanity_tests.cpp b/src/test/sanity_tests.cpp
index 464a8fbb8..f5f7f381d 100644
--- a/src/test/sanity_tests.cpp
+++ b/src/test/sanity_tests.cpp
@@ -4,9 +4,11 @@
#include "compat/sanity.h"
#include "key.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(sanity_tests)
+
+BOOST_FIXTURE_TEST_SUITE(sanity_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(basic_sanity)
{
diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp
index 94f2ce1a2..c8cfe2872 100644
--- a/src/test/script_P2SH_tests.cpp
+++ b/src/test/script_P2SH_tests.cpp
@@ -8,9 +8,10 @@
#include "script/script.h"
#include "script/script_error.h"
#include "script/sign.h"
+#include "test/test_bitcoin.h"
#ifdef ENABLE_WALLET
-#include "wallet_ismine.h"
+#include "wallet/wallet_ismine.h"
#endif
#include <vector>
@@ -47,7 +48,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, Scri
}
-BOOST_AUTO_TEST_SUITE(script_P2SH_tests)
+BOOST_FIXTURE_TEST_SUITE(script_P2SH_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(sign)
{
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index e410b5971..c0614cca4 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -13,6 +13,7 @@
#include "script/script_error.h"
#include "script/sign.h"
#include "util.h"
+#include "test/test_bitcoin.h"
#if defined(HAVE_CONSENSUS_LIB)
#include "script/bitcoinconsensus.h"
@@ -53,7 +54,7 @@ read_json(const std::string& jsondata)
return v.get_array();
}
-BOOST_AUTO_TEST_SUITE(script_tests)
+BOOST_FIXTURE_TEST_SUITE(script_tests, BasicTestingSetup)
CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey)
{
diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp
index cfbaf26e7..24c7dd3d5 100644
--- a/src/test/scriptnum_tests.cpp
+++ b/src/test/scriptnum_tests.cpp
@@ -4,10 +4,13 @@
#include "bignum.h"
#include "script/script.h"
+#include "test/test_bitcoin.h"
+
#include <boost/test/unit_test.hpp>
#include <limits.h>
#include <stdint.h>
-BOOST_AUTO_TEST_SUITE(scriptnum_tests)
+
+BOOST_FIXTURE_TEST_SUITE(scriptnum_tests, BasicTestingSetup)
static const int64_t values[] = \
{ 0, 1, CHAR_MIN, CHAR_MAX, UCHAR_MAX, SHRT_MIN, USHRT_MAX, INT_MIN, INT_MAX, UINT_MAX, LONG_MIN, LONG_MAX };
diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp
index de9510d54..cc8f2b788 100644
--- a/src/test/serialize_tests.cpp
+++ b/src/test/serialize_tests.cpp
@@ -5,6 +5,7 @@
#include "serialize.h"
#include "streams.h"
#include "hash.h"
+#include "test/test_bitcoin.h"
#include <stdint.h>
@@ -12,7 +13,7 @@
using namespace std;
-BOOST_AUTO_TEST_SUITE(serialize_tests)
+BOOST_FIXTURE_TEST_SUITE(serialize_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(sizes)
{
diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp
index ea41dbcde..afb7a41bb 100644
--- a/src/test/sighash_tests.cpp
+++ b/src/test/sighash_tests.cpp
@@ -10,6 +10,7 @@
#include "script/interpreter.h"
#include "util.h"
#include "version.h"
+#include "test/test_bitcoin.h"
#include <iostream>
@@ -115,7 +116,7 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle) {
}
}
-BOOST_AUTO_TEST_SUITE(sighash_tests)
+BOOST_FIXTURE_TEST_SUITE(sighash_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(sighash_test)
{
diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp
index 3c8264d89..b26fed99f 100644
--- a/src/test/sigopcount_tests.cpp
+++ b/src/test/sigopcount_tests.cpp
@@ -7,6 +7,7 @@
#include "script/script.h"
#include "script/standard.h"
#include "uint256.h"
+#include "test/test_bitcoin.h"
#include <vector>
@@ -23,7 +24,7 @@ Serialize(const CScript& s)
return sSerialized;
}
-BOOST_AUTO_TEST_SUITE(sigopcount_tests)
+BOOST_FIXTURE_TEST_SUITE(sigopcount_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(GetSigOpCount)
{
diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp
index c75e21a2a..86a4bc672 100644
--- a/src/test/skiplist_tests.cpp
+++ b/src/test/skiplist_tests.cpp
@@ -5,6 +5,7 @@
#include "main.h"
#include "random.h"
#include "util.h"
+#include "test/test_bitcoin.h"
#include <vector>
@@ -12,7 +13,7 @@
#define SKIPLIST_LENGTH 300000
-BOOST_AUTO_TEST_SUITE(skiplist_tests)
+BOOST_FIXTURE_TEST_SUITE(skiplist_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(skiplist_test)
{
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index 5df417b8e..7d5207b11 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -12,8 +12,8 @@
#include "ui_interface.h"
#include "util.h"
#ifdef ENABLE_WALLET
-#include "db.h"
-#include "wallet.h"
+#include "wallet/db.h"
+#include "wallet/wallet.h"
#endif
#include <boost/filesystem.hpp>
@@ -26,11 +26,17 @@ CWallet* pwalletMain;
extern bool fPrintToConsole;
extern void noui_connect();
-TestingSetup::TestingSetup()
+BasicTestingSetup::BasicTestingSetup()
{
fPrintToDebugLog = false; // don't want to write to debug.log file
- SelectParams(CBaseChainParams::UNITTEST);
- noui_connect();
+ SelectParams(CBaseChainParams::MAIN);
+}
+BasicTestingSetup::~BasicTestingSetup()
+{
+}
+
+TestingSetup::TestingSetup()
+{
#ifdef ENABLE_WALLET
bitdb.MakeMock();
#endif
diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h
index c1448dcde..2f75332d4 100644
--- a/src/test/test_bitcoin.h
+++ b/src/test/test_bitcoin.h
@@ -6,7 +6,19 @@
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
-struct TestingSetup {
+/** Basic testing setup.
+ * This just configures logging and chain parameters.
+ */
+struct BasicTestingSetup {
+ BasicTestingSetup();
+ ~BasicTestingSetup();
+};
+
+/** Testing setup that configures a complete environment.
+ * Included are data directory, coins database, script check threads
+ * and wallet (if enabled) setup.
+ */
+struct TestingSetup: public BasicTestingSetup {
CCoinsViewDB *pcoinsdbview;
boost::filesystem::path pathTemp;
boost::thread_group threadGroup;
diff --git a/src/test/timedata_tests.cpp b/src/test/timedata_tests.cpp
index 58ed96327..887cfb476 100644
--- a/src/test/timedata_tests.cpp
+++ b/src/test/timedata_tests.cpp
@@ -3,12 +3,13 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
//
#include "timedata.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
using namespace std;
-BOOST_AUTO_TEST_SUITE(timedata_tests)
+BOOST_FIXTURE_TEST_SUITE(timedata_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(util_MedianFilter)
{
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 52adfea99..2a3083316 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -4,6 +4,7 @@
#include "data/tx_invalid.json.h"
#include "data/tx_valid.json.h"
+#include "test/test_bitcoin.h"
#include "clientversion.h"
#include "key.h"
@@ -75,7 +76,7 @@ string FormatScriptFlags(unsigned int flags)
return ret.substr(0, ret.size() - 1);
}
-BOOST_AUTO_TEST_SUITE(transaction_tests)
+BOOST_FIXTURE_TEST_SUITE(transaction_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(tx_valid)
{
diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp
index 5b33846ba..426d296a9 100644
--- a/src/test/uint256_tests.cpp
+++ b/src/test/uint256_tests.cpp
@@ -4,6 +4,7 @@
#include "arith_uint256.h"
#include "uint256.h"
#include "version.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
#include <stdint.h>
@@ -14,7 +15,7 @@
#include <string>
#include <stdio.h>
-BOOST_AUTO_TEST_SUITE(uint256_tests)
+BOOST_FIXTURE_TEST_SUITE(uint256_tests, BasicTestingSetup)
const unsigned char R1Array[] =
"\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2"
diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp
index 5f0c1deb8..8cecfbf65 100644
--- a/src/test/univalue_tests.cpp
+++ b/src/test/univalue_tests.cpp
@@ -7,12 +7,13 @@
#include <string>
#include <map>
#include "univalue/univalue.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
using namespace std;
-BOOST_AUTO_TEST_SUITE(univalue_tests)
+BOOST_FIXTURE_TEST_SUITE(univalue_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(univalue_constructor)
{
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index d829ec228..3309e2e38 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -10,6 +10,7 @@
#include "sync.h"
#include "utilstrencodings.h"
#include "utilmoneystr.h"
+#include "test/test_bitcoin.h"
#include <stdint.h>
#include <vector>
@@ -18,7 +19,7 @@
using namespace std;
-BOOST_AUTO_TEST_SUITE(util_tests)
+BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(util_criticalsection)
{
diff --git a/src/uint256.cpp b/src/uint256.cpp
index 3b1334a03..25148808c 100644
--- a/src/uint256.cpp
+++ b/src/uint256.cpp
@@ -45,7 +45,7 @@ void base_blob<BITS>::SetHex(const char* psz)
psz++;
psz--;
unsigned char* p1 = (unsigned char*)data;
- unsigned char* pend = p1 + WIDTH * 4;
+ unsigned char* pend = p1 + WIDTH;
while (psz >= pbegin && p1 < pend) {
*p1 = ::HexDigit(*psz--);
if (psz >= pbegin) {
@@ -128,7 +128,7 @@ uint64_t uint256::GetHash(const uint256& salt) const
uint32_t a, b, c;
const uint32_t *pn = (const uint32_t*)data;
const uint32_t *salt_pn = (const uint32_t*)salt.data;
- a = b = c = 0xdeadbeef + (WIDTH << 2);
+ a = b = c = 0xdeadbeef + WIDTH;
a += pn[0] ^ salt_pn[0];
b += pn[1] ^ salt_pn[1];
diff --git a/src/db.cpp b/src/wallet/db.cpp
index 36946b7dc..36946b7dc 100644
--- a/src/db.cpp
+++ b/src/wallet/db.cpp
diff --git a/src/db.h b/src/wallet/db.h
index 71133f969..71133f969 100644
--- a/src/db.h
+++ b/src/wallet/db.h
diff --git a/src/rpcdump.cpp b/src/wallet/rpcdump.cpp
index b9c92a06c..b9c92a06c 100644
--- a/src/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
diff --git a/src/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index d097b6a0f..5502b0b26 100644
--- a/src/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -317,7 +317,7 @@ Value getaddressesbyaccount(const Array& params, bool fHelp)
return ret;
}
-static void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew)
+static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew)
{
CAmount curBalance = pwalletMain->GetBalance();
@@ -335,11 +335,14 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx&
CReserveKey reservekey(pwalletMain);
CAmount nFeeRequired;
std::string strError;
- if (!pwalletMain->CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError)) {
- if (nValue + nFeeRequired > curBalance)
- throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired)));
- else
- throw JSONRPCError(RPC_WALLET_ERROR, strError);
+ vector<CRecipient> vecSend;
+ int nChangePosRet = -1;
+ CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
+ vecSend.push_back(recipient);
+ if (!pwalletMain->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) {
+ if (!fSubtractFeeFromAmount && nValue + nFeeRequired > pwalletMain->GetBalance())
+ strError = strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired));
+ throw JSONRPCError(RPC_WALLET_ERROR, strError);
}
if (!pwalletMain->CommitTransaction(wtxNew, reservekey))
throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
@@ -347,9 +350,9 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx&
Value sendtoaddress(const Array& params, bool fHelp)
{
- if (fHelp || params.size() < 2 || params.size() > 4)
+ if (fHelp || params.size() < 2 || params.size() > 5)
throw runtime_error(
- "sendtoaddress \"bitcoinaddress\" amount ( \"comment\" \"comment-to\" )\n"
+ "sendtoaddress \"bitcoinaddress\" amount ( \"comment\" \"comment-to\" subtractfeefromamount )\n"
"\nSend an amount to a given address. The amount is a real and is rounded to the nearest 0.00000001\n"
+ HelpRequiringPassphrase() +
"\nArguments:\n"
@@ -360,11 +363,14 @@ Value sendtoaddress(const Array& params, bool fHelp)
"4. \"comment-to\" (string, optional) A comment to store the name of the person or organization \n"
" to which you're sending the transaction. This is not part of the \n"
" transaction, just kept in your wallet.\n"
+ "5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n"
+ " The recipient will receive less bitcoins than you enter in the amount field.\n"
"\nResult:\n"
"\"transactionid\" (string) The transaction id.\n"
"\nExamples:\n"
+ HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1")
+ HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"")
+ + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true")
+ HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"")
);
@@ -384,9 +390,13 @@ Value sendtoaddress(const Array& params, bool fHelp)
if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
wtx.mapValue["to"] = params[3].get_str();
+ bool fSubtractFeeFromAmount = false;
+ if (params.size() > 4)
+ fSubtractFeeFromAmount = params[4].get_bool();
+
EnsureWalletIsUnlocked();
- SendMoney(address.Get(), nAmount, wtx);
+ SendMoney(address.Get(), nAmount, fSubtractFeeFromAmount, wtx);
return wtx.GetHash().GetHex();
}
@@ -840,7 +850,7 @@ Value sendfrom(const Array& params, bool fHelp)
if (nAmount > nBalance)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
- SendMoney(address.Get(), nAmount, wtx);
+ SendMoney(address.Get(), nAmount, false, wtx);
return wtx.GetHash().GetHex();
}
@@ -848,9 +858,9 @@ Value sendfrom(const Array& params, bool fHelp)
Value sendmany(const Array& params, bool fHelp)
{
- if (fHelp || params.size() < 2 || params.size() > 4)
+ if (fHelp || params.size() < 2 || params.size() > 5)
throw runtime_error(
- "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" )\n"
+ "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] )\n"
"\nSend multiple times. Amounts are double-precision floating point numbers."
+ HelpRequiringPassphrase() + "\n"
"\nArguments:\n"
@@ -862,6 +872,14 @@ Value sendmany(const Array& params, bool fHelp)
" }\n"
"3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n"
"4. \"comment\" (string, optional) A comment\n"
+ "5. subtractfeefromamount (string, optional) A json array with addresses.\n"
+ " The fee will be equally deducted from the amount of each selected address.\n"
+ " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
+ " If no addresses are specified here, the sender pays the fee.\n"
+ " [\n"
+ " \"address\" (string) Subtract fee from this address\n"
+ " ,...\n"
+ " ]\n"
"\nResult:\n"
"\"transactionid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n"
" the number of addresses.\n"
@@ -870,6 +888,8 @@ Value sendmany(const Array& params, bool fHelp)
+ HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") +
"\nSend two amounts to two different addresses setting the confirmation and comment:\n"
+ HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") +
+ "\nSend two amounts to two different addresses, subtract fee from amount:\n"
+ + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") +
"\nAs a json rpc call\n"
+ HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"")
);
@@ -887,8 +907,12 @@ Value sendmany(const Array& params, bool fHelp)
if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
wtx.mapValue["comment"] = params[3].get_str();
+ Array subtractFeeFromAmount;
+ if (params.size() > 4)
+ subtractFeeFromAmount = params[4].get_array();
+
set<CBitcoinAddress> setAddress;
- vector<pair<CScript, CAmount> > vecSend;
+ vector<CRecipient> vecSend;
CAmount totalAmount = 0;
BOOST_FOREACH(const Pair& s, sendTo)
@@ -905,7 +929,13 @@ Value sendmany(const Array& params, bool fHelp)
CAmount nAmount = AmountFromValue(s.value_);
totalAmount += nAmount;
- vecSend.push_back(make_pair(scriptPubKey, nAmount));
+ bool fSubtractFeeFromAmount = false;
+ BOOST_FOREACH(const Value& addr, subtractFeeFromAmount)
+ if (addr.get_str() == s.name_)
+ fSubtractFeeFromAmount = true;
+
+ CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount};
+ vecSend.push_back(recipient);
}
EnsureWalletIsUnlocked();
@@ -918,8 +948,9 @@ Value sendmany(const Array& params, bool fHelp)
// Send
CReserveKey keyChange(pwalletMain);
CAmount nFeeRequired = 0;
+ int nChangePosRet = -1;
string strFailReason;
- bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, strFailReason);
+ bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason);
if (!fCreated)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
if (!pwalletMain->CommitTransaction(wtx, keyChange))
diff --git a/src/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index 25c8fab33..a5bc52b8d 100644
--- a/src/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -2,7 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "wallet.h"
+#include "wallet/wallet.h"
#include <set>
#include <stdint.h>
diff --git a/src/wallet.cpp b/src/wallet/wallet.cpp
index b51c4d4b1..44b416d49 100644
--- a/src/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -3,7 +3,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "wallet.h"
+#include "wallet/wallet.h"
#include "base58.h"
#include "checkpoints.h"
@@ -18,6 +18,7 @@
#include <assert.h>
#include <boost/algorithm/string/replace.hpp>
+#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
using namespace std;
@@ -339,6 +340,58 @@ set<uint256> CWallet::GetConflicts(const uint256& txid) const
return result;
}
+void CWallet::Flush(bool shutdown)
+{
+ bitdb.Flush(shutdown);
+}
+
+bool CWallet::Verify(const string walletFile, string& warningString, string& errorString)
+{
+ if (!bitdb.Open(GetDataDir()))
+ {
+ // try moving the database env out of the way
+ boost::filesystem::path pathDatabase = GetDataDir() / "database";
+ boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime());
+ try {
+ boost::filesystem::rename(pathDatabase, pathDatabaseBak);
+ LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string());
+ } catch (const boost::filesystem::filesystem_error&) {
+ // failure is ok (well, not really, but it's not worse than what we started with)
+ }
+
+ // try again
+ if (!bitdb.Open(GetDataDir())) {
+ // if it still fails, it probably means we can't even create the database env
+ string msg = strprintf(_("Error initializing wallet database environment %s!"), GetDataDir());
+ errorString += msg;
+ return true;
+ }
+ }
+
+ if (GetBoolArg("-salvagewallet", false))
+ {
+ // Recover readable keypairs:
+ if (!CWalletDB::Recover(bitdb, walletFile, true))
+ return false;
+ }
+
+ if (boost::filesystem::exists(GetDataDir() / walletFile))
+ {
+ CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover);
+ if (r == CDBEnv::RECOVER_OK)
+ {
+ warningString += strprintf(_("Warning: wallet.dat corrupt, data salvaged!"
+ " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if"
+ " your balance or transactions are incorrect you should"
+ " restore from a backup."), GetDataDir());
+ }
+ if (r == CDBEnv::RECOVER_FAIL)
+ errorString += _("wallet.dat corrupt, salvage failed");
+ }
+
+ return true;
+}
+
void CWallet::SyncMetaData(pair<TxSpends::iterator, TxSpends::iterator> range)
{
// We want all the wallet transactions in range to have the same metadata as
@@ -1549,21 +1602,22 @@ bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*
(bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet)));
}
-
-
-
-bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
- CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl)
+bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend,
+ CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl)
{
CAmount nValue = 0;
- BOOST_FOREACH (const PAIRTYPE(CScript, CAmount)& s, vecSend)
+ unsigned int nSubtractFeeFromAmount = 0;
+ BOOST_FOREACH (const CRecipient& recipient, vecSend)
{
- if (nValue < 0)
+ if (nValue < 0 || recipient.nAmount < 0)
{
strFailReason = _("Transaction amounts must be positive");
return false;
}
- nValue += s.second;
+ nValue += recipient.nAmount;
+
+ if (recipient.fSubtractFeeFromAmount)
+ nSubtractFeeFromAmount++;
}
if (vecSend.empty() || nValue < 0)
{
@@ -1606,16 +1660,40 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
txNew.vin.clear();
txNew.vout.clear();
wtxNew.fFromMe = true;
+ nChangePosRet = -1;
+ bool fFirst = true;
- CAmount nTotalValue = nValue + nFeeRet;
+ CAmount nTotalValue = nValue;
+ if (nSubtractFeeFromAmount == 0)
+ nTotalValue += nFeeRet;
double dPriority = 0;
// vouts to the payees
- BOOST_FOREACH (const PAIRTYPE(CScript, CAmount)& s, vecSend)
+ BOOST_FOREACH (const CRecipient& recipient, vecSend)
{
- CTxOut txout(s.second, s.first);
+ CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
+
+ if (recipient.fSubtractFeeFromAmount)
+ {
+ txout.nValue -= nFeeRet / nSubtractFeeFromAmount; // Subtract fee equally from each selected recipient
+
+ if (fFirst) // first receiver pays the remainder not divisible by output count
+ {
+ fFirst = false;
+ txout.nValue -= nFeeRet % nSubtractFeeFromAmount;
+ }
+ }
+
if (txout.IsDust(::minRelayTxFee))
{
- strFailReason = _("Transaction amount too small");
+ if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
+ {
+ if (txout.nValue < 0)
+ strFailReason = _("The transaction amount is too small to pay the fee");
+ else
+ strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
+ }
+ else
+ strFailReason = _("Transaction amount too small");
return false;
}
txNew.vout.push_back(txout);
@@ -1642,7 +1720,9 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
dPriority += (double)nCredit * age;
}
- CAmount nChange = nValueIn - nValue - nFeeRet;
+ CAmount nChange = nValueIn - nValue;
+ if (nSubtractFeeFromAmount == 0)
+ nChange -= nFeeRet;
if (nChange > 0)
{
@@ -1676,6 +1756,28 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
CTxOut newTxOut(nChange, scriptChange);
+ // We do not move dust-change to fees, because the sender would end up paying more than requested.
+ // This would be against the purpose of the all-inclusive feature.
+ // So instead we raise the change and deduct from the recipient.
+ if (nSubtractFeeFromAmount > 0 && newTxOut.IsDust(::minRelayTxFee))
+ {
+ CAmount nDust = newTxOut.GetDustThreshold(::minRelayTxFee) - newTxOut.nValue;
+ newTxOut.nValue += nDust; // raise change until no more dust
+ for (unsigned int i = 0; i < vecSend.size(); i++) // subtract from first recipient
+ {
+ if (vecSend[i].fSubtractFeeFromAmount)
+ {
+ txNew.vout[i].nValue -= nDust;
+ if (txNew.vout[i].IsDust(::minRelayTxFee))
+ {
+ strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
+ return false;
+ }
+ break;
+ }
+ }
+ }
+
// Never create dust outputs; if we would, just
// add the dust to the fee.
if (newTxOut.IsDust(::minRelayTxFee))
@@ -1686,7 +1788,8 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
else
{
// Insert change txn at random position:
- vector<CTxOut>::iterator position = txNew.vout.begin()+GetRandInt(txNew.vout.size()+1);
+ nChangePosRet = GetRandInt(txNew.vout.size()+1);
+ vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosRet;
txNew.vout.insert(position, newTxOut);
}
}
@@ -1755,15 +1858,8 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
}
}
}
- return true;
-}
-bool CWallet::CreateTransaction(CScript scriptPubKey, const CAmount& nValue,
- CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl)
-{
- vector< pair<CScript, CAmount> > vecSend;
- vecSend.push_back(make_pair(scriptPubKey, nValue));
- return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, strFailReason, coinControl);
+ return true;
}
/**
diff --git a/src/wallet.h b/src/wallet/wallet.h
index 6ed87d1e6..1a9feff9f 100644
--- a/src/wallet.h
+++ b/src/wallet/wallet.h
@@ -14,8 +14,8 @@
#include "keystore.h"
#include "main.h"
#include "ui_interface.h"
-#include "wallet_ismine.h"
-#include "walletdb.h"
+#include "wallet/wallet_ismine.h"
+#include "wallet/walletdb.h"
#include <algorithm>
#include <map>
@@ -103,6 +103,12 @@ public:
StringMap destdata;
};
+struct CRecipient
+{
+ CScript scriptPubKey;
+ CAmount nAmount;
+ bool fSubtractFeeFromAmount;
+};
typedef std::map<std::string, std::string> mapValue_t;
@@ -611,10 +617,8 @@ public:
CAmount GetWatchOnlyBalance() const;
CAmount GetUnconfirmedWatchOnlyBalance() const;
CAmount GetImmatureWatchOnlyBalance() const;
- bool CreateTransaction(const std::vector<std::pair<CScript, CAmount> >& vecSend,
- CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl = NULL);
- bool CreateTransaction(CScript scriptPubKey, const CAmount& nValue,
- CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl = NULL);
+ bool CreateTransaction(const std::vector<CRecipient>& vecSend,
+ CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl *coinControl = NULL);
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
static CFeeRate minTxFee;
@@ -739,6 +743,12 @@ public:
//! Get wallet transactions that conflict with given transaction (spend same outputs)
std::set<uint256> GetConflicts(const uint256& txid) const;
+ //! Flush wallet (bitdb flush)
+ void Flush(bool shutdown=false);
+
+ //! Verify the wallet database and perform salvage if required
+ static bool Verify(const std::string walletFile, std::string& warningString, std::string& errorString);
+
/**
* Address book entry changed.
* @note called with lock cs_wallet held.
diff --git a/src/wallet_ismine.cpp b/src/wallet/wallet_ismine.cpp
index 5482348e3..5482348e3 100644
--- a/src/wallet_ismine.cpp
+++ b/src/wallet/wallet_ismine.cpp
diff --git a/src/wallet_ismine.h b/src/wallet/wallet_ismine.h
index 6293df8b1..6293df8b1 100644
--- a/src/wallet_ismine.h
+++ b/src/wallet/wallet_ismine.h
diff --git a/src/walletdb.cpp b/src/wallet/walletdb.cpp
index ddec57d9a..880026d18 100644
--- a/src/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -3,7 +3,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "walletdb.h"
+#include "wallet/walletdb.h"
#include "base58.h"
#include "protocol.h"
@@ -11,7 +11,7 @@
#include "sync.h"
#include "util.h"
#include "utiltime.h"
-#include "wallet.h"
+#include "wallet/wallet.h"
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
diff --git a/src/walletdb.h b/src/wallet/walletdb.h
index 2627ef71a..6aa0fa40d 100644
--- a/src/walletdb.h
+++ b/src/wallet/walletdb.h
@@ -7,7 +7,7 @@
#define BITCOIN_WALLETDB_H
#include "amount.h"
-#include "db.h"
+#include "wallet/db.h"
#include "key.h"
#include "keystore.h"