Remove direct bitcoin calls from qt/coincontroldialog.cpp

This commit is contained in:
Russell Yanofsky 2017-04-17 19:46:08 -04:00 committed by xdustinface
parent bda6fc4be9
commit 7bb2d25c3d
7 changed files with 149 additions and 81 deletions

View File

@ -15,6 +15,9 @@
#include <net_processing.h> #include <net_processing.h>
#include <netaddress.h> #include <netaddress.h>
#include <netbase.h> #include <netbase.h>
#include <policy/feerate.h>
#include <policy/fees.h>
#include <policy/policy.h>
#include <primitives/block.h> #include <primitives/block.h>
#include <rpc/server.h> #include <rpc/server.h>
#include <scheduler.h> #include <scheduler.h>
@ -29,6 +32,7 @@
#include <config/dash-config.h> #include <config/dash-config.h>
#endif #endif
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
#include <wallet/fees.h>
#include <wallet/wallet.h> #include <wallet/wallet.h>
#define CHECK_WALLET(x) x #define CHECK_WALLET(x) x
#else #else
@ -194,7 +198,31 @@ class NodeImpl : public Node
} }
bool getNetworkActive() override { return g_connman && g_connman->GetNetworkActive(); } bool getNetworkActive() override { return g_connman && g_connman->GetNetworkActive(); }
unsigned int getTxConfirmTarget() override { CHECK_WALLET(return ::nTxConfirmTarget); } unsigned int getTxConfirmTarget() override { CHECK_WALLET(return ::nTxConfirmTarget); }
CAmount getRequiredFee(unsigned int tx_bytes) override { CHECK_WALLET(return GetRequiredFee(tx_bytes)); }
CAmount getMinimumFee(unsigned int tx_bytes,
const CCoinControl& coin_control,
int* returned_target,
FeeReason* reason) override
{
FeeCalculation fee_calc;
CAmount result;
CHECK_WALLET(result = GetMinimumFee(tx_bytes, coin_control, ::mempool, ::feeEstimator, &fee_calc));
if (returned_target) *returned_target = fee_calc.returnedTarget;
if (reason) *reason = fee_calc.reason;
return result;
}
CAmount getMaxTxFee() override { return ::maxTxFee; } CAmount getMaxTxFee() override { return ::maxTxFee; }
CFeeRate estimateSmartFee(int num_blocks, bool conservative, int* returned_target = nullptr) override
{
FeeCalculation fee_calc;
CFeeRate result = ::feeEstimator.estimateSmartFee(num_blocks, &fee_calc, conservative);
if (returned_target) {
*returned_target = fee_calc.returnedTarget;
}
return result;
}
CFeeRate getDustRelayFee() override { return ::dustRelayFee; }
CFeeRate getPayTxFee() override { CHECK_WALLET(return ::payTxFee); }
UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) override UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) override
{ {
JSONRPCRequest req; JSONRPCRequest req;

View File

@ -19,11 +19,14 @@
#include <tuple> #include <tuple>
#include <vector> #include <vector>
class CCoinControl;
class CDeterministicMNList; class CDeterministicMNList;
class CFeeRate;
class CNodeStats; class CNodeStats;
class RPCTimerInterface; class RPCTimerInterface;
class UniValue; class UniValue;
class proxyType; class proxyType;
enum class FeeReason;
struct CNodeStateStats; struct CNodeStateStats;
namespace interface { namespace interface {
@ -149,9 +152,27 @@ public:
//! Get tx confirm target. //! Get tx confirm target.
virtual unsigned int getTxConfirmTarget() = 0; virtual unsigned int getTxConfirmTarget() = 0;
//! Get required fee.
virtual CAmount getRequiredFee(unsigned int tx_bytes) = 0;
//! Get minimum fee.
virtual CAmount getMinimumFee(unsigned int tx_bytes,
const CCoinControl& coin_control,
int* returned_target,
FeeReason* reason) = 0;
//! Get max tx fee. //! Get max tx fee.
virtual CAmount getMaxTxFee() = 0; virtual CAmount getMaxTxFee() = 0;
//! Estimate smart fee.
virtual CFeeRate estimateSmartFee(int num_blocks, bool conservative, int* returned_target = nullptr) = 0;
//! Get dust relay fee.
virtual CFeeRate getDustRelayFee() = 0;
//! Get pay tx fee.
virtual CFeeRate getPayTxFee() = 0;
//! Execute rpc command. //! Execute rpc command.
virtual UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) = 0; virtual UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) = 0;

View File

@ -51,6 +51,17 @@ public:
CReserveKey m_key; CReserveKey m_key;
}; };
//! Construct wallet TxOut struct.
WalletTxOut MakeWalletTxOut(CWallet& wallet, const CWalletTx& wtx, int n, int depth)
{
WalletTxOut result;
result.txout = wtx.tx->vout[n];
result.time = wtx.GetTxTime();
result.depth_in_main_chain = depth;
result.is_spent = wallet.IsSpent(wtx.GetHash(), n);
return result;
}
class WalletImpl : public Wallet class WalletImpl : public Wallet
{ {
public: public:
@ -220,6 +231,36 @@ public:
return m_wallet.GetAvailableBalance(&coin_control); return m_wallet.GetAvailableBalance(&coin_control);
} }
} }
CoinsList listCoins() override
{
LOCK2(::cs_main, m_wallet.cs_wallet);
CoinsList result;
for (const auto& entry : m_wallet.ListCoins()) {
auto& group = result[entry.first];
for (const auto& coin : entry.second) {
group.emplace_back(
COutPoint(coin.tx->GetHash(), coin.i), MakeWalletTxOut(m_wallet, *coin.tx, coin.i, coin.nDepth));
}
}
return result;
}
std::vector<WalletTxOut> getCoins(const std::vector<COutPoint>& outputs) override
{
LOCK2(::cs_main, m_wallet.cs_wallet);
std::vector<WalletTxOut> result;
result.reserve(outputs.size());
for (const auto& output : outputs) {
result.emplace_back();
auto it = m_wallet.mapWallet.find(output.hash);
if (it != m_wallet.mapWallet.end()) {
int depth = it->second.GetDepthInMainChain();
if (depth >= 0) {
result.back() = MakeWalletTxOut(m_wallet, it->second, output.n, depth);
}
}
}
return result;
}
bool hdEnabled() override { return m_wallet.IsHDEnabled(); } bool hdEnabled() override { return m_wallet.IsHDEnabled(); }
std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) override std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) override
{ {

View File

@ -17,6 +17,7 @@
#include <memory> #include <memory>
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#include <tuple>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -30,6 +31,7 @@ namespace interface {
class Handler; class Handler;
class PendingWalletTx; class PendingWalletTx;
struct WalletBalances; struct WalletBalances;
struct WalletTxOut;
using WalletOrderForm = std::vector<std::pair<std::string, std::string>>; using WalletOrderForm = std::vector<std::pair<std::string, std::string>>;
using WalletValueMap = std::map<std::string, std::string>; using WalletValueMap = std::map<std::string, std::string>;
@ -162,6 +164,14 @@ public:
//! Get available balance. //! Get available balance.
virtual CAmount getAvailableBalance(const CCoinControl& coin_control, bool fAnonymized = false) = 0; virtual CAmount getAvailableBalance(const CCoinControl& coin_control, bool fAnonymized = false) = 0;
//! Return AvailableCoins + LockedCoins grouped by wallet address.
//! (put change in one group with wallet address)
using CoinsList = std::map<CTxDestination, std::vector<std::tuple<COutPoint, WalletTxOut>>>;
virtual CoinsList listCoins() = 0;
//! Return wallet transaction output information.
virtual std::vector<WalletTxOut> getCoins(const std::vector<COutPoint>& outputs) = 0;
// Return whether HD enabled. // Return whether HD enabled.
virtual bool hdEnabled() = 0; virtual bool hdEnabled() = 0;
@ -235,6 +245,15 @@ struct WalletBalances
} }
}; };
//! Wallet transaction output.
struct WalletTxOut
{
CTxOut txout;
int64_t time;
int depth_in_main_chain = -1;
bool is_spent = false;
};
//! Return implementation of Wallet interface. This function will be undefined //! Return implementation of Wallet interface. This function will be undefined
//! in builds where ENABLE_WALLET is false. //! in builds where ENABLE_WALLET is false.
std::unique_ptr<Wallet> MakeWallet(CWallet& wallet); std::unique_ptr<Wallet> MakeWallet(CWallet& wallet);

