Make sure we re-check the conditions of a feebump during commit

This commit is contained in:
Jonas Schnelli 2017-05-11 09:34:39 +02:00
parent 9b9ca538cd
commit a38783747b
No known key found for this signature in database
GPG key ID: 1EB776BB03C7922D
2 changed files with 34 additions and 19 deletions

View file

@ -41,6 +41,31 @@ int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *pWal
return GetVirtualTransactionSize(txNew); return GetVirtualTransactionSize(txNew);
} }
bool CFeeBumper::preconditionChecks(const CWallet *pWallet, const CWalletTx& wtx) {
if (pWallet->HasWalletSpend(wtx.GetHash())) {
vErrors.push_back("Transaction has descendants in the wallet");
currentResult = BumpFeeResult::INVALID_PARAMETER;
return false;
}
{
LOCK(mempool.cs);
auto it_mp = mempool.mapTx.find(wtx.GetHash());
if (it_mp != mempool.mapTx.end() && it_mp->GetCountWithDescendants() > 1) {
vErrors.push_back("Transaction has descendants in the mempool");
currentResult = BumpFeeResult::INVALID_PARAMETER;
return false;
}
}
if (wtx.GetDepthInMainChain() != 0) {
vErrors.push_back("Transaction has been mined, or is conflicted with a mined transaction");
currentResult = BumpFeeResult::WALLET_ERROR;
return false;
}
return true;
}
CFeeBumper::CFeeBumper(const CWallet *pWallet, const uint256 txidIn, int newConfirmTarget, bool specifiedConfirmTarget, CAmount totalFee, bool newTxReplaceable) CFeeBumper::CFeeBumper(const CWallet *pWallet, const uint256 txidIn, int newConfirmTarget, bool specifiedConfirmTarget, CAmount totalFee, bool newTxReplaceable)
: :
txid(std::move(txidIn)), txid(std::move(txidIn)),
@ -58,25 +83,7 @@ CFeeBumper::CFeeBumper(const CWallet *pWallet, const uint256 txidIn, int newConf
auto it = pWallet->mapWallet.find(txid); auto it = pWallet->mapWallet.find(txid);
const CWalletTx& wtx = it->second; const CWalletTx& wtx = it->second;
if (pWallet->HasWalletSpend(txid)) { if (!preconditionChecks(pWallet, wtx)) {
vErrors.push_back("Transaction has descendants in the wallet");
currentResult = BumpFeeResult::INVALID_PARAMETER;
return;
}
{
LOCK(mempool.cs);
auto it_mp = mempool.mapTx.find(txid);
if (it_mp != mempool.mapTx.end() && it_mp->GetCountWithDescendants() > 1) {
vErrors.push_back("Transaction has descendants in the mempool");
currentResult = BumpFeeResult::INVALID_PARAMETER;
return;
}
}
if (wtx.GetDepthInMainChain() != 0) {
vErrors.push_back("Transaction has been mined, or is conflicted with a mined transaction");
currentResult = BumpFeeResult::WALLET_ERROR;
return; return;
} }
@ -248,6 +255,11 @@ bool CFeeBumper::commit(CWallet *pWallet)
} }
CWalletTx& oldWtx = pWallet->mapWallet[txid]; CWalletTx& oldWtx = pWallet->mapWallet[txid];
// make sure the transaction still has no descendants and hasen't been mined in the meantime
if (!preconditionChecks(pWallet, oldWtx)) {
return false;
}
CWalletTx wtxBumped(pWallet, MakeTransactionRef(std::move(mtx))); CWalletTx wtxBumped(pWallet, MakeTransactionRef(std::move(mtx)));
// commit/broadcast the tx // commit/broadcast the tx
CReserveKey reservekey(pWallet); CReserveKey reservekey(pWallet);

View file

@ -8,6 +8,7 @@
#include <primitives/transaction.h> #include <primitives/transaction.h>
class CWallet; class CWallet;
class CWalletTx;
class uint256; class uint256;
enum class BumpFeeResult enum class BumpFeeResult
@ -44,6 +45,8 @@ public:
bool commit(CWallet *pWalletNonConst); bool commit(CWallet *pWalletNonConst);
private: private:
bool preconditionChecks(const CWallet *pWallet, const CWalletTx& wtx);
const uint256 txid; const uint256 txid;
uint256 bumpedTxid; uint256 bumpedTxid;
CMutableTransaction mtx; CMutableTransaction mtx;