Changeset View
Changeset View
Standalone View
Standalone View
contrib/tracing/connectblock_benchmark.bt
#!/usr/bin/env bpftrace | #!/usr/bin/env bpftrace | ||||
/* | /* | ||||
USAGE: | USAGE: | ||||
BPFTRACE_STRLEN=65 bpftrace contrib/tracing/connectblock_benchmark.bt <start height> <end height> <logging threshold in ms> | bpftrace contrib/tracing/connectblock_benchmark.bt <start height> <end height> <logging threshold in ms> | ||||
- The environment variable BPFTRACE_STRLEN needs to be set to 65 chars as | |||||
strings are limited to 64 chars by default. Hex strings with Bitcoin block | |||||
hashes are 64 hex chars + 1 null-termination char. | |||||
- <start height> sets the height at which the benchmark should start. Setting | - <start height> sets the height at which the benchmark should start. Setting | ||||
the start height to 0 starts the benchmark immediately, even before the | the start height to 0 starts the benchmark immediately, even before the | ||||
first block is connected. | first block is connected. | ||||
- <end height> sets the height after which the benchmark should end. Setting | - <end height> sets the height after which the benchmark should end. Setting | ||||
the end height to 0 disables the benchmark. The script only logs blocks | the end height to 0 disables the benchmark. The script only logs blocks | ||||
over <logging threshold in ms>. | over <logging threshold in ms>. | ||||
- Threshold <logging threshold in ms> | - Threshold <logging threshold in ms> | ||||
This script requires a 'bitcoind' binary compiled with eBPF support and the | This script requires a 'bitcoind' binary compiled with eBPF support and the | ||||
'validation:block_connected' USDT. By default, it's assumed that 'bitcoind' is | 'validation:block_connected' USDT. By default, it's assumed that 'bitcoind' is | ||||
located in './src/bitcoind'. This can be modified in the script below. | located in './src/bitcoind'. This can be modified in the script below. | ||||
EXAMPLES: | EXAMPLES: | ||||
BPFTRACE_STRLEN=65 bpftrace contrib/tracing/connectblock_benchmark.bt 300000 680000 1000 | bpftrace contrib/tracing/connectblock_benchmark.bt 300000 680000 1000 | ||||
When run together 'bitcoind -reindex', this benchmarks the time it takes to | When run together 'bitcoind -reindex', this benchmarks the time it takes to | ||||
connect the blocks between height 300.000 and 680.000 (inclusive) and prints | connect the blocks between height 300.000 and 680.000 (inclusive) and prints | ||||
details about all blocks that take longer than 1000ms to connect. Prints a | details about all blocks that take longer than 1000ms to connect. Prints a | ||||
histogram with block connection times when the benchmark is finished. | histogram with block connection times when the benchmark is finished. | ||||
BPFTRACE_STRLEN=65 bpftrace contrib/tracing/connectblock_benchmark.bt 0 0 500 | bpftrace contrib/tracing/connectblock_benchmark.bt 0 0 500 | ||||
When running together 'bitcoind', all newly connected blocks that | When running together 'bitcoind', all newly connected blocks that | ||||
take longer than 500ms to connect are logged. A histogram with block | take longer than 500ms to connect are logged. A histogram with block | ||||
connection times is shown when the script is terminated. | connection times is shown when the script is terminated. | ||||
*/ | */ | ||||
BEGIN | BEGIN | ||||
Show All 27 Lines | /* | ||||
connected block is between the start and end height (or the end height is | connected block is between the start and end height (or the end height is | ||||
unset). | unset). | ||||
*/ | */ | ||||
usdt:./src/bitcoind:validation:block_connected /arg1 >= $1 && (arg1 <= $2 || $2 == 0 )/ | usdt:./src/bitcoind:validation:block_connected /arg1 >= $1 && (arg1 <= $2 || $2 == 0 )/ | ||||
{ | { | ||||
$height = arg1; | $height = arg1; | ||||
$transactions = arg2; | $transactions = arg2; | ||||
$inputs = arg3; | $inputs = arg3; | ||||
$sigops = arg4; | $sigchecks = arg4; | ||||
$duration = (uint64) arg5; | $duration = (uint64) arg5; | ||||
@height = $height; | @height = $height; | ||||
@blocks = @blocks + 1; | @blocks = @blocks + 1; | ||||
@transactions = @transactions + $transactions; | @transactions = @transactions + $transactions; | ||||
@inputs = @inputs + $inputs; | @inputs = @inputs + $inputs; | ||||
@sigops = @sigops + $sigops; | @sigchecks = @sigchecks + $sigchecks; | ||||
@durations = hist($duration / 1000); | @durations = hist($duration / 1000); | ||||
if ($height == $1 && $height != 0) { | if ($height == $1 && $height != 0) { | ||||
@start = nsecs; | @start = nsecs; | ||||
printf("Starting Connect Block Benchmark between height %d and %d.\n", $1, $2); | printf("Starting Connect Block Benchmark between height %d and %d.\n", $1, $2); | ||||
} | } | ||||
if ($2 > 0 && $height >= $2) { | if ($2 > 0 && $height >= $2) { | ||||
@end = nsecs; | @end = nsecs; | ||||
$duration = @end - @start; | $duration = @end - @start; | ||||
printf("\nTook %d ms to connect the blocks between height %d and %d.\n", $duration / 1000000, $1, $2); | printf("\nTook %d ms to connect the blocks between height %d and %d.\n", $duration / 1000000, $1, $2); | ||||
exit(); | exit(); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
Attaches to the 'validation:block_connected' USDT and logs information about | Attaches to the 'validation:block_connected' USDT and logs information about | ||||
blocks where the time it took to connect the block is above the | blocks where the time it took to connect the block is above the | ||||
<logging threshold in ms>. | <logging threshold in ms>. | ||||
*/ | */ | ||||
usdt:./src/bitcoind:validation:block_connected / (uint64) arg5 / 1000> $3 / | usdt:./src/bitcoind:validation:block_connected / (uint64) arg5 / 1000> $3 / | ||||
{ | { | ||||
$hash_str = str(arg0); | $hash = arg0; | ||||
$height = (int32) arg1; | $height = (int32) arg1; | ||||
$transactions = (uint64) arg2; | $transactions = (uint64) arg2; | ||||
$inputs = (int32) arg3; | $inputs = (int32) arg3; | ||||
$sigops = (int64) arg4; | $sigchecks = (int64) arg4; | ||||
$duration = (int64) arg5; | $duration = (int64) arg5; | ||||
printf("Block %d (%s) %4d tx %5d ins %5d sigops took %4d ms\n", $height, $hash_str, $transactions, $inputs, $sigops, (uint64) $duration / 1000); | |||||
printf("Block %d (", $height); | |||||
/* Prints each byte of the block hash as hex in big-endian (the block-explorer format) */ | |||||
$p = $hash + 31; | |||||
unroll(32) { | |||||
$b = *(uint8*)$p; | |||||
printf("%02x", $b); | |||||
$p -= 1; | |||||
} | |||||
printf(") %4d tx %5d ins %5d sigchk took %4d ms\n", $transactions, $inputs, $sigchecks, (uint64) $duration / 1000); | |||||
} | } | ||||
/* | /* | ||||
Prints stats about the blocks, transactions, inputs, and sigops processed in | Prints stats about the blocks, transactions, inputs, and sigchecks processed | ||||
the last second (if any). | in the last second (if any). | ||||
*/ | */ | ||||
interval:s:1 { | interval:s:1 { | ||||
if (@blocks > 0) { | if (@blocks > 0) { | ||||
printf("BENCH %4d blk/s %6d tx/s %7d inputs/s %8d sigops/s (height %d)\n", @blocks, @transactions, @inputs, @sigops, @height); | printf("BENCH %4d blk/s %6d tx/s %7d inputs/s %8d sigchk/s (height %d)\n", @blocks, @transactions, @inputs, @sigchecks, @height); | ||||
zero(@blocks); | zero(@blocks); | ||||
zero(@transactions); | zero(@transactions); | ||||
zero(@inputs); | zero(@inputs); | ||||
zero(@sigops); | zero(@sigchecks); | ||||
} | } | ||||
} | } | ||||
END | END | ||||
{ | { | ||||
printf("\nHistogram of block connection times in milliseconds (ms).\n"); | printf("\nHistogram of block connection times in milliseconds (ms).\n"); | ||||
print(@durations); | print(@durations); | ||||
clear(@durations); | clear(@durations); | ||||
clear(@blocks); | clear(@blocks); | ||||
clear(@transactions); | clear(@transactions); | ||||
clear(@inputs); | clear(@inputs); | ||||
clear(@sigops); | clear(@sigchecks); | ||||
clear(@height); | clear(@height); | ||||
clear(@start); | clear(@start); | ||||
clear(@end); | clear(@end); | ||||
} | } | ||||