mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-14 12:43:40 +02:00
Merge a7261da479 into merged_master (Bitcoin PR bitcoin/bitcoin#27831)
This commit is contained in:
commit
c75f3a8fa0
4 changed files with 88 additions and 90 deletions
|
|
@ -139,6 +139,7 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
|||
|
||||
EXPECTED_ADDED_EVENTS = 1
|
||||
handled_added_events = 0
|
||||
event = None
|
||||
|
||||
self.log.info("Hooking into mempool:added tracepoint...")
|
||||
node = self.nodes[0]
|
||||
|
|
@ -147,11 +148,8 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
|||
bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0)
|
||||
|
||||
def handle_added_event(_, data, __):
|
||||
nonlocal handled_added_events
|
||||
nonlocal event, handled_added_events
|
||||
event = bpf["added_events"].event(data)
|
||||
assert_equal(txid, bytes(event.hash)[::-1].hex())
|
||||
assert_equal(vsize, event.vsize)
|
||||
assert_equal(fee, event.fee)
|
||||
handled_added_events += 1
|
||||
|
||||
bpf["added_events"].open_perf_buffer(handle_added_event)
|
||||
|
|
@ -159,9 +157,6 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
|||
self.log.info("Sending transaction...")
|
||||
fee = Decimal(31200)
|
||||
tx = self.wallet.send_self_transfer(from_node=node, fee=fee / COIN)
|
||||
# expected data
|
||||
txid = tx["txid"]
|
||||
vsize = tx["tx"].get_vsize()
|
||||
|
||||
self.log.info("Polling buffer...")
|
||||
bpf.perf_buffer_poll(timeout=200)
|
||||
|
|
@ -169,10 +164,13 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
|||
self.log.info("Cleaning up mempool...")
|
||||
self.generate(node, 1)
|
||||
|
||||
bpf.cleanup()
|
||||
|
||||
self.log.info("Ensuring mempool:added event was handled successfully...")
|
||||
assert_equal(EXPECTED_ADDED_EVENTS, handled_added_events)
|
||||
assert_equal(bytes(event.hash)[::-1].hex(), tx["txid"])
|
||||
assert_equal(event.vsize, tx["tx"].get_vsize())
|
||||
assert_equal(event.fee, fee)
|
||||
|
||||
bpf.cleanup()
|
||||
self.generate(self.wallet, 1)
|
||||
|
||||
def removed_test(self):
|
||||
|
|
@ -181,6 +179,7 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
|||
|
||||
EXPECTED_REMOVED_EVENTS = 1
|
||||
handled_removed_events = 0
|
||||
event = None
|
||||
|
||||
self.log.info("Hooking into mempool:removed tracepoint...")
|
||||
node = self.nodes[0]
|
||||
|
|
@ -189,13 +188,8 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
|||
bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0)
|
||||
|
||||
def handle_removed_event(_, data, __):
|
||||
nonlocal handled_removed_events
|
||||
nonlocal event, handled_removed_events
|
||||
event = bpf["removed_events"].event(data)
|
||||
assert_equal(txid, bytes(event.hash)[::-1].hex())
|
||||
assert_equal(reason, event.reason.decode("UTF-8"))
|
||||
assert_equal(vsize, event.vsize)
|
||||
assert_equal(fee, event.fee)
|
||||
assert_equal(entry_time, event.entry_time)
|
||||
handled_removed_events += 1
|
||||
|
||||
bpf["removed_events"].open_perf_buffer(handle_removed_event)
|
||||
|
|
@ -203,10 +197,7 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
|||
self.log.info("Sending transaction...")
|
||||
fee = Decimal(31200)
|
||||
tx = self.wallet.send_self_transfer(from_node=node, fee=fee / COIN)
|
||||
# expected data
|
||||
txid = tx["txid"]
|
||||
reason = "expiry"
|
||||
vsize = tx["tx"].get_vsize()
|
||||
|
||||
self.log.info("Fast-forwarding time to mempool expiry...")
|
||||
entry_time = node.getmempoolentry(txid)["time"]
|
||||
|
|
@ -220,10 +211,15 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
|||
self.log.info("Polling buffer...")
|
||||
bpf.perf_buffer_poll(timeout=200)
|
||||
|
||||
bpf.cleanup()
|
||||
|
||||
self.log.info("Ensuring mempool:removed event was handled successfully...")
|
||||
assert_equal(EXPECTED_REMOVED_EVENTS, handled_removed_events)
|
||||
assert_equal(bytes(event.hash)[::-1].hex(), txid)
|
||||
assert_equal(event.reason.decode("UTF-8"), "expiry")
|
||||
assert_equal(event.vsize, tx["tx"].get_vsize())
|
||||
assert_equal(event.fee, fee)
|
||||
assert_equal(event.entry_time, entry_time)
|
||||
|
||||
bpf.cleanup()
|
||||
self.generate(self.wallet, 1)
|
||||
|
||||
def replaced_test(self):
|
||||
|
|
@ -232,6 +228,7 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
|||
|
||||
EXPECTED_REPLACED_EVENTS = 1
|
||||
handled_replaced_events = 0
|
||||
event = None
|
||||
|
||||
self.log.info("Hooking into mempool:replaced tracepoint...")
|
||||
node = self.nodes[0]
|
||||
|
|
@ -240,15 +237,8 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
|||
bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0)
|
||||
|
||||
def handle_replaced_event(_, data, __):
|
||||
nonlocal handled_replaced_events
|
||||
nonlocal event, handled_replaced_events
|
||||
event = bpf["replaced_events"].event(data)
|
||||
assert_equal(replaced_txid, bytes(event.replaced_hash)[::-1].hex())
|
||||
assert_equal(replaced_vsize, event.replaced_vsize)
|
||||
assert_equal(replaced_fee, event.replaced_fee)
|
||||
assert_equal(replaced_entry_time, event.replaced_entry_time)
|
||||
assert_equal(replacement_txid, bytes(event.replacement_hash)[::-1].hex())
|
||||
assert_equal(replacement_vsize, event.replacement_vsize)
|
||||
assert_equal(replacement_fee, event.replacement_fee)
|
||||
handled_replaced_events += 1
|
||||
|
||||
bpf["replaced_events"].open_perf_buffer(handle_replaced_event)
|
||||
|
|
@ -267,21 +257,20 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
|||
from_node=node, utxo_to_spend=utxo, fee=replacement_fee / COIN
|
||||
)
|
||||
|
||||
# expected data
|
||||
replaced_txid = original_tx["txid"]
|
||||
replaced_vsize = original_tx["tx"].get_vsize()
|
||||
replaced_fee = original_fee
|
||||
replaced_entry_time = entry_time
|
||||
replacement_txid = replacement_tx["txid"]
|
||||
replacement_vsize = replacement_tx["tx"].get_vsize()
|
||||
|
||||
self.log.info("Polling buffer...")
|
||||
bpf.perf_buffer_poll(timeout=200)
|
||||
|
||||
bpf.cleanup()
|
||||
|
||||
self.log.info("Ensuring mempool:replaced event was handled successfully...")
|
||||
assert_equal(EXPECTED_REPLACED_EVENTS, handled_replaced_events)
|
||||
assert_equal(bytes(event.replaced_hash)[::-1].hex(), original_tx["txid"])
|
||||
assert_equal(event.replaced_vsize, original_tx["tx"].get_vsize())
|
||||
assert_equal(event.replaced_fee, original_fee)
|
||||
assert_equal(event.replaced_entry_time, entry_time)
|
||||
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)
|
||||
|
||||
bpf.cleanup()
|
||||
self.generate(self.wallet, 1)
|
||||
|
||||
def rejected_test(self):
|
||||
|
|
@ -290,6 +279,7 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
|||
|
||||
EXPECTED_REJECTED_EVENTS = 1
|
||||
handled_rejected_events = 0
|
||||
event = None
|
||||
|
||||
self.log.info("Adding P2P connection...")
|
||||
node = self.nodes[0]
|
||||
|
|
@ -301,10 +291,8 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
|||
bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0)
|
||||
|
||||
def handle_rejected_event(_, data, __):
|
||||
nonlocal handled_rejected_events
|
||||
nonlocal event, handled_rejected_events
|
||||
event = bpf["rejected_events"].event(data)
|
||||
assert_equal(txid, bytes(event.hash)[::-1].hex())
|
||||
assert_equal(reason, event.reason.decode("UTF-8"))
|
||||
handled_rejected_events += 1
|
||||
|
||||
bpf["rejected_events"].open_perf_buffer(handle_rejected_event)
|
||||
|
|
@ -313,17 +301,15 @@ class MempoolTracepointTest(BitcoinTestFramework):
|
|||
tx = self.wallet.create_self_transfer(fee_rate=Decimal(0))
|
||||
node.p2ps[0].send_txs_and_test([tx["tx"]], node, success=False)
|
||||
|
||||
# expected data
|
||||
txid = tx["tx"].hash
|
||||
reason = "min relay fee not met"
|
||||
|
||||
self.log.info("Polling buffer...")
|
||||
bpf.perf_buffer_poll(timeout=200)
|
||||
|
||||
bpf.cleanup()
|
||||
|
||||
self.log.info("Ensuring mempool:rejected event was handled successfully...")
|
||||
assert_equal(EXPECTED_REJECTED_EVENTS, handled_rejected_events)
|
||||
assert_equal(bytes(event.hash)[::-1].hex(), tx["tx"].hash)
|
||||
assert_equal(event.reason.decode("UTF-8"), "min relay fee not met")
|
||||
|
||||
bpf.cleanup()
|
||||
self.generate(self.wallet, 1)
|
||||
|
||||
def run_test(self):
|
||||
|
|
|
|||
|
|
@ -116,13 +116,10 @@ class NetTracepointTest(BitcoinTestFramework):
|
|||
fn_name="trace_outbound_message")
|
||||
bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0)
|
||||
|
||||
# The handle_* function is a ctypes callback function called from C. When
|
||||
# we assert in the handle_* function, the AssertError doesn't propagate
|
||||
# back to Python. The exception is ignored. We manually count and assert
|
||||
# that the handle_* functions succeeded.
|
||||
EXPECTED_INOUTBOUND_VERSION_MSG = 1
|
||||
checked_inbound_version_msg = 0
|
||||
checked_outbound_version_msg = 0
|
||||
events = []
|
||||
|
||||
def check_p2p_message(event, inbound):
|
||||
nonlocal checked_inbound_version_msg, checked_outbound_version_msg
|
||||
|
|
@ -142,12 +139,13 @@ class NetTracepointTest(BitcoinTestFramework):
|
|||
checked_outbound_version_msg += 1
|
||||
|
||||
def handle_inbound(_, data, __):
|
||||
nonlocal events
|
||||
event = ctypes.cast(data, ctypes.POINTER(P2PMessage)).contents
|
||||
check_p2p_message(event, True)
|
||||
events.append((event, True))
|
||||
|
||||
def handle_outbound(_, data, __):
|
||||
event = ctypes.cast(data, ctypes.POINTER(P2PMessage)).contents
|
||||
check_p2p_message(event, False)
|
||||
events.append((event, False))
|
||||
|
||||
bpf["inbound_messages"].open_perf_buffer(handle_inbound)
|
||||
bpf["outbound_messages"].open_perf_buffer(handle_outbound)
|
||||
|
|
@ -158,12 +156,15 @@ class NetTracepointTest(BitcoinTestFramework):
|
|||
bpf.perf_buffer_poll(timeout=200)
|
||||
|
||||
self.log.info(
|
||||
"check that we got both an inbound and outbound version message")
|
||||
"check receipt and content of in- and outbound version messages")
|
||||
for event, inbound in events:
|
||||
check_p2p_message(event, inbound)
|
||||
assert_equal(EXPECTED_INOUTBOUND_VERSION_MSG,
|
||||
checked_inbound_version_msg)
|
||||
assert_equal(EXPECTED_INOUTBOUND_VERSION_MSG,
|
||||
checked_outbound_version_msg)
|
||||
|
||||
|
||||
bpf.cleanup()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -188,13 +188,16 @@ class UTXOCacheTracepointTest(BitcoinTestFramework):
|
|||
nonlocal handle_uncache_succeeds
|
||||
event = ctypes.cast(data, ctypes.POINTER(UTXOCacheChange)).contents
|
||||
self.log.info(f"handle_utxocache_uncache(): {event}")
|
||||
assert_equal(block_1_coinbase_txid, bytes(event.txid[::-1]).hex())
|
||||
assert_equal(0, event.index) # prevout index
|
||||
assert_equal(EARLY_BLOCK_HEIGHT, event.height)
|
||||
assert_equal(50 * COIN, event.value)
|
||||
assert_equal(True, event.is_coinbase)
|
||||
|
||||
handle_uncache_succeeds += 1
|
||||
try:
|
||||
assert_equal(block_1_coinbase_txid, bytes(event.txid[::-1]).hex())
|
||||
assert_equal(0, event.index) # prevout index
|
||||
assert_equal(EARLY_BLOCK_HEIGHT, event.height)
|
||||
assert_equal(50 * COIN, event.value)
|
||||
assert_equal(True, event.is_coinbase)
|
||||
except AssertionError:
|
||||
self.log.exception("Assertion failed")
|
||||
else:
|
||||
handle_uncache_succeeds += 1
|
||||
|
||||
bpf["utxocache_uncache"].open_perf_buffer(handle_utxocache_uncache)
|
||||
|
||||
|
|
@ -260,24 +263,32 @@ class UTXOCacheTracepointTest(BitcoinTestFramework):
|
|||
event = ctypes.cast(data, ctypes.POINTER(UTXOCacheChange)).contents
|
||||
self.log.info(f"handle_utxocache_add(): {event}")
|
||||
add = expected_utxocache_adds.pop(0)
|
||||
assert_equal(add["txid"], bytes(event.txid[::-1]).hex())
|
||||
assert_equal(add["index"], event.index)
|
||||
assert_equal(add["height"], event.height)
|
||||
assert_equal(add["value"], event.value)
|
||||
assert_equal(add["is_coinbase"], event.is_coinbase)
|
||||
handle_add_succeeds += 1
|
||||
try:
|
||||
assert_equal(add["txid"], bytes(event.txid[::-1]).hex())
|
||||
assert_equal(add["index"], event.index)
|
||||
assert_equal(add["height"], event.height)
|
||||
assert_equal(add["value"], event.value)
|
||||
assert_equal(add["is_coinbase"], event.is_coinbase)
|
||||
except AssertionError:
|
||||
self.log.exception("Assertion failed")
|
||||
else:
|
||||
handle_add_succeeds += 1
|
||||
|
||||
def handle_utxocache_spent(_, data, __):
|
||||
nonlocal handle_spent_succeeds
|
||||
event = ctypes.cast(data, ctypes.POINTER(UTXOCacheChange)).contents
|
||||
self.log.info(f"handle_utxocache_spent(): {event}")
|
||||
spent = expected_utxocache_spents.pop(0)
|
||||
assert_equal(spent["txid"], bytes(event.txid[::-1]).hex())
|
||||
assert_equal(spent["index"], event.index)
|
||||
assert_equal(spent["height"], event.height)
|
||||
assert_equal(spent["value"], event.value)
|
||||
assert_equal(spent["is_coinbase"], event.is_coinbase)
|
||||
handle_spent_succeeds += 1
|
||||
try:
|
||||
assert_equal(spent["txid"], bytes(event.txid[::-1]).hex())
|
||||
assert_equal(spent["index"], event.index)
|
||||
assert_equal(spent["height"], event.height)
|
||||
assert_equal(spent["value"], event.value)
|
||||
assert_equal(spent["is_coinbase"], event.is_coinbase)
|
||||
except AssertionError:
|
||||
self.log.exception("Assertion failed")
|
||||
else:
|
||||
handle_spent_succeeds += 1
|
||||
|
||||
bpf["utxocache_add"].open_perf_buffer(handle_utxocache_add)
|
||||
bpf["utxocache_spent"].open_perf_buffer(handle_utxocache_spent)
|
||||
|
|
|
|||
|
|
@ -85,13 +85,10 @@ class ValidationTracepointTest(BitcoinTestFramework):
|
|||
self.sigops,
|
||||
self.duration)
|
||||
|
||||
# The handle_* function is a ctypes callback function called from C. When
|
||||
# we assert in the handle_* function, the AssertError doesn't propagate
|
||||
# back to Python. The exception is ignored. We manually count and assert
|
||||
# that the handle_* functions succeeded.
|
||||
BLOCKS_EXPECTED = 2
|
||||
blocks_checked = 0
|
||||
expected_blocks = dict()
|
||||
events = []
|
||||
|
||||
self.log.info("hook into the validation:block_connected tracepoint")
|
||||
ctx = USDT(pid=self.nodes[0].process.pid)
|
||||
|
|
@ -101,19 +98,10 @@ class ValidationTracepointTest(BitcoinTestFramework):
|
|||
usdt_contexts=[ctx], debug=0)
|
||||
|
||||
def handle_blockconnected(_, data, __):
|
||||
nonlocal expected_blocks, blocks_checked
|
||||
nonlocal events, blocks_checked
|
||||
event = ctypes.cast(data, ctypes.POINTER(Block)).contents
|
||||
self.log.info(f"handle_blockconnected(): {event}")
|
||||
block_hash = bytes(event.hash[::-1]).hex()
|
||||
block = expected_blocks[block_hash]
|
||||
assert_equal(block["hash"], block_hash)
|
||||
assert_equal(block["height"], event.height)
|
||||
assert_equal(len(block["tx"]), event.transactions)
|
||||
assert_equal(len([tx["vin"] for tx in block["tx"]]), event.inputs)
|
||||
assert_equal(0, event.sigops) # no sigops in coinbase tx
|
||||
# only plausibility checks
|
||||
assert event.duration > 0
|
||||
del expected_blocks[block_hash]
|
||||
events.append(event)
|
||||
blocks_checked += 1
|
||||
|
||||
bpf["block_connected"].open_perf_buffer(
|
||||
|
|
@ -126,12 +114,24 @@ class ValidationTracepointTest(BitcoinTestFramework):
|
|||
expected_blocks[block_hash] = self.nodes[0].getblock(block_hash, 2)
|
||||
|
||||
bpf.perf_buffer_poll(timeout=200)
|
||||
bpf.cleanup()
|
||||
|
||||
self.log.info(f"check that we traced {BLOCKS_EXPECTED} blocks")
|
||||
self.log.info(f"check that we correctly traced {BLOCKS_EXPECTED} blocks")
|
||||
for event in events:
|
||||
block_hash = bytes(event.hash[::-1]).hex()
|
||||
block = expected_blocks[block_hash]
|
||||
assert_equal(block["hash"], block_hash)
|
||||
assert_equal(block["height"], event.height)
|
||||
assert_equal(len(block["tx"]), event.transactions)
|
||||
assert_equal(len([tx["vin"] for tx in block["tx"]]), event.inputs)
|
||||
assert_equal(0, event.sigops) # no sigops in coinbase tx
|
||||
# only plausibility checks
|
||||
assert event.duration > 0
|
||||
del expected_blocks[block_hash]
|
||||
assert_equal(BLOCKS_EXPECTED, blocks_checked)
|
||||
assert_equal(0, len(expected_blocks))
|
||||
|
||||
bpf.cleanup()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ValidationTracepointTest().main()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue