Skip to content

Commit a7ebe48

Browse files
committed
[rpc] add unbroadcast info to mempool entries and getmempoolinfo
- expose info about number of txns in unbroadcast set and whether a mempool entry's tx has passed initial broadcast - makes rpcs more informative and allows for more explicit testing, eg tracking if tx is in unbroadcast set before and after originating node connects to peers (adds this in mempool_unbroadcast.py) - adds mempool method IsUnbroadcastTx to query for tx inclusion in mempool's unbroadcast set
1 parent d160069 commit a7ebe48

File tree

4 files changed

+26
-1
lines changed

4 files changed

+26
-1
lines changed

src/rpc/blockchain.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ static std::vector<RPCResult> MempoolEntryDescription() { return {
399399
RPCResult{RPCResult::Type::ARR, "spentby", "unconfirmed transactions spending outputs from this transaction",
400400
{RPCResult{RPCResult::Type::STR_HEX, "transactionid", "child transaction id"}}},
401401
RPCResult{RPCResult::Type::BOOL, "bip125-replaceable", "Whether this transaction could be replaced due to BIP125 (replace-by-fee)"},
402+
RPCResult{RPCResult::Type::BOOL, "unbroadcast", "Whether this transaction is currently unbroadcast (initial broadcast not yet confirmed)"},
402403
};}
403404

404405
static void entryToJSON(const CTxMemPool& pool, UniValue& info, const CTxMemPoolEntry& e) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
@@ -460,6 +461,7 @@ static void entryToJSON(const CTxMemPool& pool, UniValue& info, const CTxMemPool
460461
}
461462

462463
info.pushKV("bip125-replaceable", rbfStatus);
464+
info.pushKV("unbroadcast", pool.IsUnbroadcastTx(tx.GetHash()));
463465
}
464466

465467
UniValue MempoolToJSON(const CTxMemPool& pool, bool verbose)
@@ -1389,7 +1391,7 @@ UniValue MempoolInfoToJSON(const CTxMemPool& pool)
13891391
ret.pushKV("maxmempool", (int64_t) maxmempool);
13901392
ret.pushKV("mempoolminfee", ValueFromAmount(std::max(pool.GetMinFee(maxmempool), ::minRelayTxFee).GetFeePerK()));
13911393
ret.pushKV("minrelaytxfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()));
1392-
1394+
ret.pushKV("unbroadcastcount", uint64_t{pool.GetUnbroadcastTxs().size()});
13931395
return ret;
13941396
}
13951397

@@ -1408,6 +1410,7 @@ static UniValue getmempoolinfo(const JSONRPCRequest& request)
14081410
{RPCResult::Type::NUM, "maxmempool", "Maximum memory usage for the mempool"},
14091411
{RPCResult::Type::STR_AMOUNT, "mempoolminfee", "Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee"},
14101412
{RPCResult::Type::STR_AMOUNT, "minrelaytxfee", "Current minimum relay fee for transactions"},
1413+
{RPCResult::Type::NUM, "unbroadcastcount", "Current number of transactions that haven't passed initial broadcast yet"}
14111414
}},
14121415
RPCExamples{
14131416
HelpExampleCli("getmempoolinfo", "")

src/txmempool.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,12 @@ class CTxMemPool
716716
return m_unbroadcast_txids;
717717
}
718718

719+
// Returns if a txid is in the unbroadcast set
720+
bool IsUnbroadcastTx(const uint256& txid) const {
721+
LOCK(cs);
722+
return (m_unbroadcast_txids.count(txid) != 0);
723+
}
724+
719725
private:
720726
/** UpdateForDescendants is used by UpdateTransactionsFromBlock to update
721727
* the descendants for a single transaction that has been added to the

test/functional/mempool_packages.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,10 @@ def run_test(self):
212212
for tx in chain[:MAX_ANCESTORS_CUSTOM]:
213213
assert tx in mempool1
214214
# TODO: more detailed check of node1's mempool (fees etc.)
215+
# check transaction unbroadcast info (should be false if in both mempools)
216+
mempool = self.nodes[0].getrawmempool(True)
217+
for tx in mempool:
218+
assert_equal(mempool[tx]['unbroadcast'], False)
215219

216220
# TODO: test ancestor size limits
217221

test/functional/mempool_unbroadcast.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ def test_broadcast(self):
5353
txFS = node.signrawtransactionwithwallet(txF["hex"])
5454
rpc_tx_hsh = node.sendrawtransaction(txFS["hex"])
5555

56+
# check transactions are in unbroadcast using rpc
57+
mempoolinfo = self.nodes[0].getmempoolinfo()
58+
assert_equal(mempoolinfo['unbroadcastcount'], 2)
59+
mempool = self.nodes[0].getrawmempool(True)
60+
for tx in mempool:
61+
assert_equal(mempool[tx]['unbroadcast'], True)
62+
5663
# check that second node doesn't have these two txns
5764
mempool = self.nodes[1].getrawmempool()
5865
assert rpc_tx_hsh not in mempool
@@ -71,6 +78,11 @@ def test_broadcast(self):
7178
assert rpc_tx_hsh in mempool
7279
assert wallet_tx_hsh in mempool
7380

81+
# check that transactions are no longer in first node's unbroadcast set
82+
mempool = self.nodes[0].getrawmempool(True)
83+
for tx in mempool:
84+
assert_equal(mempool[tx]['unbroadcast'], False)
85+
7486
self.log.info("Add another connection & ensure transactions aren't broadcast again")
7587

7688
conn = node.add_p2p_connection(P2PTxInvStore())

0 commit comments

Comments
 (0)