From 78ab91a0309d9a0c403e21a0ab4c2198ccc88cc5 Mon Sep 17 00:00:00 2001 From: Naviabheeman <45412531+Naviabheeman@users.noreply.github.com> Date: Wed, 15 Oct 2025 19:03:36 +0530 Subject: [PATCH 1/2] Fixed USDT functional test scripts (interface_usdt_*.py) - Updated tracing documentation and scripts - Added USDT test configuration updates --- .github/workflows/daily-test.yml | 67 ----------- cmake/module/FindUSDT.cmake | 10 +- contrib/tracing/connectblock_benchmark.bt | 2 +- contrib/tracing/log_coinselection.bt | 26 +++-- doc/tracing.md | 9 +- src/validation.cpp | 4 +- src/wallet/wallet.cpp | 13 ++- test/CMakeLists.txt | 4 + test/config.ini.in | 2 +- .../interface_usdt_coinselection.py | 68 +++++------ test/functional/interface_usdt_mempool.py | 110 ++++++++++-------- test/functional/interface_usdt_net.py | 8 +- test/functional/interface_usdt_utxocache.py | 91 ++++++++++++--- test/functional/test_runner.py | 2 +- 14 files changed, 220 insertions(+), 196 deletions(-) diff --git a/.github/workflows/daily-test.yml b/.github/workflows/daily-test.yml index ae234a3ab0..2456391eed 100644 --- a/.github/workflows/daily-test.yml +++ b/.github/workflows/daily-test.yml @@ -698,73 +698,6 @@ jobs: exit 1 fi - # # Test USDT tracing functionality if enabled - # if [ "${{ matrix.config.enable_usdt }}" == "true" ]; then - # echo "---------------- Start USDT tracing tests ---------------- " - # cd "$BASE_ROOT_DIR" - - # # Install BCC and bpftrace for USDT testing (Linux only) - # if [ "${{ matrix.config.platform }}" == "linux" ]; then - # echo "Installing BCC and bpftrace for tracing tests..." - # # Install BCC for Python USDT scripts - # python3 -m pip install bcc --user --quiet || echo "Warning: BCC installation failed" - - # # Install bpftrace for .bt scripts (already installed in setup, but ensure it's available) - # which bpftrace || echo "Warning: bpftrace not available" - - # # Run USDT functional tests (excluding coinselection as it tests non-existent tracepoints) - # echo "Running USDT functional tests..." - # if python3 test/functional/test_runner.py \ - # --tmpdir="$TAPYRUS_TEST_DIR" \ - # -j 1 \ - # --combinedlogslen=4000 \ - # --usdt \ - # interface_usdt_mempool.py \ - # interface_usdt_net.py \ - # interface_usdt_utxocache.py; then - # echo "USDT functional tests passed" - # else - # echo "USDT functional tests failed, continuing..." - # fi - - # # Test contrib tracing scripts with a short tapyrusd run - # echo "Testing contrib tracing scripts..." - # mkdir -p "$TAPYRUS_TEST_DIR/tracing_test" - - # # Start tapyrusd in background for tracing tests - # cd "$BASE_BUILD_DIR/bin" - # ./tapyrusd -datadir="$TAPYRUS_TEST_DIR/tracing_test" -daemon -regtest -txindex=1 -fallbackfee=0.0002 || echo "Failed to start tapyrusd" - # sleep 5 - - # # Test Python tracing scripts (run each for 5 seconds) - # cd "$BASE_ROOT_DIR" - # for script in contrib/tracing/*.py; do - # if [ -f "$script" ]; then - # echo "Testing $(basename $script)..." - # timeout 5 python3 "$script" "$BASE_BUILD_DIR/bin/tapyrusd" &>/dev/null || echo "Script $(basename $script) test completed" - # fi - # done - - # # Test bpftrace scripts syntax (without running, as they require root) - # for script in contrib/tracing/*.bt; do - # if [ -f "$script" ] && command -v bpftrace >/dev/null; then - # echo "Checking syntax of $(basename $script)..." - # bpftrace --dry-run "$script" &>/dev/null && echo "$(basename $script) syntax OK" || echo "$(basename $script) syntax issues" - # fi - # done - - # # Stop tapyrusd - # ./tapyrus-cli -datadir="$TAPYRUS_TEST_DIR/tracing_test" -regtest stop 2>/dev/null || pkill tapyrusd - # sleep 2 - - # echo "USDT tracing scripts tested" - # else - # echo "Skipping USDT tracing tests on ${{ matrix.config.platform }} (Linux only)" - # fi - # else - # echo "Skipping USDT tracing tests (USDT disabled)" - # fi - echo "---------------- Start daily functional test suite ---------------- " cd "$BASE_ROOT_DIR" # Run the daily functional test suite including long-running tests diff --git a/cmake/module/FindUSDT.cmake b/cmake/module/FindUSDT.cmake index 1378d462f9..2a59ef6d0c 100644 --- a/cmake/module/FindUSDT.cmake +++ b/cmake/module/FindUSDT.cmake @@ -34,8 +34,16 @@ if(APPLE) endif() else() # On Linux, look for systemtap headers + # Try to find sys/sdt.h in standard and architecture-specific locations find_path(USDT_INCLUDE_DIR NAMES sys/sdt.h + PATHS + /usr/include + /usr/local/include + /usr/include/${CMAKE_LIBRARY_ARCHITECTURE} + /usr/include/x86_64-linux-gnu + /usr/include/aarch64-linux-gnu + /usr/include/arm-linux-gnueabihf ) mark_as_advanced(USDT_INCLUDE_DIR) @@ -74,5 +82,5 @@ if(USDT_FOUND AND NOT TARGET USDT::headers) set_target_properties(USDT::headers PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${USDT_INCLUDE_DIR}" ) - set(ENABLE_TRACING TRUE) + set(ENABLE_TRACING ON) endif() diff --git a/contrib/tracing/connectblock_benchmark.bt b/contrib/tracing/connectblock_benchmark.bt index a6924588e6..83b50b18a6 100755 --- a/contrib/tracing/connectblock_benchmark.bt +++ b/contrib/tracing/connectblock_benchmark.bt @@ -102,7 +102,7 @@ usdt:./src/tapyrusd:validation:block_connected /arg1 >= $1 && (arg1 <= $2 || $2 blocks where the time it took to connect the block is above the . */ -usdt:./src/tapyrusd:validation:block_connected / (uint64) arg5 / 1000> $3 / +usdt:./src/tapyrusd:validation:block_connected / (uint64) arg5 / 1000 > $3 / { $hash = arg0; $height = (int32) arg1; diff --git a/contrib/tracing/log_coinselection.bt b/contrib/tracing/log_coinselection.bt index c4fc847705..b4316a09a5 100644 --- a/contrib/tracing/log_coinselection.bt +++ b/contrib/tracing/log_coinselection.bt @@ -7,19 +7,20 @@ BEGIN usdt:./src/tapyrusd:coin_selection:coins_requested { - @value = (uint64)arg0; + $wallet = str(arg0); $color = str(arg1); + @value = (uint64)arg2; - printf("Request [%s] : value [%d]\n", $color, @value); + printf("Request wallet [%s] [%s] : value [%d]\n", $wallet, $color, @value); } usdt:./src/tapyrusd:coin_selection:selected_coins { - $color = str(arg0); - @value = (uint64)arg1; - @mapValueIn = (uint64)arg2; + $algo = str(arg0); + $color = str(arg1); + @value = (uint64)arg2; @count = (uint64)arg3; - $algo = str(arg4); + @mapValueIn = (uint64)arg4; printf("Select [%s]: try to select [%d] using [%d]", $color, @value, @count); printf(" coins of total value [%d]", @mapValueIn); @@ -28,16 +29,17 @@ usdt:./src/tapyrusd:coin_selection:selected_coins usdt:./src/tapyrusd:coin_selection:change_info { - @amount = (uint64)arg0; - $color = str(arg1); + $color = str(arg0); + @position = (uint64)arg1; + @amount = (uint64)arg2; - printf("Change [%s] : value [%d]\n", $color, @amount); + printf("Change [%s] : position [%d] value [%d]\n", $color, @position, @amount); } usdt:./src/tapyrusd:coin_selection:fee_info { - @fee = (uint64)arg0; - @fee_need = (uint64)arg1; + @fee_need = (uint64)arg0; + @fee = (uint64)arg1; - printf("Fee [TPC] : value [%d] need [%d]\n", @fee, @fee_need); + printf("Fee [TPC] : need [%d] value [%d]\n", @fee_need, @fee); } \ No newline at end of file diff --git a/doc/tracing.md b/doc/tracing.md index ce85b24ebd..1ff6a5a030 100644 --- a/doc/tracing.md +++ b/doc/tracing.md @@ -137,11 +137,12 @@ Arguments passed: Is called when a coin is added to a UTXO cache. This can be a temporary UTXO cache too. Arguments passed: -1. Transaction ID (hash) as `pointer to unsigned chars` (i.e. 64 bytes hex string in little-endian) +1. Transaction ID (hash) as `pointer to C-style string` (64 bytes) 2. Output index as `uint32` -3. Block height the coin was added to the UTXO-set as `uint32` -4. Value of the coin as `int64` -5. If the coin is a coinbase as `bool` +3. Token name as `pointer to C-style string`(66 bytes) +4. Block height the coin was added to the UTXO-set as `uint32` +5. Value of the coin as `int64` +6. If the coin is a coinbase as `bool` #### Tracepoint `utxocache:utxocache_spent` diff --git a/src/validation.cpp b/src/validation.cpp index f33581477a..5c5c2a6f22 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -858,11 +858,11 @@ static bool AcceptToMemoryPoolWorker(const CTransactionRef &ptx, CTxMempoolAccep TRACE7(mempool, replaced, it->GetTx().GetHashMalFix().begin(), it->GetTxSize(), - nModifiedFees, + it->GetModifiedFee(), it->GetTime(), hash.begin(), tx.GetTotalSize(), - nConflictingFees + nModifiedFees ); opt.txnReplaced.push_back(it->GetSharedTx()); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 389bba0390..eed07e324c 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2652,7 +2652,7 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CTransac for ([[maybe_unused]]const auto& entity:mapValue) { - TRACE2(coin_selection, coins_requested, entity.second, entity.first.toHexString().c_str()); + TRACE3(coin_selection, coins_requested, GetName().c_str(), entity.first.toHexString().c_str(), entity.second); } if (vecSend.empty()) @@ -2836,7 +2836,7 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CTransac return false; } } - TRACE5(coin_selection, selected_coins, colorId.toHexString().c_str(), targetValue, mapValueIn[colorId], mapCoins[colorId].size(), bnb_used ? "BNB" : "knapsack"); + TRACE5(coin_selection, selected_coins, bnb_used ? "BNB" : "knapsack", colorId.toHexString().c_str(), targetValue, mapCoins[colorId].size(), mapValueIn[colorId]); } } else { bnb_used = false; @@ -2862,7 +2862,7 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CTransac // add colored coin change at the end mapChangePosInOut[colorId] = txNew.vout.size(); txNew.vout.push_back(newTxOut); - TRACE2(coin_selection, change_info, nChange, colorId.toHexString().c_str()); + TRACE3(coin_selection, change_info, colorId.toHexString().c_str(), mapChangePosInOut[colorId], nChange); } else mapChangePosInOut[colorId] = -1; @@ -2877,7 +2877,6 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CTransac const CAmount nChange = mapValueIn[colorId] - targetValue; if (nChange > 0) { - TRACE2(coin_selection, change_info, &nChange, colorId.toHexString().c_str()); // Fill a vout to ourself CTxOut newTxOut(nChange, scriptChange); @@ -2898,6 +2897,7 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CTransac //add change output to the end mapChangePosInOut[colorId] = txNew.vout.size(); txNew.vout.push_back(newTxOut); + TRACE3(coin_selection, change_info, colorId.toHexString().c_str(), mapChangePosInOut[colorId], nChange); } else { @@ -2908,6 +2908,7 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CTransac } std::vector::iterator position = txNew.vout.begin()+mapChangePosInOut[colorId]; txNew.vout.insert(position, newTxOut); + TRACE3(coin_selection, change_info, colorId.toHexString().c_str(), mapChangePosInOut[colorId], nChange); //colored coin change outputs may be incorrect after this insert. fix them for(auto& i : mapChangePosInOut) @@ -2980,7 +2981,7 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CTransac change_position->nValue += extraFeePaid; nFeeRet -= extraFeePaid; } - TRACE2(coin_selection, fee_info, nFeeRet, nFeeNeeded); + TRACE2(coin_selection, fee_info, nFeeNeeded, nFeeRet); break; // Done, enough fee included. } else if (!pick_new_inputs) { @@ -3000,7 +3001,7 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CTransac if (change_position->nValue >= MIN_FINAL_CHANGE + additionalFeeNeeded) { change_position->nValue -= additionalFeeNeeded; nFeeRet += additionalFeeNeeded; - TRACE2(coin_selection, fee_info, nFeeRet, nFeeNeeded); + TRACE2(coin_selection, fee_info, nFeeNeeded, nFeeRet); break; // Done, able to increase fee from change } } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 623dd8ac7b..464ff5977f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -19,6 +19,10 @@ if(NOT ENABLE_ZMQ) set(ENABLE_ZMQ_TRUE "#") endif() +if(NOT ENABLE_TRACING) + set(ENABLE_TRACING_TRUE "#") +endif() + # Create build ini file in build and source dir configure_file(config.ini.in config.ini USE_SOURCE_PERMISSIONS @ONLY) configure_file(config.ini.in ${abs_top_srcdir}/test/config.ini USE_SOURCE_PERMISSIONS @ONLY) diff --git a/test/config.ini.in b/test/config.ini.in index 672c8b0a0f..1ff2615902 100644 --- a/test/config.ini.in +++ b/test/config.ini.in @@ -20,4 +20,4 @@ RPCAUTH=@abs_top_srcdir@/share/rpcauth/rpcauth.py @BUILD_GENESIS_TRUE@BUILD_GENESIS=true @ENABLE_WALLET_TRUE@ENABLE_WALLET=true @ENABLE_ZMQ_TRUE@ENABLE_ZMQ=true -@ENABLE_USDT_TRACEPOINTS_TRUE@ENABLE_USDT_TRACEPOINTS=true \ No newline at end of file +@ENABLE_TRACING_TRUE@ENABLE_TRACING=true \ No newline at end of file diff --git a/test/functional/interface_usdt_coinselection.py b/test/functional/interface_usdt_coinselection.py index a3c830bb51..a1e1abc76e 100755 --- a/test/functional/interface_usdt_coinselection.py +++ b/test/functional/interface_usdt_coinselection.py @@ -17,32 +17,35 @@ assert_equal, assert_greater_than, assert_raises_rpc_error, + TAPYRUS_MODES, ) coinselection_tracepoints_program = """ #include -#define WALLET_NAME_LENGTH 16 +#define COLOR_ID_LENGTH 64 #define ALGO_NAME_LENGTH 16 struct event_data { u8 type; - char wallet_name[WALLET_NAME_LENGTH]; + char color_id[COLOR_ID_LENGTH]; - // selected coins event - char algo[ALGO_NAME_LENGTH]; - s64 target; - s64 waste; + // selected coins event (type 1) + s64 target_value; s64 selected_value; + s64 num_coins; + char algo[ALGO_NAME_LENGTH]; + + // coins requested event (type 2) + s64 amount; - // create tx event - bool success; - s64 fee; - s32 change_pos; + // change info event (type 3) + s64 change_amount; - // aps create tx event - bool use_aps; + // fee info event (type 4) + s64 fee_ret; + s64 fee_needed; }; BPF_QUEUE(coin_selection_events, struct event_data, 1024); @@ -51,45 +54,41 @@ struct event_data data; __builtin_memset(&data, 0, sizeof(data)); data.type = 1; - bpf_usdt_readarg_p(1, ctx, &data.wallet_name, WALLET_NAME_LENGTH); - bpf_usdt_readarg_p(2, ctx, &data.algo, ALGO_NAME_LENGTH); - bpf_usdt_readarg(3, ctx, &data.target); - bpf_usdt_readarg(4, ctx, &data.waste); - bpf_usdt_readarg(5, ctx, &data.selected_value); + bpf_usdt_readarg_p(1, ctx, &data.color_id, COLOR_ID_LENGTH); + bpf_usdt_readarg(2, ctx, &data.target_value); + bpf_usdt_readarg(3, ctx, &data.selected_value); + bpf_usdt_readarg(4, ctx, &data.num_coins); + bpf_usdt_readarg_p(5, ctx, &data.algo, ALGO_NAME_LENGTH); coin_selection_events.push(&data, 0); return 0; } -int trace_normal_create_tx(struct pt_regs *ctx) { +int trace_coins_requested(struct pt_regs *ctx) { struct event_data data; __builtin_memset(&data, 0, sizeof(data)); data.type = 2; - bpf_usdt_readarg_p(1, ctx, &data.wallet_name, WALLET_NAME_LENGTH); - bpf_usdt_readarg(2, ctx, &data.success); - bpf_usdt_readarg(3, ctx, &data.fee); - bpf_usdt_readarg(4, ctx, &data.change_pos); + bpf_usdt_readarg(1, ctx, &data.amount); + bpf_usdt_readarg_p(2, ctx, &data.color_id, COLOR_ID_LENGTH); coin_selection_events.push(&data, 0); return 0; } -int trace_attempt_aps(struct pt_regs *ctx) { +int trace_change_info(struct pt_regs *ctx) { struct event_data data; __builtin_memset(&data, 0, sizeof(data)); data.type = 3; - bpf_usdt_readarg_p(1, ctx, &data.wallet_name, WALLET_NAME_LENGTH); + bpf_usdt_readarg(1, ctx, &data.change_amount); + bpf_usdt_readarg_p(2, ctx, &data.color_id, COLOR_ID_LENGTH); coin_selection_events.push(&data, 0); return 0; } -int trace_aps_create_tx(struct pt_regs *ctx) { +int trace_fee_info(struct pt_regs *ctx) { struct event_data data; __builtin_memset(&data, 0, sizeof(data)); data.type = 4; - bpf_usdt_readarg_p(1, ctx, &data.wallet_name, WALLET_NAME_LENGTH); - bpf_usdt_readarg(2, ctx, &data.use_aps); - bpf_usdt_readarg(3, ctx, &data.success); - bpf_usdt_readarg(4, ctx, &data.fee); - bpf_usdt_readarg(5, ctx, &data.change_pos); + bpf_usdt_readarg(1, ctx, &data.fee_ret); + bpf_usdt_readarg(2, ctx, &data.fee_needed); coin_selection_events.push(&data, 0); return 0; } @@ -98,11 +97,12 @@ class CoinSelectionTracepointTest(BitcoinTestFramework): def add_options(self, parser): - self.add_wallet_options(parser) + pass def set_test_params(self): self.num_nodes = 1 self.setup_clean_chain = True + self.mode = TAPYRUS_MODES.PROD def skip_test_if_missing_module(self): self.skip_if_platform_not_linux() @@ -163,9 +163,9 @@ def run_test(self): self.log.info("hook into the coin_selection tracepoints") ctx = USDT(pid=self.nodes[0].process.pid) ctx.enable_probe(probe="coin_selection:selected_coins", fn_name="trace_selected_coins") - ctx.enable_probe(probe="coin_selection:normal_create_tx_internal", fn_name="trace_normal_create_tx") - ctx.enable_probe(probe="coin_selection:attempting_aps_create_tx", fn_name="trace_attempt_aps") - ctx.enable_probe(probe="coin_selection:aps_create_tx_internal", fn_name="trace_aps_create_tx") + ctx.enable_probe(probe="coin_selection:coins_requested", fn_name="trace_coins_requested") + ctx.enable_probe(probe="coin_selection:change_info", fn_name="trace_change_info") + ctx.enable_probe(probe="coin_selection:fee_info", fn_name="trace_fee_info") self.bpf = BPF(text=coinselection_tracepoints_program, usdt_contexts=[ctx], debug=0) self.log.info("Prepare wallets") diff --git a/test/functional/interface_usdt_mempool.py b/test/functional/interface_usdt_mempool.py index 59180e96a8..64c5dbe87f 100755 --- a/test/functional/interface_usdt_mempool.py +++ b/test/functional/interface_usdt_mempool.py @@ -13,18 +13,13 @@ from test_framework.messages import COIN from test_framework.mininode import P2PDataStore from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal +from test_framework.util import assert_equal, TAPYRUS_MODES from test_framework.timeout_config import TAPYRUSD_SYNC_TIMEOUT -MEMPOOL_TRACEPOINTS_PROGRAM = """ +MEMPOOL_ADDED_PROGRAM = """ # include -// The longest rejection reason is 118 chars and is generated in case of SCRIPT_ERR_EVAL_FALSE by -// strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())) -#define MAX_REJECT_REASON_LENGTH 118 -// The longest string returned by RemovalReasonToString() is 'sizelimit' -#define MAX_REMOVAL_REASON_LENGTH 9 -#define HASH_LENGTH 32 +#define HASH_LENGTH 32 struct added_event { @@ -33,37 +28,7 @@ s64 fee; }; -struct removed_event -{ - u8 hash[HASH_LENGTH]; - char reason[MAX_REMOVAL_REASON_LENGTH]; - s32 vsize; - s64 fee; - u64 entry_time; -}; - -struct rejected_event -{ - u8 hash[HASH_LENGTH]; - char reason[MAX_REJECT_REASON_LENGTH]; -}; - -struct replaced_event -{ - u8 replaced_hash[HASH_LENGTH]; - s32 replaced_vsize; - s64 replaced_fee; - u64 replaced_entry_time; - u8 replacement_hash[HASH_LENGTH]; - s32 replacement_vsize; - s64 replacement_fee; -}; - -// BPF perf buffer to push the data to user space. BPF_PERF_OUTPUT(added_events); -BPF_PERF_OUTPUT(removed_events); -BPF_PERF_OUTPUT(rejected_events); -BPF_PERF_OUTPUT(replaced_events); int trace_added(struct pt_regs *ctx) { struct added_event added = {}; @@ -75,6 +40,24 @@ added_events.perf_submit(ctx, &added, sizeof(added)); return 0; } +""" + +MEMPOOL_REMOVED_PROGRAM = """ +# include + +#define MAX_REMOVAL_REASON_LENGTH 9 +#define HASH_LENGTH 32 + +struct removed_event +{ + u8 hash[HASH_LENGTH]; + char reason[MAX_REMOVAL_REASON_LENGTH]; + s32 vsize; + s64 fee; + u64 entry_time; +}; + +BPF_PERF_OUTPUT(removed_events); int trace_removed(struct pt_regs *ctx) { struct removed_event removed = {}; @@ -88,6 +71,21 @@ removed_events.perf_submit(ctx, &removed, sizeof(removed)); return 0; } +""" + +MEMPOOL_REJECTED_PROGRAM = """ +# include + +#define MAX_REJECT_REASON_LENGTH 118 +#define HASH_LENGTH 32 + +struct rejected_event +{ + u8 hash[HASH_LENGTH]; + char reason[MAX_REJECT_REASON_LENGTH]; +}; + +BPF_PERF_OUTPUT(rejected_events); int trace_rejected(struct pt_regs *ctx) { struct rejected_event rejected = {}; @@ -98,6 +96,25 @@ rejected_events.perf_submit(ctx, &rejected, sizeof(rejected)); return 0; } +""" + +MEMPOOL_REPLACED_PROGRAM = """ +# include + +#define HASH_LENGTH 32 + +struct replaced_event +{ + u8 replaced_hash[HASH_LENGTH]; + s32 replaced_vsize; + s64 replaced_fee; + u64 replaced_entry_time; + u8 replacement_hash[HASH_LENGTH]; + s32 replacement_vsize; + s64 replacement_fee; +}; + +BPF_PERF_OUTPUT(replaced_events); int trace_replaced(struct pt_regs *ctx) { struct replaced_event replaced = {}; @@ -120,6 +137,7 @@ class MempoolTracepointTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 self.setup_clean_chain = True + self.mode = TAPYRUS_MODES.PROD def skip_test_if_missing_module(self): self.skip_if_platform_not_linux() @@ -137,8 +155,8 @@ def added_test(self): self.log.info("Hooking into mempool:added tracepoint...") node = self.nodes[0] ctx = USDT(pid=node.process.pid) - ctx.enable_probe(probe="added", fn_name="trace_added") - bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0) + ctx.enable_probe(probe="mempool:added", fn_name="trace_added") + bpf = BPF(text=MEMPOOL_ADDED_PROGRAM, usdt_contexts=[ctx], debug=0) def handle_added_event(_, data, __): nonlocal handled_added_events @@ -178,8 +196,8 @@ def removed_test(self): self.log.info("Hooking into mempool:removed tracepoint...") node = self.nodes[0] ctx = USDT(pid=node.process.pid) - ctx.enable_probe(probe="removed", fn_name="trace_removed") - bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0) + ctx.enable_probe(probe="mempool:removed", fn_name="trace_removed") + bpf = BPF(text=MEMPOOL_REMOVED_PROGRAM, usdt_contexts=[ctx], debug=0) def handle_removed_event(_, data, __): nonlocal handled_removed_events @@ -228,8 +246,8 @@ def replaced_test(self): self.log.info("Hooking into mempool:replaced tracepoint...") node = self.nodes[0] ctx = USDT(pid=node.process.pid) - ctx.enable_probe(probe="replaced", fn_name="trace_replaced") - bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0) + ctx.enable_probe(probe="mempool:replaced", fn_name="trace_replaced") + bpf = BPF(text=MEMPOOL_REPLACED_PROGRAM, usdt_contexts=[ctx], debug=0) def handle_replaced_event(_, data, __): nonlocal handled_replaced_events @@ -284,8 +302,8 @@ def rejected_test(self): self.log.info("Hooking into mempool:rejected tracepoint...") ctx = USDT(pid=node.process.pid) - ctx.enable_probe(probe="rejected", fn_name="trace_rejected") - bpf = BPF(text=MEMPOOL_TRACEPOINTS_PROGRAM, usdt_contexts=[ctx], debug=0) + ctx.enable_probe(probe="mempool:rejected", fn_name="trace_rejected") + bpf = BPF(text=MEMPOOL_REJECTED_PROGRAM, usdt_contexts=[ctx], debug=0) def handle_rejected_event(_, data, __): nonlocal handled_rejected_events diff --git a/test/functional/interface_usdt_net.py b/test/functional/interface_usdt_net.py index 6c2a89c307..28d764e15d 100755 --- a/test/functional/interface_usdt_net.py +++ b/test/functional/interface_usdt_net.py @@ -13,7 +13,7 @@ from test_framework.messages import msg_version from test_framework.mininode import P2PInterface from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal +from test_framework.util import assert_equal, TAPYRUS_MODES from test_framework.timeout_config import TAPYRUSD_SYNC_TIMEOUT # Tor v3 addresses are 62 chars + 6 chars for the port (':12345'). @@ -80,6 +80,8 @@ class NetTracepointTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 + self.setup_clean_chain = True + self.mode = TAPYRUS_MODES.PROD def run_test(self): # Tests the net:inbound_message and net:outbound_message tracepoints @@ -101,9 +103,9 @@ def __repr__(self): self.log.info( "hook into the net:inbound_message and net:outbound_message tracepoints") ctx = USDT(pid=self.nodes[0].process.pid) - ctx.enable_probe(probe="inbound_message", + ctx.enable_probe(probe="net:inbound_message", fn_name="trace_inbound_message") - ctx.enable_probe(probe="outbound_message", + ctx.enable_probe(probe="net:outbound_message", fn_name="trace_outbound_message") bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=1) diff --git a/test/functional/interface_usdt_utxocache.py b/test/functional/interface_usdt_utxocache.py index 5a2d79952a..0ff46e49ce 100755 --- a/test/functional/interface_usdt_utxocache.py +++ b/test/functional/interface_usdt_utxocache.py @@ -15,10 +15,10 @@ print from test_framework.messages import COIN, CTransaction from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, hex_str_to_bytes +from test_framework.util import assert_equal, hex_str_to_bytes, TAPYRUS_MODES from test_framework.timeout_config import TAPYRUSD_SYNC_TIMEOUT -utxocache_changes_program = """ +utxocache_add_program = """ #include typedef signed long long i64; @@ -45,6 +45,22 @@ utxocache_add.perf_submit(ctx, &add, sizeof(add)); return 0; } +""" + +utxocache_spent_program = """ +#include + +typedef signed long long i64; + +struct utxocache_change +{ + char txid[64]; + u32 index; + char token[66]; + u32 height; + i64 value; + bool is_coinbase; +}; BPF_PERF_OUTPUT(utxocache_spent); int trace_utxocache_spent(struct pt_regs *ctx) { @@ -58,17 +74,55 @@ utxocache_spent.perf_submit(ctx, &spent, sizeof(spent)); return 0; } +""" + +utxocache_uncache_program = """ +#include -BPF_PERF_OUTPUT(utxocache_uncache); int trace_utxocache_uncache(struct pt_regs *ctx) { - struct utxocache_change uncache = {}; - bpf_usdt_readarg_p(1, ctx, &uncache.txid, 64); - bpf_usdt_readarg(2, ctx, &uncache.index); - bpf_usdt_readarg_p(3, ctx, &uncache.token, 66); - bpf_usdt_readarg(4, ctx, &uncache.height); - bpf_usdt_readarg(5, ctx, &uncache.value); - bpf_usdt_readarg(6, ctx, &uncache.is_coinbase); - utxocache_uncache.perf_submit(ctx, &uncache, sizeof(uncache)); + // Minimal probe - just attach, don't read arguments + return 0; +} +""" + +utxocache_add_spent_program = """ +#include + +typedef signed long long i64; + +struct utxocache_change +{ + char txid[64]; + u32 index; + char token[66]; + u32 height; + i64 value; + bool is_coinbase; +}; + +BPF_PERF_OUTPUT(utxocache_add); +int trace_utxocache_add(struct pt_regs *ctx) { + struct utxocache_change add = {}; + bpf_usdt_readarg_p(1, ctx, &add.txid, 64); + bpf_usdt_readarg(2, ctx, &add.index); + bpf_usdt_readarg_p(3, ctx, &add.token, 66); + bpf_usdt_readarg(4, ctx, &add.height); + bpf_usdt_readarg(5, ctx, &add.value); + bpf_usdt_readarg(6, ctx, &add.is_coinbase); + utxocache_add.perf_submit(ctx, &add, sizeof(add)); + return 0; +} + +BPF_PERF_OUTPUT(utxocache_spent); +int trace_utxocache_spent(struct pt_regs *ctx) { + struct utxocache_change spent = {}; + bpf_usdt_readarg_p(1, ctx, &spent.txid, 64); + bpf_usdt_readarg(2, ctx, &spent.index); + bpf_usdt_readarg_p(3, ctx, &spent.token, 66); + bpf_usdt_readarg(4, ctx, &spent.height); + bpf_usdt_readarg(5, ctx, &spent.value); + bpf_usdt_readarg(6, ctx, &spent.is_coinbase); + utxocache_spent.perf_submit(ctx, &spent, sizeof(spent)); return 0; } """ @@ -141,6 +195,7 @@ def set_test_params(self): self.setup_clean_chain = False self.num_nodes = 1 self.extra_args = [["-txindex"]] + self.mode = TAPYRUS_MODES.PROD def run_test(self): @@ -176,10 +231,10 @@ def test_uncache(self): invalid_tx.vin[0].prevout.hash = int(block_1_coinbase_txid, 16) self.log.info("hooking into the uncache tracepoint") - ctx = USDT(pid = self.nodes[0].process.pid) - ctx.enable_probe(probe="utxocache_uncache", + ctx = USDT(pid=self.nodes[0].process.pid) + ctx.enable_probe(probe="utxocache:utxocache_uncache", fn_name="trace_utxocache_uncache") - bpf = BPF(text=utxocache_changes_program, usdt_contexts=[ctx], debug=0) + bpf = BPF(text=utxocache_uncache_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 @@ -242,10 +297,10 @@ def test_add_spent(self): self.log.info( "hook into the utxocache:utxocache_add and utxocache:utxocache_spent tracepoints") ctx = USDT(pid = self.nodes[0].process.pid) - ctx.enable_probe(probe="utxocache_add", fn_name="trace_utxocache_add") - ctx.enable_probe(probe="utxocache_spent", + ctx.enable_probe(probe="utxocache:utxocache_add", fn_name="trace_utxocache_add") + ctx.enable_probe(probe="utxocache:utxocache_spent", fn_name="trace_utxocache_spent") - bpf = BPF(text=utxocache_changes_program, usdt_contexts=[ctx], debug=0) + bpf = BPF(text=utxocache_add_spent_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 @@ -342,7 +397,7 @@ def test_flush(self): self.log.info("test the utxocache_flush tracepoint API") self.log.info("hook into the utxocache_flush tracepoint") ctx = USDT(pid = self.nodes[0].process.pid) - ctx.enable_probe(probe="utxocache_flush", + ctx.enable_probe(probe="utxocache:utxocache_flush", fn_name="trace_utxocache_flush") bpf = BPF(text=utxocache_flushes_program, usdt_contexts=[ctx], debug=0) diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 3d989b079c..ed89b24cd0 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -301,7 +301,7 @@ def main(): enable_wallet = config["components"].getboolean("ENABLE_WALLET") enable_utils = config["components"].getboolean("BUILD_UTILS") enable_tapyrusd = config["components"].getboolean("BUILD_DAEMON") - enable_usdt = config["components"].getboolean("ENABLE_USDT") + enable_usdt = config["components"].getboolean("ENABLE_TRACING") if config["environment"]["EXEEXT"] == ".exe" and not args.force: # https://github.com/bitcoin/bitcoin/commit/d52802551752140cf41f0d9a225a43e84404d3e9 From bef7ddf0bfe9ede5f7731f88d71bb6adeeb8efab Mon Sep 17 00:00:00 2001 From: Naviabheeman <45412531+Naviabheeman@users.noreply.github.com> Date: Fri, 17 Oct 2025 18:42:26 +0530 Subject: [PATCH 2/2] remove USDT test from the list of tests to run in the CI --- test/functional/test_runner.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index ed89b24cd0..3f8bee6bd0 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -338,8 +338,9 @@ def main(): if args.debugscripts: test_list += DEBUG_MODE_SCRIPTS - if enable_usdt: - test_list += USDT_SCRIPTS + # USDT scripts are not enabled in the CI now + #if enable_usdt: + # test_list += USDT_SCRIPTS # Remove the test cases that the user has explicitly asked to exclude. if args.exclude: