Skip to content

Commit a626172

Browse files
committed
mining: add getTransactionsByWitnessID() IPC method
1 parent cf0b427 commit a626172

File tree

6 files changed

+49
-3
lines changed

6 files changed

+49
-3
lines changed

src/interfaces/mining.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,15 @@ class Mining
163163
* transaction if found, otherwise nullptr
164164
*/
165165
virtual std::vector<CTransactionRef> getTransactionsByTxID(const std::vector<Txid>& txids) = 0;
166+
167+
/**
168+
* Fetch raw transactions from the mempool by wtxid.
169+
*
170+
* @param[in] wtxids witness transaction ids to look up
171+
* @returns one entry per requested wtxid containing the
172+
* transaction if found, otherwise nullptr
173+
*/
174+
virtual std::vector<CTransactionRef> getTransactionsByWitnessID(const std::vector<Wtxid>& wtxids) = 0;
166175
//! Get internal node context. Useful for RPC and testing,
167176
//! but not accessible across processes.
168177
virtual node::NodeContext* context() { return nullptr; }

src/ipc/capnp/mining.capnp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ interface Mining $Proxy.wrap("interfaces::Mining") {
2626
checkBlock @5 (context :Proxy.Context, block: Data, options: BlockCheckOptions) -> (reason: Text, debug: Text, result: Bool);
2727
interrupt @6 () -> ();
2828
getTransactionsByTxID @7 (context :Proxy.Context, txids: List(Data)) -> (result: List(Data));
29+
getTransactionsByWitnessID @8 (context :Proxy.Context, wtxids: List(Data)) -> (result: List(Data));
2930
}
3031

3132
interface BlockTemplate $Proxy.wrap("interfaces::BlockTemplate") {

src/node/interfaces.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,19 @@ class MinerImpl : public Mining
10261026
return results;
10271027
}
10281028

1029+
std::vector<CTransactionRef> getTransactionsByWitnessID(const std::vector<Wtxid>& wtxids) override
1030+
{
1031+
if (!m_node.mempool) return {};
1032+
LOCK(m_node.mempool->cs);
1033+
1034+
std::vector<CTransactionRef> results;
1035+
results.reserve(wtxids.size());
1036+
for (const auto& wtxid : wtxids) {
1037+
results.emplace_back(GetTransaction(*m_node.mempool, wtxid));
1038+
}
1039+
return results;
1040+
}
1041+
10291042
NodeContext* context() override { return &m_node; }
10301043
ChainstateManager& chainman() { return *Assert(m_node.chainman); }
10311044
KernelNotifications& notifications() { return *Assert(m_node.notifications); }

src/test/miner_tests.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,17 @@ void MinerTestingSetup::TestPackageSelection(const CScript& scriptPubKey, const
177177
BOOST_CHECK(raw_txs[0]);
178178
BOOST_CHECK(raw_txs[0]->GetHash() == hashParentTx);
179179
BOOST_CHECK(!raw_txs[1]);
180+
// Test getTransactionsByWitnessID()
181+
// tx has no witness, so just cast to Wtxid
182+
const std::vector<Wtxid> wtx_id_list{
183+
Wtxid::FromUint256(hashParentTx.ToUint256()),
184+
Wtxid::FromUint256(uint256::ZERO)
185+
};
186+
raw_txs = mining->getTransactionsByWitnessID(wtx_id_list);
187+
BOOST_REQUIRE_EQUAL(raw_txs.size(), tx_id_list.size());
188+
BOOST_CHECK(raw_txs[0]);
189+
BOOST_CHECK(raw_txs[0]->GetHash() == hashParentTx);
190+
BOOST_CHECK(!raw_txs[1]);
180191
block_template = mining->createNewBlock(options, /*cooldown=*/false);
181192
BOOST_REQUIRE(block_template);
182193
block = block_template->getBlock();

test/functional/interface_ipc_mining.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ async def async_routine():
415415
asyncio.run(capnp.run(async_routine()))
416416

417417
def run_transaction_lookup_test(self):
418-
"""Test getTransactionsByTxID()."""
418+
"""Test getTransactionsByTxID() and getTransactionsByWitnessID()."""
419419
self.log.info("Running transaction lookup test")
420420

421421
async def async_routine():
@@ -430,6 +430,13 @@ async def async_routine():
430430
assert_equal(raw_txs_txid.result[1].hex(), tx2["hex"])
431431
assert_equal(raw_txs_txid.result[2], b'')
432432

433+
self.log.debug("getTransactionsByWitnessID() returns mempool txs and nulls")
434+
raw_txs_wtxid = await mining.getTransactionsByWitnessID(ctx, [tx1["tx"].wtxid, tx2["tx"].wtxid, bytes(32)])
435+
assert_equal(len(raw_txs_wtxid.result), 3)
436+
assert_equal(raw_txs_wtxid.result[0].hex(), tx1["hex"])
437+
assert_equal(raw_txs_wtxid.result[1].hex(), tx2["hex"])
438+
assert_equal(raw_txs_wtxid.result[2], b'')
439+
433440
self.log.debug("getTransactionsByTxID() uses txindex when enabled")
434441
self.generate(self.nodes[0], 1)
435442
self.sync_all()

test/functional/test_framework/messages.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -686,15 +686,20 @@ def serialize_with_witness(self):
686686
def serialize(self):
687687
return self.serialize_with_witness()
688688

689+
@property
690+
def wtxid(self):
691+
"""Return wtxid (transaction hash with witness) as little-endian bytes."""
692+
return hash256(self.serialize_with_witness())
693+
689694
@property
690695
def wtxid_hex(self):
691696
"""Return wtxid (transaction hash with witness) as hex string."""
692-
return hash256(self.serialize())[::-1].hex()
697+
return self.wtxid[::-1].hex()
693698

694699
@property
695700
def wtxid_int(self):
696701
"""Return wtxid (transaction hash with witness) as integer."""
697-
return uint256_from_str(hash256(self.serialize_with_witness()))
702+
return uint256_from_str(self.wtxid)
698703

699704
@property
700705
def txid(self):

0 commit comments

Comments
 (0)