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.
25 SCP_TARGET="user@hostname"
26 BITCOIN_CLI="~/bitcoin-cli"
27 BITCOIND_REST="http://127.0.0.1/rest"
30 cc -Wall -O2 ./split.c -o split
33 if [ "$LATEST_HASH" != "$($BITCOIN_CLI getbestblockhash)" ]; then
34 LATEST_HASH=$($BITCOIN_CLI getbestblockhash)
35 echo "Updating for new hash $LATEST_HASH..."
37 COUNT=$($BITCOIN_CLI getblockcount)
39 # Break header chunks into zones of 10k headers each
40 for I in `seq 0 10000 $COUNT`; do
41 TARGET=$(($COUNT > $(($I + 9999)) ? $(($I + 9999)) : $COUNT))
44 # ...but bitcoind only provides 2000 at a time, so load them in batches
45 for J in `seq $I 2000 $TARGET`; do
46 HASH=$($BITCOIN_CLI getblockhash $J)
47 HEADERS="$HEADERS$(wget -q -O - $BITCOIND_REST/headers/2000/$HASH.hex)"
48 FILTERS="$FILTERS$(wget -q -O - $BITCOIND_REST/blockfilterheaders/basic/2000/$HASH.hex)"
51 # split returns non-0 on error or if the zone on disk ends with the same header
52 # as what we just provided, so only scp it to our nameserver if we get 0
53 if echo "$HEADERS" | ./split $I $COUNT 80 headers-$(($I / 10000)).zone; then
54 echo -e "put headers-$(($I / 10000)).zone dest/\nquit\n" | sftp $SCP_TARGET
56 if echo "$FILTERS" | ./split $I $COUNT 32 filterheaders-$(($I / 10000)).zone; then
57 echo -e "put filterheaders-$(($I / 10000)).zone dest/\nquit\n" | sftp $SCP_TARGET