3 # We need access to a bitcoin-cli instance to get some basic block information and a
4 # Bitcoin Core REST instance to get batches of filter headers and headers in hex.
5 # Requires https://github.com/bitcoin/bitcoin/pull/17631 for REST filter headers.
6 # After creating the zones, we scp them to SCP_TARGET, which is expected to add a
7 # relevant SOA record, NS record(s) and possibly DNSSec-sign the zones before loading
8 # them into a nameserver (knot is generally recommended as it uses much less memory to
9 # store such large zones, though you may need to set `zonefile-load: whole`,
10 # `journal-content: none` and `semantic-checks: off` to get reasonable performance out
13 # The SOA record used on bitcoinheaders.net zones is:
14 # @ TTL_REPLACE IN SOA ns.as397444.net. dnsadmin.as397444.net. (
15 # SERIAL_REPLACE ; Serial
16 # TTL_REPLACE ; Refresh
19 # 60 ) ; Negative Cache TTL
20 # with TTL_REPLACE replaced with max(min(head -n2 headers-$I.zone | tail -n1 | awk '{ print $2 }', 2592000), 86400) / 24.
22 # It is important that your secondary nameserver(s) support NOTIFYs to ensure you can
23 # update them as new blocks come in.
27 SCP_TARGET="user@hostname"
28 BITCOIN_CLI="~/bitcoin-cli"
29 BITCOIND_REST="http://127.0.0.1/rest"
32 cc -Wall -O2 ./split.c -o split
36 if [ "$LATEST_HASH" != "$($BITCOIN_CLI getbestblockhash)" ]; then
37 LATEST_HASH=$($BITCOIN_CLI getbestblockhash)
38 echo "Updating for new hash $LATEST_HASH..."
40 COUNT=$($BITCOIN_CLI getblockcount)
42 # Break header chunks into zones of 10k headers each
43 for I in `seq 0 10000 $COUNT`; do
44 TARGET=$(($COUNT > $(($I + 9999)) ? $(($I + 9999)) : $COUNT))
47 # ...but bitcoind only provides 2000 at a time, so load them in batches
48 for J in `seq $I 2000 $TARGET`; do
49 HASH=$($BITCOIN_CLI getblockhash $J)
50 HEADERS="$HEADERS$(wget -q -O - $BITCOIND_REST/headers/2000/$HASH.hex)"
51 FILTERS="$FILTERS$(wget -q -O - $BITCOIND_REST/blockfilterheaders/basic/2000/$HASH.hex)"
54 # split returns non-0 on error or if the zone on disk ends with the same header
55 # as what we just provided, so only scp it to our nameserver if we get 0
56 if echo "$HEADERS" | ../split $I $COUNT 80 headers-$(($I / 10000)).zone; then
57 echo -e "put headers-$(($I / 10000)).zone dest/\nquit\n" | sftp $SCP_TARGET
59 if echo "$FILTERS" | ../split $I $COUNT 32 filterheaders-$(($I / 10000)).zone; then
60 echo -e "put filterheaders-$(($I / 10000)).zone dest/\nquit\n" | sftp $SCP_TARGET