connectblock_benchmark.bt raw

   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  
 157