global: snap

This commit is contained in:
nym21
2026-04-04 18:19:11 +02:00
parent 5340cc288e
commit 62f51761ee
23 changed files with 492 additions and 126 deletions

228
scripts/compare_bitcoin_cli.sh Executable file
View File

@@ -0,0 +1,228 @@
#!/usr/bin/env bash
#
# Compare brk output against bitcoin-cli to find discrepancies.
#
set -euo pipefail
BRK="http://localhost:3110"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BOLD='\033[1m'
NC='\033[0m'
pass=0
fail=0
warn=0
# Convert BTC decimal string to sats using python Decimal (no float loss)
btc_to_sats() {
python3 -c "from decimal import Decimal; print(int(Decimal('$1') * 100000000))"
}
# Sum an array of BTC values to sats precisely
sum_btc_values_to_sats() {
python3 -c "
import sys, json
from decimal import Decimal
vals = json.load(sys.stdin)
print(int(sum(Decimal(str(v)) for v in vals) * 100000000))
"
}
compare() {
local label="$1" btc_val="$2" brk_val="$3"
if [[ "$btc_val" == "$brk_val" ]]; then
printf "${GREEN} ✓ %-30s${NC} %s\n" "$label" "$btc_val"
((pass++)) || true
else
printf "${RED} ✗ %-30s${NC} bitcoin-cli: %-20s brk: %-20s\n" "$label" "$btc_val" "$brk_val"
((fail++)) || true
fi
}
compare_float() {
local label="$1" btc_val="$2" brk_val="$3"
local btc_short="${btc_val:0:15}" brk_short="${brk_val:0:15}"
if [[ "$btc_short" == "$brk_short" ]]; then
printf "${GREEN} ✓ %-30s${NC} %s\n" "$label" "$btc_val"
((pass++)) || true
else
printf "${YELLOW} ~ %-30s${NC} bitcoin-cli: %-20s brk: %-20s\n" "$label" "$btc_val" "$brk_val"
((warn++)) || true
fi
}
section() {
printf "\n${BOLD}── %s ──${NC}\n" "$1"
}
# ─── Get tip from brk ───
brk_height=$(curl -sf "$BRK/api/blocks/tip/height")
brk_hash=$(curl -sf "$BRK/api/blocks/tip/hash")
btc_height=$(bitcoin-cli getblockcount)
btc_hash=$(bitcoin-cli getbestblockhash)
section "Chain tip"
compare "height" "$btc_height" "$brk_height"
compare "hash" "$btc_hash" "$brk_hash"
# If tips differ, use the lower height for comparison
if [[ "$btc_height" != "$brk_height" ]]; then
printf "${YELLOW} Tips differ — comparing at brk height %s${NC}\n" "$brk_height"
btc_hash=$(bitcoin-cli getblockhash "$brk_height")
brk_hash=$(curl -sf "$BRK/api/block-height/$brk_height")
compare "hash at $brk_height" "$btc_hash" "$brk_hash"
fi
# ─── gettxoutsetinfo ───
section "gettxoutsetinfo"
printf " Running gettxoutsetinfo (this can take a while)...\n"
txoutset=$(bitcoin-cli gettxoutsetinfo 2>/dev/null || echo '{}')
if [[ "$txoutset" != '{}' ]]; then
btc_txouts=$(echo "$txoutset" | jq -r '.txouts')
btc_total_amount=$(echo "$txoutset" | jq -r '.total_amount')
btc_txoutset_height=$(echo "$txoutset" | jq -r '.height')
# Get brk utxoSetSize from block extras at that height
txoutset_hash=$(bitcoin-cli getblockhash "$btc_txoutset_height")
brk_block=$(curl -sf "$BRK/api/v1/block/$txoutset_hash")
brk_utxo_set_size=$(echo "$brk_block" | jq -r '.extras.utxoSetSize')
compare "txouts (UTXO count)" "$btc_txouts" "$brk_utxo_set_size"
if [[ "$btc_txouts" != "$brk_utxo_set_size" ]]; then
diff=$((brk_utxo_set_size - btc_txouts))
printf "${RED} → delta: %d${NC}\n" "$diff"
fi
btc_supply_sats=$(btc_to_sats "$btc_total_amount")
printf " ${YELLOW}total_amount:${NC} bitcoin-cli: %s BTC (%s sats) — check brk supply series\n" "$btc_total_amount" "$btc_supply_sats"
else
printf " ${YELLOW}gettxoutsetinfo unavailable or timed out${NC}\n"
fi
# ─── getblock comparison ───
section "getblock vs /api/v1/block (at tip: $brk_hash)"
btc_block=$(bitcoin-cli getblock "$brk_hash")
brk_v1=$(curl -sf "$BRK/api/v1/block/$brk_hash")
btc_size=$(echo "$btc_block" | jq -r '.size')
btc_weight=$(echo "$btc_block" | jq -r '.weight')
btc_nTx=$(echo "$btc_block" | jq -r '.nTx')
btc_difficulty=$(echo "$btc_block" | jq -r '.difficulty')
btc_version=$(echo "$btc_block" | jq -r '.version')
# bitcoin-cli returns bits as hex string, brk as decimal — convert
btc_bits_hex=$(echo "$btc_block" | jq -r '.bits')
btc_bits=$(printf '%d' "0x$btc_bits_hex" 2>/dev/null || echo "$btc_bits_hex")
btc_nonce=$(echo "$btc_block" | jq -r '.nonce')
btc_timestamp=$(echo "$btc_block" | jq -r '.time')
btc_mediantime=$(echo "$btc_block" | jq -r '.mediantime')
btc_merkle=$(echo "$btc_block" | jq -r '.merkleroot')
btc_prevhash=$(echo "$btc_block" | jq -r '.previousblockhash')
brk_size=$(echo "$brk_v1" | jq -r '.size')
brk_weight=$(echo "$brk_v1" | jq -r '.weight')
brk_nTx=$(echo "$brk_v1" | jq -r '.tx_count')
brk_difficulty=$(echo "$brk_v1" | jq -r '.difficulty')
brk_version=$(echo "$brk_v1" | jq -r '.version')
brk_bits=$(echo "$brk_v1" | jq -r '.bits')
brk_nonce=$(echo "$brk_v1" | jq -r '.nonce')
brk_timestamp=$(echo "$brk_v1" | jq -r '.timestamp')
brk_mediantime=$(echo "$brk_v1" | jq -r '.mediantime')
brk_merkle=$(echo "$brk_v1" | jq -r '.merkle_root')
brk_prevhash=$(echo "$brk_v1" | jq -r '.previousblockhash')
compare "size" "$btc_size" "$brk_size"
compare "weight" "$btc_weight" "$brk_weight"
compare "nTx / tx_count" "$btc_nTx" "$brk_nTx"
compare_float "difficulty" "$btc_difficulty" "$brk_difficulty"
compare "version" "$btc_version" "$brk_version"
compare "bits" "$btc_bits" "$brk_bits"
compare "nonce" "$btc_nonce" "$brk_nonce"
compare "timestamp" "$btc_timestamp" "$brk_timestamp"
compare "mediantime" "$btc_mediantime" "$brk_mediantime"
compare "merkle_root" "$btc_merkle" "$brk_merkle"
compare "previousblockhash" "$btc_prevhash" "$brk_prevhash"
# ─── Block extras sanity checks ───
section "Block extras sanity (at tip)"
btc_block_v2=$(bitcoin-cli getblock "$brk_hash" 2 2>/dev/null || echo '{}')
if [[ "$btc_block_v2" != '{}' ]]; then
btc_total_outputs=$(echo "$btc_block_v2" | jq '[.tx[].vout | length] | add')
btc_total_inputs=$(echo "$btc_block_v2" | jq '[.tx[1:][].vin | length] | add // 0')
brk_total_outputs=$(echo "$brk_v1" | jq -r '.extras.totalOutputs')
brk_total_inputs=$(echo "$brk_v1" | jq -r '.extras.totalInputs')
compare "totalOutputs" "$btc_total_outputs" "$brk_total_outputs"
compare "totalInputs" "$btc_total_inputs" "$brk_total_inputs"
# totalOutputAmt excludes coinbase (matches mempool.space), so compare non-coinbase outputs only
btc_total_output_amt=$(echo "$btc_block_v2" | jq '[.tx[1:][].vout[].value]' | sum_btc_values_to_sats)
brk_total_output_amt=$(echo "$brk_v1" | jq -r '.extras.totalOutputAmt')
compare "totalOutputAmt (sats)" "$btc_total_output_amt" "$brk_total_output_amt"
if [[ "$btc_total_output_amt" != "$brk_total_output_amt" ]]; then
delta=$((brk_total_output_amt - btc_total_output_amt))
printf "${RED} → delta: %d sats (%.8f BTC)${NC}\n" "$delta" "$(python3 -c "print($delta / 1e8)")"
fi
# Reward = subsidy + fees. bitcoin-cli coinbase output sum = reward
btc_coinbase_value=$(echo "$btc_block_v2" | jq '[.tx[0].vout[].value]' | sum_btc_values_to_sats)
brk_reward=$(echo "$brk_v1" | jq -r '.extras.reward')
compare "reward (coinbase sats)" "$btc_coinbase_value" "$brk_reward"
# Total input amount — needs verbosity 3 for prevout data
btc_block_v3=$(bitcoin-cli getblock "$brk_hash" 3 2>/dev/null || echo '{}')
if [[ "$btc_block_v3" != '{}' ]]; then
btc_total_input_amt=$(echo "$btc_block_v3" | jq '[.tx[1:][].vin[].prevout.value]' | sum_btc_values_to_sats)
brk_total_input_amt=$(echo "$brk_v1" | jq -r '.extras.totalInputAmt')
compare "totalInputAmt (sats)" "$btc_total_input_amt" "$brk_total_input_amt"
if [[ "$btc_total_input_amt" != "$brk_total_input_amt" ]]; then
delta=$((brk_total_input_amt - btc_total_input_amt))
printf "${RED} → delta: %d sats (%.8f BTC)${NC}\n" "$delta" "$(python3 -c "print($delta / 1e8)")"
fi
# fees = non-coinbase inputs - non-coinbase outputs
btc_fees=$((btc_total_input_amt - btc_total_output_amt))
brk_fees=$(echo "$brk_v1" | jq -r '.extras.totalFees')
compare "totalFees (sats)" "$btc_fees" "$brk_fees"
else
printf " ${YELLOW}getblock verbosity 3 unavailable — skipping totalInputAmt${NC}\n"
fi
else
printf " ${YELLOW}getblock verbosity 2 unavailable${NC}\n"
fi
# ─── getmempoolinfo ───
section "getmempoolinfo vs /api/mempool"
btc_mempool=$(bitcoin-cli getmempoolinfo)
brk_mempool=$(curl -sf "$BRK/api/mempool")
btc_mp_count=$(echo "$btc_mempool" | jq -r '.size')
btc_mp_vsize=$(echo "$btc_mempool" | jq -r '.bytes')
brk_mp_count=$(echo "$brk_mempool" | jq -r '.count')
brk_mp_vsize=$(echo "$brk_mempool" | jq -r '.vsize')
printf " ${YELLOW}%-30s${NC} bitcoin-cli: %-12s brk: %-12s (live, may differ)\n" "tx count" "$btc_mp_count" "$brk_mp_count"
printf " ${YELLOW}%-30s${NC} bitcoin-cli: %-12s brk: %-12s (live, may differ)\n" "vsize" "$btc_mp_vsize" "$brk_mp_vsize"
# ─── Difficulty adjustment ───
section "Difficulty adjustment"
compare_float "current difficulty" "$(echo "$btc_block" | jq -r '.difficulty')" "$(echo "$brk_v1" | jq -r '.difficulty')"
# ─── Summary ───
section "Summary"
printf " ${GREEN}Passed: %d${NC} ${RED}Failed: %d${NC} ${YELLOW}Approximate: %d${NC}\n" "$pass" "$fail" "$warn"
if [[ $fail -gt 0 ]]; then
exit 1
fi