aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/test/wallet_tests.cpp25
-rw-r--r--src/wallet/wallet.h164
-rw-r--r--src/wallet/walletdb.cpp13
3 files changed, 111 insertions, 91 deletions
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index f03cb4896c..e84d588026 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -328,7 +328,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests)
empty_wallet();
}
-BOOST_AUTO_TEST_CASE(pruning_in_ApproximateBestSet)
+BOOST_AUTO_TEST_CASE(ApproximateBestSubset)
{
CoinSet setCoinsRet;
CAmount nValueRet;
@@ -336,15 +336,28 @@ BOOST_AUTO_TEST_CASE(pruning_in_ApproximateBestSet)
LOCK(wallet.cs_wallet);
empty_wallet();
+
+ // Test vValue sort order
+ for (int i = 0; i < 1000; i++)
+ add_coin(1000 * COIN);
+ add_coin(3 * COIN);
+
+ BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet));
+ BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN);
+ BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U);
+
+ empty_wallet();
+
+ // Test trimming
for (int i = 0; i < 100; i++)
- add_coin(10 * CENT);
+ add_coin(10 * COIN);
for (int i = 0; i < 100; i++)
- add_coin(1000 * CENT);
+ add_coin(1000 * COIN);
- BOOST_CHECK(wallet.SelectCoinsMinConf(100001 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet));
+ BOOST_CHECK(wallet.SelectCoinsMinConf(100001 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet));
// We need all 100 larger coins and exactly one small coin.
- // Superfluous small coins must be pruned:
- BOOST_CHECK_EQUAL(nValueRet, 100010 * CENT);
+ // Superfluous small coins must be trimmed from the set:
+ BOOST_CHECK_EQUAL(nValueRet, 100010 * COIN);
BOOST_CHECK_EQUAL(setCoinsRet.size(), 101);
}
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 53a2b96690..a9d0c3f604 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -59,7 +59,6 @@ static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWa
static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000;
static const bool DEFAULT_WALLETBROADCAST = true;
-class CAccountingEntry;
class CBlockIndex;
class CCoinControl;
class COutput;
@@ -445,6 +444,86 @@ public:
}
};
+/**
+ * Internal transfers.
+ * Database key is acentry<account><counter>.
+ */
+class CAccountingEntry
+{
+public:
+ std::string strAccount;
+ CAmount nCreditDebit;
+ int64_t nTime;
+ std::string strOtherAccount;
+ std::string strComment;
+ mapValue_t mapValue;
+ int64_t nOrderPos; //! position in ordered transaction list
+ uint64_t nEntryNo;
+
+ CAccountingEntry()
+ {
+ SetNull();
+ }
+
+ void SetNull()
+ {
+ nCreditDebit = 0;
+ nTime = 0;
+ strAccount.clear();
+ strOtherAccount.clear();
+ strComment.clear();
+ nOrderPos = -1;
+ nEntryNo = 0;
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ if (!(nType & SER_GETHASH))
+ READWRITE(nVersion);
+ //! Note: strAccount is serialized as part of the key, not here.
+ READWRITE(nCreditDebit);
+ READWRITE(nTime);
+ READWRITE(LIMITED_STRING(strOtherAccount, 65536));
+
+ if (!ser_action.ForRead())
+ {
+ WriteOrderPos(nOrderPos, mapValue);
+
+ if (!(mapValue.empty() && _ssExtra.empty()))
+ {
+ CDataStream ss(nType, nVersion);
+ ss.insert(ss.begin(), '\0');
+ ss << mapValue;
+ ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end());
+ strComment.append(ss.str());
+ }
+ }
+
+ READWRITE(LIMITED_STRING(strComment, 65536));
+
+ size_t nSepPos = strComment.find("\0", 0, 1);
+ if (ser_action.ForRead())
+ {
+ mapValue.clear();
+ if (std::string::npos != nSepPos)
+ {
+ CDataStream ss(std::vector<char>(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion);
+ ss >> mapValue;
+ _ssExtra = std::vector<char>(ss.begin(), ss.end());
+ }
+ ReadOrderPos(nOrderPos, mapValue);
+ }
+ if (std::string::npos != nSepPos)
+ strComment.erase(nSepPos);
+
+ mapValue.erase("n");
+ }
+
+private:
+ std::vector<char> _ssExtra;
+};
/**
@@ -840,87 +919,4 @@ public:
}
};
-
-
-/**
- * Internal transfers.
- * Database key is acentry<account><counter>.
- */
-class CAccountingEntry
-{
-public:
- std::string strAccount;
- CAmount nCreditDebit;
- int64_t nTime;
- std::string strOtherAccount;
- std::string strComment;
- mapValue_t mapValue;
- int64_t nOrderPos; //! position in ordered transaction list
- uint64_t nEntryNo;
-
- CAccountingEntry()
- {
- SetNull();
- }
-
- void SetNull()
- {
- nCreditDebit = 0;
- nTime = 0;
- strAccount.clear();
- strOtherAccount.clear();
- strComment.clear();
- nOrderPos = -1;
- nEntryNo = 0;
- }
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- if (!(nType & SER_GETHASH))
- READWRITE(nVersion);
- //! Note: strAccount is serialized as part of the key, not here.
- READWRITE(nCreditDebit);
- READWRITE(nTime);
- READWRITE(LIMITED_STRING(strOtherAccount, 65536));
-
- if (!ser_action.ForRead())
- {
- WriteOrderPos(nOrderPos, mapValue);
-
- if (!(mapValue.empty() && _ssExtra.empty()))
- {
- CDataStream ss(nType, nVersion);
- ss.insert(ss.begin(), '\0');
- ss << mapValue;
- ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end());
- strComment.append(ss.str());
- }
- }
-
- READWRITE(LIMITED_STRING(strComment, 65536));
-
- size_t nSepPos = strComment.find("\0", 0, 1);
- if (ser_action.ForRead())
- {
- mapValue.clear();
- if (std::string::npos != nSepPos)
- {
- CDataStream ss(std::vector<char>(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion);
- ss >> mapValue;
- _ssExtra = std::vector<char>(ss.begin(), ss.end());
- }
- ReadOrderPos(nOrderPos, mapValue);
- }
- if (std::string::npos != nSepPos)
- strComment.erase(nSepPos);
-
- mapValue.erase("n");
- }
-
-private:
- std::vector<char> _ssExtra;
-};
-
#endif // BITCOIN_WALLET_WALLET_H
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 88dc3102da..5266946ca0 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -15,6 +15,12 @@
#include "utiltime.h"
#include "wallet/wallet.h"
+#if defined(FORCE_BOOST_EMULATED_SCOPED_ENUMS)
+#define BOOST_NO_SCOPED_ENUMS
+#define BOOST_NO_CXX11_SCOPED_ENUMS
+#endif
+
+#include <boost/version.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/scoped_ptr.hpp>
@@ -960,8 +966,13 @@ bool CWalletDB::Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKe
CDataStream ssKey(row.first, SER_DISK, CLIENT_VERSION);
CDataStream ssValue(row.second, SER_DISK, CLIENT_VERSION);
string strType, strErr;
- bool fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue,
+ bool fReadOK;
+ {
+ // Required in LoadKeyMetadata():
+ LOCK(dummyWallet.cs_wallet);
+ fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue,
wss, strType, strErr);
+ }
if (!IsKeyType(strType))
continue;
if (!fReadOK)