Refactor IsRBFOptIn, avoid exception

This commit is contained in:
Jonas Schnelli 2016-04-05 14:20:49 +02:00
parent a9149688f8
commit 4f7c959af1
No known key found for this signature in database
GPG Key ID: 29D4BCB6416F53EC
3 changed files with 19 additions and 16 deletions

View File

@ -14,33 +14,34 @@ bool SignalsOptInRBF(const CTransaction &tx)
return false; return false;
} }
bool IsRBFOptIn(const CTxMemPoolEntry &entry, CTxMemPool &pool) RBFTransactionState IsRBFOptIn(const CTransaction &tx, CTxMemPool &pool)
{ {
AssertLockHeld(pool.cs); AssertLockHeld(pool.cs);
CTxMemPool::setEntries setAncestors; CTxMemPool::setEntries setAncestors;
// First check the transaction itself. // First check the transaction itself.
if (SignalsOptInRBF(entry.GetTx())) { if (SignalsOptInRBF(tx)) {
return true; return RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125;
} }
// If this transaction is not in our mempool, then we can't be sure // If this transaction is not in our mempool, then we can't be sure
// we will know about all its inputs. // we will know about all its inputs.
if (!pool.exists(entry.GetTx().GetHash())) { if (!pool.exists(tx.GetHash())) {
throw std::runtime_error("Cannot determine RBF opt-in signal for non-mempool transaction\n"); return RBF_TRANSACTIONSTATE_UNKNOWN;
} }
// If all the inputs have nSequence >= maxint-1, it still might be // If all the inputs have nSequence >= maxint-1, it still might be
// signaled for RBF if any unconfirmed parents have signaled. // signaled for RBF if any unconfirmed parents have signaled.
uint64_t noLimit = std::numeric_limits<uint64_t>::max(); uint64_t noLimit = std::numeric_limits<uint64_t>::max();
std::string dummy; std::string dummy;
CTxMemPoolEntry entry = *pool.mapTx.find(tx.GetHash());
pool.CalculateMemPoolAncestors(entry, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false); pool.CalculateMemPoolAncestors(entry, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false);
BOOST_FOREACH(CTxMemPool::txiter it, setAncestors) { BOOST_FOREACH(CTxMemPool::txiter it, setAncestors) {
if (SignalsOptInRBF(it->GetTx())) { if (SignalsOptInRBF(it->GetTx())) {
return true; return RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125;
} }
} }
return false; return RBF_TRANSACTIONSTATE_FINAL;
} }

View File

@ -7,6 +7,12 @@
#include "txmempool.h" #include "txmempool.h"
enum RBFTransactionState {
RBF_TRANSACTIONSTATE_UNKNOWN,
RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125,
RBF_TRANSACTIONSTATE_FINAL
};
// Check whether the sequence numbers on this transaction are signaling // Check whether the sequence numbers on this transaction are signaling
// opt-in to replace-by-fee, according to BIP 125 // opt-in to replace-by-fee, according to BIP 125
bool SignalsOptInRBF(const CTransaction &tx); bool SignalsOptInRBF(const CTransaction &tx);
@ -15,6 +21,6 @@ bool SignalsOptInRBF(const CTransaction &tx);
// according to BIP 125 // according to BIP 125
// This involves checking sequence numbers of the transaction, as well // This involves checking sequence numbers of the transaction, as well
// as the sequence numbers of all in-mempool ancestors. // as the sequence numbers of all in-mempool ancestors.
bool IsRBFOptIn(const CTxMemPoolEntry &entry, CTxMemPool &pool); RBFTransactionState IsRBFOptIn(const CTransaction &tx, CTxMemPool &pool);
#endif // BITCOIN_POLICY_RBF_H #endif // BITCOIN_POLICY_RBF_H

View File

@ -82,15 +82,11 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
std::string rbfStatus = "no"; std::string rbfStatus = "no";
if (confirms <= 0) { if (confirms <= 0) {
LOCK(mempool.cs); LOCK(mempool.cs);
if (!mempool.exists(hash)) { RBFTransactionState rbfState = IsRBFOptIn(wtx, mempool);
if (SignalsOptInRBF(wtx)) { if (rbfState == RBF_TRANSACTIONSTATE_UNKNOWN)
rbfStatus = "yes"; rbfStatus = "unknown";
} else { else if (rbfState == RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125)
rbfStatus = "unknown";
}
} else if (IsRBFOptIn(*mempool.mapTx.find(hash), mempool)) {
rbfStatus = "yes"; rbfStatus = "yes";
}
} }
entry.push_back(Pair("bip125-replaceable", rbfStatus)); entry.push_back(Pair("bip125-replaceable", rbfStatus));