Qortal Core - Main Code Repository Decentralized Data Network - Blockchain - TRUE Cross-Chain Trading - Application and Website Hosting - Much More - Qortal is the future internet infrastructure for the global digital world. https://qortal.dev
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
4.2 KiB

#!/usr/bin/env bash
start_height=$1
count=$2
if [ -z "${start_height}" ]; then
echo
echo "Error: missing start height."
echo
echo "Usage:"
echo "block-timings.sh <startheight> [count] [target] [deviation] [power]"
echo
echo "startheight: a block height, preferably within the untrimmed range, to avoid data gaps"
echo "count: the number of blocks to request and analyse after the start height. Default: 100"
echo "target: the target block time in milliseconds. Originates from blockchain.json. Default: 60000"
echo "deviation: the allowed block time deviation in milliseconds. Originates from blockchain.json. Default: 30000"
echo "power: used when transforming key distance to a time offset. Originates from blockchain.json. Default: 0.2"
echo
exit
fi
target=$3
deviation=$4
power=$5
count=${count:=100}
target=${target:=60000}
deviation=${deviation:=30000}
power=${power:=0.2}
finish_height=$((start_height + count - 1))
height=$start_height
echo "Settings:"
echo "Target time offset: ${target}"
echo "Deviation: ${deviation}"
echo "Power transform: ${power}"
echo
function calculate_time_offset {
local key_distance_ratio=$1
local transformed=$( echo "" | awk "END {print ${key_distance_ratio} ^ ${power}}")
local time_offset=$(echo "${deviation}*2*${transformed}" | bc)
time_offset=${time_offset%.*}
echo $time_offset
}
function fetch_and_process_blocks {
echo "Fetching blocks from height ${start_height} to ${finish_height}..."
echo
total_time_offset=0
errors=0
while [ "${height}" -le "${finish_height}" ]; do
block_minting_info=$(curl -s "http://localhost:12391/blocks/byheight/${height}/mintinginfo")
error=$(echo "${block_minting_info}" | jq -r .error)
if [ "${error}" != "null" ]; then
echo "Error fetching minting info for block ${height}"
echo
errors=$((errors+1))
height=$((height+1))
continue;
fi
# Parse minting info
minter_level=$(echo "${block_minting_info}" | jq -r .minterLevel)
key_distance_ratio=$(echo "${block_minting_info}" | jq -r .keyDistanceRatio)
time_delta=$(echo "${block_minting_info}" | jq -r .timeDelta)
time_offset=$(calculate_time_offset "${key_distance_ratio}")
block_time=$((target-deviation+time_offset))
echo "=== BLOCK ${height} ==="
echo "Minter level: ${minter_level}"
echo "Key distance ratio: ${key_distance_ratio}"
echo "Time offset: ${time_offset}"
echo "Block time (real): ${time_delta}"
echo "Block time (calculated): ${block_time}"
if [ "${time_delta}" -ne "${block_time}" ]; then
echo "WARNING: Block time mismatch. This is to be expected when using custom settings."
fi
echo
total_time_offset=$((total_time_offset+block_time))
height=$((height+1))
done
adjusted_count=$((count-errors))
if [ "${adjusted_count}" -eq 0 ]; then
echo "No blocks were retrieved."
echo
exit;
fi
mean_time_offset=$((total_time_offset/adjusted_count))
time_offset_diff=$((mean_time_offset-target))
echo "==================="
echo "===== SUMMARY ====="
echo "==================="
echo "Total blocks retrieved: ${adjusted_count}"
echo "Total blocks failed: ${errors}"
echo "Mean time offset: ${mean_time_offset}ms"
echo "Target time offset: ${target}ms"
echo "Difference from target: ${time_offset_diff}ms"
echo
}
function estimate_key_distance_ratio_for_level {
local level=$1
local example_key_distance="0.5"
echo "(${example_key_distance}/${level})"
}
function estimate_block_timestamps {
min_block_time=9999999
max_block_time=0
echo "===== BLOCK TIME ESTIMATES ====="
for level in {1..10}; do
example_key_distance_ratio=$(estimate_key_distance_ratio_for_level "${level}")
time_offset=$(calculate_time_offset "${example_key_distance_ratio}")
block_time=$((target-deviation+time_offset))
if [ "${block_time}" -gt "${max_block_time}" ]; then
max_block_time=${block_time}
fi
if [ "${block_time}" -lt "${min_block_time}" ]; then
min_block_time=${block_time}
fi
echo "Level: ${level}, time offset: ${time_offset}, block time: ${block_time}"
done
block_time_range=$((max_block_time-min_block_time))
echo "Range: ${block_time_range}"
echo
}
fetch_and_process_blocks
estimate_block_timestamps