Skip to content

Commit 5736d1d

Browse files
0xB10Csdaftuar
authored andcommitted
tracing: pass if replaced by tx/pkg to tracepoint
The mempool:replaced tracepoint now reports either a txid or a package hash (previously it always was a txid). To let users know if a txid or package hash is passed, a boolean argument is added the the tracepoint. In the functional test, a ctypes.Structure class for MempoolReplaced is introduced as Python warns the following when not explcitly casting it to a ctype: Type: 'bool' not recognized. Please define the data with ctypes manually.
1 parent a4ec07f commit 5736d1d

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed

doc/tracing.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -245,14 +245,15 @@ Arguments passed:
245245
2. Replaced transaction virtual size as `int32`
246246
3. Replaced transaction fee as `int64`
247247
4. Replaced transaction mempool entry time (epoch) as `uint64`
248-
5. Replacement transaction ID (hash) as `pointer to unsigned chars` (i.e. 32 bytes in little-endian)
248+
5. Replacement transaction ID or package hash as `pointer to unsigned chars` (i.e. 32 bytes in little-endian)
249249
6. Replacement transaction virtual size as `int32`
250250
7. Replacement transaction fee as `int64`
251+
8. `bool` indicating if the argument 5. is a transaction ID or package hash (true if it's a transaction ID)
251252

252-
Note: In cases where a single replacement transaction replaces multiple
253+
Note: In cases where a replacement transaction or package replaces multiple
253254
existing transactions in the mempool, the tracepoint is called once for each
254-
replaced transaction, with data of the replacement transaction being the same
255-
in each call.
255+
replaced transaction, with data of the replacement transaction or package
256+
being the same in each call.
256257

257258
#### Tracepoint `mempool:rejected`
258259

src/validation.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,8 @@ void MemPoolAccept::FinalizeSubpackage(const ATMPArgs& args)
12991299
it->GetTxSize());
13001300
FeeFrac feerate{m_subpackage.m_total_modified_fees, int32_t(m_subpackage.m_total_vsize)};
13011301
uint256 tx_or_package_hash{};
1302-
if (m_subpackage.m_changeset->GetTxCount() == 1) {
1302+
const bool replaced_with_tx{m_subpackage.m_changeset->GetTxCount() == 1};
1303+
if (replaced_with_tx) {
13031304
const CTransaction& tx = m_subpackage.m_changeset->GetAddedTxn(0);
13041305
tx_or_package_hash = tx.GetHash();
13051306
log_string += strprintf("New tx %s (wtxid=%s, fees=%s, vsize=%s)",
@@ -1324,7 +1325,8 @@ void MemPoolAccept::FinalizeSubpackage(const ATMPArgs& args)
13241325
std::chrono::duration_cast<std::chrono::duration<std::uint64_t>>(it->GetTime()).count(),
13251326
tx_or_package_hash.data(),
13261327
feerate.size,
1327-
feerate.fee
1328+
feerate.fee,
1329+
replaced_with_tx
13281330
);
13291331
m_subpackage.m_replaced_transactions.push_back(it->GetSharedTx());
13301332
}

test/functional/interface_usdt_mempool.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
See https://github.com/bitcoin/bitcoin/blob/master/doc/tracing.md#context-mempool
88
"""
99

10+
import ctypes
1011
from decimal import Decimal
1112

1213
# Test will be skipped if we don't have bcc installed
@@ -63,6 +64,7 @@
6364
u8 replacement_hash[HASH_LENGTH];
6465
s32 replacement_vsize;
6566
s64 replacement_fee;
67+
bool replaced_by_transaction;
6668
};
6769
6870
// BPF perf buffer to push the data to user space.
@@ -115,6 +117,7 @@
115117
bpf_usdt_readarg_p(5, ctx, &replaced.replacement_hash, HASH_LENGTH);
116118
bpf_usdt_readarg(6, ctx, &replaced.replacement_vsize);
117119
bpf_usdt_readarg(7, ctx, &replaced.replacement_fee);
120+
bpf_usdt_readarg(8, ctx, &replaced.replaced_by_transaction);
118121
119122
replaced_events.perf_submit(ctx, &replaced, sizeof(replaced));
120123
return 0;
@@ -123,6 +126,19 @@
123126
"""
124127

125128

129+
class MempoolReplaced(ctypes.Structure):
130+
_fields_ = [
131+
("replaced_hash", ctypes.c_ubyte * 32),
132+
("replaced_vsize", ctypes.c_int32),
133+
("replaced_fee", ctypes.c_int64),
134+
("replaced_entry_time", ctypes.c_uint64),
135+
("replacement_hash", ctypes.c_ubyte * 32),
136+
("replacement_vsize", ctypes.c_int32),
137+
("replacement_fee", ctypes.c_int64),
138+
("replaced_by_transaction", ctypes.c_bool),
139+
]
140+
141+
126142
class MempoolTracepointTest(BitcoinTestFramework):
127143
def set_test_params(self):
128144
self.num_nodes = 1
@@ -230,7 +246,8 @@ def replaced_test(self):
230246
bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"])
231247

232248
def handle_replaced_event(_, data, __):
233-
events.append(bpf["replaced_events"].event(data))
249+
event = ctypes.cast(data, ctypes.POINTER(MempoolReplaced)).contents
250+
events.append(event)
234251

235252
bpf["replaced_events"].open_perf_buffer(handle_replaced_event)
236253

@@ -261,6 +278,7 @@ def handle_replaced_event(_, data, __):
261278
assert_equal(bytes(event.replacement_hash)[::-1].hex(), replacement_tx["txid"])
262279
assert_equal(event.replacement_vsize, replacement_tx["tx"].get_vsize())
263280
assert_equal(event.replacement_fee, replacement_fee)
281+
assert_equal(event.replaced_by_transaction, True)
264282

265283
bpf.cleanup()
266284
self.generate(self.wallet, 1)

0 commit comments

Comments
 (0)