connectblock_benchmark.bt
1 #!/usr/bin/env bpftrace 2 3 /* 4 5 USAGE: 6 7 bpftrace contrib/tracing/connectblock_benchmark.bt <start height> <end height> <logging threshold in ms> 8 9 - <start height> sets the height at which the benchmark should start. Setting 10 the start height to 0 starts the benchmark immediately, even before the 11 first block is connected. 12 - <end height> sets the height after which the benchmark should end. Setting 13 the end height to 0 disables the benchmark. The script only logs blocks 14 over <logging threshold in ms>. 15 - Threshold <logging threshold in ms> 16 17 This script requires a 'bitcoind' binary compiled with eBPF support and the 18 'validation:block_connected' USDT. By default, it's assumed that 'bitcoind' is 19 located in './build/bin/bitcoind'. This can be modified in the script below. 20 21 EXAMPLES: 22 23 bpftrace contrib/tracing/connectblock_benchmark.bt 300000 680000 1000 24 25 When run together 'bitcoind -reindex', this benchmarks the time it takes to 26 connect the blocks between height 300.000 and 680.000 (inclusive) and prints 27 details about all blocks that take longer than 1000ms to connect. Prints a 28 histogram with block connection times when the benchmark is finished. 29 30 31 bpftrace contrib/tracing/connectblock_benchmark.bt 0 0 500 32 33 When running together 'bitcoind', all newly connected blocks that 34 take longer than 500ms to connect are logged. A histogram with block 35 connection times is shown when the script is terminated. 36 37 */ 38 39 BEGIN 40 { 41 $start_height = $1; 42 $end_height = $2; 43 $logging_threshold_ms = $3; 44 45 if ($end_height < $start_height) { 46 printf("Error: start height (%d) larger than end height (%d)!\n", $start_height, $end_height); 47 exit(); 48 } 49 50 if ($end_height > 0) { 51 printf("ConnectBlock benchmark between height %d and %d inclusive\n", $start_height, $end_height); 52 } else { 53 printf("ConnectBlock logging starting at height %d\n", $start_height); 54 } 55 56 if ($logging_threshold_ms > 0) { 57 printf("Logging blocks taking longer than %d ms to connect.\n", $3); 58 } 59 60 if ($start_height == 0) { 61 @start = nsecs; 62 } 63 } 64 65 /* 66 Attaches to the 'validation:block_connected' USDT and collects stats when the 67 connected block is between the start and end height (or the end height is 68 unset). 69 */ 70 usdt:./build/bin/bitcoind:validation:block_connected /arg1 >= $1 && (arg1 <= $2 || $2 == 0 )/ 71 { 72 $height = arg1; 73 $transactions = arg2; 74 $inputs = arg3; 75 $sigops = arg4; 76 $duration = (uint64) arg5; 77 78 @height = $height; 79 80 @blocks = @blocks + 1; 81 @transactions = @transactions + $transactions; 82 @inputs = @inputs + $inputs; 83 @sigops = @sigops + $sigops; 84 85 @durations = hist($duration / 1e6); 86 87 if ($height == $1 && $height != 0) { 88 @start = nsecs; 89 printf("Starting Connect Block Benchmark between height %d and %d.\n", $1, $2); 90 } 91 92 if ($2 > 0 && $height >= $2) { 93 @end = nsecs; 94 $duration = @end - @start; 95 printf("\nTook %d ms to connect the blocks between height %d and %d.\n", $duration / 1e9, $1, $2); 96 exit(); 97 } 98 } 99 100 /* 101 Attaches to the 'validation:block_connected' USDT and logs information about 102 blocks where the time it took to connect the block is above the 103 <logging threshold in ms>. 104 */ 105 usdt:./build/bin/bitcoind:validation:block_connected / (uint64) arg5 / 1e6 > $3 / 106 { 107 $hash = arg0; 108 $height = (int32) arg1; 109 $transactions = (uint64) arg2; 110 $inputs = (int32) arg3; 111 $sigops = (int64) arg4; 112 $duration = (int64) arg5; 113 114 115 printf("Block %d (", $height); 116 /* Prints each byte of the block hash as hex in big-endian (the block-explorer format) */ 117 $p = $hash + 31; 118 unroll(32) { 119 $b = *(uint8*)$p; 120 printf("%02x", $b); 121 $p -= 1; 122 } 123 printf(") %4d tx %5d ins %5d sigops took %4d ms\n", $transactions, $inputs, $sigops, (uint64) $duration / 1e6); 124 } 125 126 127 /* 128 Prints stats about the blocks, transactions, inputs, and sigops processed in 129 the last second (if any). 130 */ 131 interval:s:1 { 132 if (@blocks > 0) { 133 printf("BENCH %4d blk/s %6d tx/s %7d inputs/s %8d sigops/s (height %d)\n", @blocks, @transactions, @inputs, @sigops, @height); 134 135 zero(@blocks); 136 zero(@transactions); 137 zero(@inputs); 138 zero(@sigops); 139 } 140 } 141 142 END 143 { 144 printf("\nHistogram of block connection times in milliseconds (ms).\n"); 145 print(@durations); 146 147 clear(@durations); 148 clear(@blocks); 149 clear(@transactions); 150 clear(@inputs); 151 clear(@sigops); 152 clear(@height); 153 clear(@start); 154 clear(@end); 155 } 156