Merge bitcoin/bitcoin#34020: mining: add getTransactions(ByWitnessID) IPC methods

9784818442 mining: add getTransactionsByWitnessID() IPC method (Sjors Provoost)
d282ae6883 mining: add getTransactionsByTxID() IPC method (Sjors Provoost)
0d5e4d4712 test: restart node after IPC option override test (Sjors Provoost)
f16b3613cd ipc: Serialize null CTransactionRef as empty Data (Sjors Provoost)
0f466e1094 mempool: add lookup by witness hash (Sjors Provoost)

Pull request description:

  For Stratum v2 custom job declaration to be bandwidth efficient, the pool can request[^0] only the transactions that it doesn't know about.

  The spec doesn't specify how this is achieved, but one method is to call the `getrawtransaction` RPC on each transaction id listed in [DeclareMiningJob](https://stratumprotocol.org/specification/06-Job-Declaration-Protocol?query=DeclareMiningJob#644-declareminingjob-client-server) (or a subset if the pool software maintains a cache). Using RPC is inefficient, made worse by the need to make multiple calls. It also doesn't support queuing by witness id (yet, see #34013).

  This PR introduces two new IPC methods:

  - `getTransactionsById()`: takes a list of `Txid`'s
  - `getTransactionsByWitnessID()`: : takes a list of `Wtxid`'s

  Both return a list of serialised transactions. An empty element is returned for transactions that were not found.

  Unlike the RPC counterpart, the IPC methods do not take advantage of `-txindex`. This could be done in a followup. For `Wtxid` that would involve adding a `-witnesstxindex`.

  I thought about having a single (or overloaded) `getTransactions()` that works with both `Txid` and `Wtxid`, but I prefer that clients are intentional about which one they want.

  A unit and functional test cover the new functionality.

  Sv2 probably only needs `getTransactionsByWitnessID()`, but it's easy enough to just add both.

  To rest with Rust use:
  - https://github.com/2140-dev/bitcoin-capnp-types/pull/11

  [^0]: there's two reasons the pool requests these transactions: to approve the template and to broadcast the block if a solution is found (the miner will also broadcast via their template provider). See also https://github.com/stratum-mining/sv2-spec/issues/170

ACKs for top commit:
  achow101:
    ACK 9784818442
  sedited:
    Re-ACK 9784818442
  ViniciusCestarii:
    Re-ACK  9784818442
  ismaelsadeeq:
    Code review ACK 9784818442

Tree-SHA512: 3c6ceb572ab7d8bd090a8f31b5e331304a7a19a3d1f1551c9c2e1ee41339d76f96ca6c41bd634c87fca0a969e7d9bfa6a16c26fb06c0dd2315f6ca1c76a16a31
This commit is contained in:
Ava Chow
2026-07-07 14:29:10 -07:00
13 changed files with 202 additions and 5 deletions

View File

@@ -919,6 +919,7 @@ public:
bool submitSolution(uint32_t version, uint32_t timestamp, uint32_t nonce, CTransactionRef coinbase) override
{
if (!coinbase) return false;
AddMerkleRootAndCoinbase(m_block_template->block, std::move(coinbase), version, timestamp, nonce);
std::string reason;
std::string debug;
@@ -1034,6 +1035,32 @@ public:
return accepted && new_block && reason.empty();
}
std::vector<CTransactionRef> getTransactionsByTxID(const std::vector<Txid>& txids) override
{
if (!m_node.mempool) return {};
std::vector<CTransactionRef> results;
results.reserve(txids.size());
LOCK(m_node.mempool->cs);
for (const auto& txid : txids) {
results.emplace_back(m_node.mempool->get(txid));
}
return results;
}
std::vector<CTransactionRef> getTransactionsByWitnessID(const std::vector<Wtxid>& wtxids) override
{
if (!m_node.mempool) return {};
std::vector<CTransactionRef> results;
results.reserve(wtxids.size());
LOCK(m_node.mempool->cs);
for (const auto& wtxid : wtxids) {
results.emplace_back(m_node.mempool->get(wtxid));
}
return results;
}
const NodeContext* context() override { return &m_node; }
ChainstateManager& chainman() { return *Assert(m_node.chainman); }
KernelNotifications& notifications() { return *Assert(m_node.notifications); }