Skip to content

Commit

Permalink
tracing: pass if replaced by tx/pkg to tracepoint
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
0xB10C authored and sdaftuar committed Nov 13, 2024
1 parent a4ec07f commit 5736d1d
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 7 deletions.
9 changes: 5 additions & 4 deletions doc/tracing.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,14 +245,15 @@ Arguments passed:
2. Replaced transaction virtual size as `int32`
3. Replaced transaction fee as `int64`
4. Replaced transaction mempool entry time (epoch) as `uint64`
5. Replacement transaction ID (hash) as `pointer to unsigned chars` (i.e. 32 bytes in little-endian)
5. Replacement transaction ID or package hash as `pointer to unsigned chars` (i.e. 32 bytes in little-endian)
6. Replacement transaction virtual size as `int32`
7. Replacement transaction fee as `int64`
8. `bool` indicating if the argument 5. is a transaction ID or package hash (true if it's a transaction ID)

Note: In cases where a single replacement transaction replaces multiple
Note: In cases where a replacement transaction or package replaces multiple
existing transactions in the mempool, the tracepoint is called once for each
replaced transaction, with data of the replacement transaction being the same
in each call.
replaced transaction, with data of the replacement transaction or package
being the same in each call.

#### Tracepoint `mempool:rejected`

Expand Down
6 changes: 4 additions & 2 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1299,7 +1299,8 @@ void MemPoolAccept::FinalizeSubpackage(const ATMPArgs& args)
it->GetTxSize());
FeeFrac feerate{m_subpackage.m_total_modified_fees, int32_t(m_subpackage.m_total_vsize)};
uint256 tx_or_package_hash{};
if (m_subpackage.m_changeset->GetTxCount() == 1) {
const bool replaced_with_tx{m_subpackage.m_changeset->GetTxCount() == 1};
if (replaced_with_tx) {
const CTransaction& tx = m_subpackage.m_changeset->GetAddedTxn(0);
tx_or_package_hash = tx.GetHash();
log_string += strprintf("New tx %s (wtxid=%s, fees=%s, vsize=%s)",
Expand All @@ -1324,7 +1325,8 @@ void MemPoolAccept::FinalizeSubpackage(const ATMPArgs& args)
std::chrono::duration_cast<std::chrono::duration<std::uint64_t>>(it->GetTime()).count(),
tx_or_package_hash.data(),
feerate.size,
feerate.fee
feerate.fee,
replaced_with_tx
);
m_subpackage.m_replaced_transactions.push_back(it->GetSharedTx());
}
Expand Down
20 changes: 19 additions & 1 deletion test/functional/interface_usdt_mempool.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
See https://github.com/bitcoin/bitcoin/blob/master/doc/tracing.md#context-mempool
"""

import ctypes
from decimal import Decimal

# Test will be skipped if we don't have bcc installed
Expand Down Expand Up @@ -63,6 +64,7 @@
u8 replacement_hash[HASH_LENGTH];
s32 replacement_vsize;
s64 replacement_fee;
bool replaced_by_transaction;
};
// BPF perf buffer to push the data to user space.
Expand Down Expand Up @@ -115,6 +117,7 @@
bpf_usdt_readarg_p(5, ctx, &replaced.replacement_hash, HASH_LENGTH);
bpf_usdt_readarg(6, ctx, &replaced.replacement_vsize);
bpf_usdt_readarg(7, ctx, &replaced.replacement_fee);
bpf_usdt_readarg(8, ctx, &replaced.replaced_by_transaction);
replaced_events.perf_submit(ctx, &replaced, sizeof(replaced));
return 0;
Expand All @@ -123,6 +126,19 @@
"""


class MempoolReplaced(ctypes.Structure):
_fields_ = [
("replaced_hash", ctypes.c_ubyte * 32),
("replaced_vsize", ctypes.c_int32),
("replaced_fee", ctypes.c_int64),
("replaced_entry_time", ctypes.c_uint64),
("replacement_hash", ctypes.c_ubyte * 32),
("replacement_vsize", ctypes.c_int32),
("replacement_fee", ctypes.c_int64),
("replaced_by_transaction", ctypes.c_bool),
]


class MempoolTracepointTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
Expand Down Expand Up @@ -230,7 +246,8 @@ def replaced_test(self):
bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0, cflags=["-Wno-error=implicit-function-declaration"])

def handle_replaced_event(_, data, __):
events.append(bpf["replaced_events"].event(data))
event = ctypes.cast(data, ctypes.POINTER(MempoolReplaced)).contents
events.append(event)

bpf["replaced_events"].open_perf_buffer(handle_replaced_event)

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

bpf.cleanup()
self.generate(self.wallet, 1)
Expand Down

0 comments on commit 5736d1d

Please sign in to comment.