View File

@ -14,7 +14,7 @@
#include <qt/walletmodel.h> #include <qt/walletmodel.h>
#include <wallet/coincontrol.h> #include <wallet/coincontrol.h>
#include <init.h> #include <interface/node.h>
#include <policy/fees.h> #include <policy/fees.h>
#include <policy/policy.h> #include <policy/policy.h>
#include <validation.h> // For mempool #include <validation.h> // For mempool
@ -221,13 +221,13 @@ void CoinControlDialog::buttonToggleLockClicked()
if (coinControl()->IsUsingPrivateSend() && !fHideAdditional && !model->isFullyMixed(outpt)) { if (coinControl()->IsUsingPrivateSend() && !fHideAdditional && !model->isFullyMixed(outpt)) {
continue; continue;
} }
if (model->isLockedCoin(uint256S(item->data(COLUMN_ADDRESS, TxHashRole).toString().toStdString()), item->data(COLUMN_ADDRESS, VOutRole).toUInt())){ if (model->wallet().isLockedCoin(outpt)) {
model->unlockCoin(outpt); model->wallet().unlockCoin(outpt);
item->setDisabled(false); item->setDisabled(false);
item->setIcon(COLUMN_CHECKBOX, QIcon()); item->setIcon(COLUMN_CHECKBOX, QIcon());
} }
else{ else{
model->lockCoin(outpt); model->wallet().lockCoin(outpt);
item->setDisabled(true); item->setDisabled(true);
item->setIcon(COLUMN_CHECKBOX, GUIUtil::getIcon("lock_closed", GUIUtil::ThemedColor::RED)); item->setIcon(COLUMN_CHECKBOX, GUIUtil::getIcon("lock_closed", GUIUtil::ThemedColor::RED));
} }
@ -476,7 +476,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
{ {
CTxOut txout(amount, static_cast<CScript>(std::vector<unsigned char>(24, 0))); CTxOut txout(amount, static_cast<CScript>(std::vector<unsigned char>(24, 0)));
txDummy.vout.push_back(txout); txDummy.vout.push_back(txout);
fDust |= IsDust(txout, ::dustRelayFee); fDust |= IsDust(txout, model->node().getDustRelayFee());
} }
} }
@ -492,16 +492,16 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
bool fUnselectedNonMixed{false}; bool fUnselectedNonMixed{false};
std::vector<COutPoint> vCoinControl; std::vector<COutPoint> vCoinControl;
std::vector<COutput> vOutputs;
coinControl()->ListSelected(vCoinControl); coinControl()->ListSelected(vCoinControl);
model->getOutputs(vCoinControl, vOutputs);
for (const COutput& out : vOutputs) { size_t i = 0;
for (const auto& out : model->wallet().getCoins(vCoinControl)) {
if (out.depth_in_main_chain < 0) continue;
// unselect already spent, very unlikely scenario, this could happen // unselect already spent, very unlikely scenario, this could happen
// when selected are spent elsewhere, like rpc or another computer // when selected are spent elsewhere, like rpc or another computer
uint256 txhash = out.tx->GetHash(); const COutPoint& outpt = vCoinControl[i++];
COutPoint outpt(txhash, out.i); if (out.is_spent)
if (model->isSpent(outpt))
{ {
coinControl()->UnSelect(outpt); coinControl()->UnSelect(outpt);
fUnselectedSpent = true; fUnselectedSpent = true;
@ -512,11 +512,11 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
nQuantity++; nQuantity++;
// Amount // Amount
nAmount += out.tx->tx->vout[out.i].nValue; nAmount += out.txout.nValue;
// Bytes // Bytes
CTxDestination address; CTxDestination address;
if(ExtractDestination(out.tx->tx->vout[out.i].scriptPubKey, address)) if(ExtractDestination(out.txout.scriptPubKey, address))
{ {
CPubKey pubkey; CPubKey pubkey;
CKeyID *keyid = boost::get<CKeyID>(&address); CKeyID *keyid = boost::get<CKeyID>(&address);
@ -542,7 +542,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
nBytes -= 34; nBytes -= 34;
// Fee // Fee
nPayFee = GetMinimumFee(nBytes, *coinControl(), ::mempool, ::feeEstimator, nullptr /* FeeCalculation */); nPayFee = model->node().getMinimumFee(nBytes, *coinControl(), nullptr /* returned_target */, nullptr /* reason */);
if (nPayAmount > 0) if (nPayAmount > 0)
{ {
@ -563,7 +563,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
if (nChange > 0 && nChange < MIN_CHANGE) if (nChange > 0 && nChange < MIN_CHANGE)
{ {
CTxOut txout(nChange, static_cast<CScript>(std::vector<unsigned char>(24, 0))); CTxOut txout(nChange, static_cast<CScript>(std::vector<unsigned char>(24, 0)));
if (IsDust(txout, ::dustRelayFee)) if (IsDust(txout, model->node().getDustRelayFee()))
{ {
nPayFee += nChange; nPayFee += nChange;
nChange = 0; nChange = 0;
@ -716,13 +716,10 @@ void CoinControlDialog::updateView()
int nDisplayUnit = model->getOptionsModel()->getDisplayUnit(); int nDisplayUnit = model->getOptionsModel()->getDisplayUnit();
std::map<QString, std::vector<COutput> > mapCoins; for (const auto& coins : model->wallet().listCoins()) {
model->listCoins(mapCoins);
for (const std::pair<const QString, std::vector<COutput>>& coins : mapCoins) {
CCoinControlWidgetItem *itemWalletAddress = new CCoinControlWidgetItem(); CCoinControlWidgetItem *itemWalletAddress = new CCoinControlWidgetItem();
itemWalletAddress->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); itemWalletAddress->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
QString sWalletAddress = coins.first; QString sWalletAddress = QString::fromStdString(EncodeDestination(coins.first));
QString sWalletLabel = model->getAddressTableModel()->labelForAddress(sWalletAddress); QString sWalletLabel = model->getAddressTableModel()->labelForAddress(sWalletAddress);
if (sWalletLabel.isEmpty()) if (sWalletLabel.isEmpty())
sWalletLabel = tr("(no label)"); sWalletLabel = tr("(no label)");
@ -746,27 +743,27 @@ void CoinControlDialog::updateView()
CAmount nSum = 0; CAmount nSum = 0;
int nChildren = 0; int nChildren = 0;
for (const COutput& out : coins.second) { for (const auto& outpair : coins.second) {
COutPoint outpoint = COutPoint(out.tx->tx->GetHash(), out.i); const COutPoint& output = std::get<0>(outpair);
const interface::WalletTxOut& out = std::get<1>(outpair);
bool fFullyMixed{false}; bool fFullyMixed{false};
CAmount nAmount = out.tx->tx->vout[out.i].nValue; CAmount nAmount = out.txout.nValue;
bool fPrivateSendAmount = CPrivateSend::IsDenominatedAmount(nAmount) || CPrivateSend::IsCollateralAmount(nAmount); bool fPrivateSendAmount = CPrivateSend::IsDenominatedAmount(nAmount) || CPrivateSend::IsCollateralAmount(nAmount);
if (coinControl()->IsUsingPrivateSend()) { if (coinControl()->IsUsingPrivateSend()) {
fFullyMixed = model->isFullyMixed(outpoint); fFullyMixed = model->isFullyMixed(output);
if ((fHideAdditional && !fFullyMixed) || (!fHideAdditional && !fPrivateSendAmount)) { if ((fHideAdditional && !fFullyMixed) || (!fHideAdditional && !fPrivateSendAmount)) {
coinControl()->UnSelect(outpoint); coinControl()->UnSelect(output);
continue; continue;
} }
} else { } else {
if (fHideAdditional && fPrivateSendAmount) { if (fHideAdditional && fPrivateSendAmount) {
coinControl()->UnSelect(outpoint); coinControl()->UnSelect(output);
continue; continue;
} }
} }
nSum += out.tx->tx->vout[out.i].nValue; nSum += out.txout.nValue;
nChildren++; nChildren++;
CCoinControlWidgetItem* itemOutput; CCoinControlWidgetItem* itemOutput;
@ -781,7 +778,7 @@ void CoinControlDialog::updateView()
// address // address
CTxDestination outputAddress; CTxDestination outputAddress;
QString sAddress = ""; QString sAddress = "";
if (ExtractDestination(out.tx->tx->vout[out.i].scriptPubKey, outputAddress)) { if (ExtractDestination(out.txout.scriptPubKey, outputAddress)) {
sAddress = QString::fromStdString(EncodeDestination(outputAddress)); sAddress = QString::fromStdString(EncodeDestination(outputAddress));
// if listMode or change => show dash address. In tree mode, address is not shown again for direct wallet address outputs // if listMode or change => show dash address. In tree mode, address is not shown again for direct wallet address outputs
@ -806,17 +803,17 @@ void CoinControlDialog::updateView()
} }
// amount // amount
itemOutput->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, out.tx->tx->vout[out.i].nValue)); itemOutput->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, out.txout.nValue));
itemOutput->setToolTip(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, out.tx->tx->vout[out.i].nValue)); itemOutput->setToolTip(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, out.txout.nValue));
itemOutput->setData(COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong)out.tx->tx->vout[out.i].nValue)); // padding so that sorting works correctly itemOutput->setData(COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong)out.txout.nValue)); // padding so that sorting works correctly
// date // date
itemOutput->setText(COLUMN_DATE, GUIUtil::dateTimeStr(out.tx->GetTxTime())); itemOutput->setText(COLUMN_DATE, GUIUtil::dateTimeStr(out.time));
itemOutput->setToolTip(COLUMN_DATE, GUIUtil::dateTimeStr(out.tx->GetTxTime())); itemOutput->setToolTip(COLUMN_DATE, GUIUtil::dateTimeStr(out.time));
itemOutput->setData(COLUMN_DATE, Qt::UserRole, QVariant((qlonglong)out.tx->GetTxTime())); itemOutput->setData(COLUMN_DATE, Qt::UserRole, QVariant((qlonglong)out.time));
// PrivateSend rounds // PrivateSend rounds
int nRounds = model->getRealOutpointPrivateSendRounds(outpoint); int nRounds = model->getRealOutpointPrivateSendRounds(output);
if (nRounds >= 0 || LogAcceptCategory(BCLog::PRIVATESEND)) { if (nRounds >= 0 || LogAcceptCategory(BCLog::PRIVATESEND)) {
itemOutput->setText(COLUMN_PRIVATESEND_ROUNDS, QString::number(nRounds)); itemOutput->setText(COLUMN_PRIVATESEND_ROUNDS, QString::number(nRounds));
} else { } else {
@ -825,26 +822,24 @@ void CoinControlDialog::updateView()
itemOutput->setData(COLUMN_PRIVATESEND_ROUNDS, Qt::UserRole, QVariant((qlonglong)nRounds)); itemOutput->setData(COLUMN_PRIVATESEND_ROUNDS, Qt::UserRole, QVariant((qlonglong)nRounds));
// confirmations // confirmations
itemOutput->setText(COLUMN_CONFIRMATIONS, QString::number(out.nDepth)); itemOutput->setText(COLUMN_CONFIRMATIONS, QString::number(out.depth_in_main_chain));
itemOutput->setData(COLUMN_CONFIRMATIONS, Qt::UserRole, QVariant((qlonglong)out.nDepth)); itemOutput->setData(COLUMN_CONFIRMATIONS, Qt::UserRole, QVariant((qlonglong)out.depth_in_main_chain));
// transaction hash // transaction hash
uint256 txhash = out.tx->GetHash(); itemOutput->setData(COLUMN_ADDRESS, TxHashRole, QString::fromStdString(output.hash.GetHex()));
itemOutput->setData(COLUMN_ADDRESS, TxHashRole, QString::fromStdString(txhash.GetHex()));
// vout index // vout index
itemOutput->setData(COLUMN_ADDRESS, VOutRole, out.i); itemOutput->setData(COLUMN_ADDRESS, VOutRole, output.n);
// disable locked coins // disable locked coins
if (model->wallet().isLockedCoin(COutPoint(txhash, out.i))) { if (model->wallet().isLockedCoin(output)) {
COutPoint outpt(txhash, out.i); coinControl()->UnSelect(output); // just to be sure
coinControl()->UnSelect(outpt); // just to be sure
itemOutput->setDisabled(true); itemOutput->setDisabled(true);
itemOutput->setIcon(COLUMN_CHECKBOX, GUIUtil::getIcon("lock_closed", GUIUtil::ThemedColor::RED)); itemOutput->setIcon(COLUMN_CHECKBOX, GUIUtil::getIcon("lock_closed", GUIUtil::ThemedColor::RED));
} }
// set checkbox // set checkbox
if (coinControl()->IsSelected(COutPoint(txhash, out.i))) { if (coinControl()->IsSelected(output)) {
itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Checked); itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Checked);
} }

View File

@ -565,38 +565,6 @@ void WalletModel::UnlockContext::CopyFrom(const UnlockContext& rhs)
rhs.was_mixing = false; rhs.was_mixing = false;
} }
// returns a list of COutputs from COutPoints
void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs)
{
LOCK2(cs_main, cwallet->cs_wallet);
for (const COutPoint& outpoint : vOutpoints)
{
auto it = cwallet->mapWallet.find(outpoint.hash);
if (it == cwallet->mapWallet.end()) continue;
int nDepth = it->second.GetDepthInMainChain();
if (nDepth < 0) continue;
COutput out(&it->second, outpoint.n, nDepth, true /* spendable */, true /* solvable */, true /* safe */);
vOutputs.push_back(out);
}
}
bool WalletModel::isSpent(const COutPoint& outpoint) const
{
LOCK2(cs_main, cwallet->cs_wallet);
return cwallet->IsSpent(outpoint.hash, outpoint.n);
}
// AvailableCoins + LockedCoins grouped by wallet address (put change in one group with wallet address)
void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const
{
for (auto& group : cwallet->ListCoins()) {
auto& resultGroup = mapCoins[QString::fromStdString(EncodeDestination(group.first))];
for (auto& coin : group.second) {
resultGroup.emplace_back(std::move(coin));
}
}
}
void WalletModel::loadReceiveRequests(std::vector<std::string>& vReceiveRequests) void WalletModel::loadReceiveRequests(std::vector<std::string>& vReceiveRequests)
{ {
vReceiveRequests = m_wallet->getDestValues("rr"); // receive request vReceiveRequests = m_wallet->getDestValues("rr"); // receive request

View File

@ -189,10 +189,6 @@ public:
UnlockContext requestUnlock(bool fForMixingOnly=false); UnlockContext requestUnlock(bool fForMixingOnly=false);
void getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs);
bool isSpent(const COutPoint& outpoint) const;
void listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const;
void loadReceiveRequests(std::vector<std::string>& vReceiveRequests); void loadReceiveRequests(std::vector<std::string>& vReceiveRequests);
bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest); bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest);