Skip to content

Commit

Permalink
Merge branch 'bitcoin' into auxpow
Browse files Browse the repository at this point in the history
  • Loading branch information
domob1812 committed Sep 2, 2024
2 parents 08efd59 + 1248d0d commit 7f73e23
Show file tree
Hide file tree
Showing 148 changed files with 13,558 additions and 23,900 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
AC_PREREQ([2.69])
define(_CLIENT_VERSION_MAJOR, 27)
define(_CLIENT_VERSION_MAJOR, 28)
define(_CLIENT_VERSION_MINOR, 99)
define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_RC, 0)
Expand Down
10 changes: 10 additions & 0 deletions contrib/devtools/utxo_snapshot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ if (( GENERATE_AT_HEIGHT < PRUNED )); then
exit 1
fi

# Check current block height to ensure the node has synchronized past the required block
CURRENT_BLOCK_HEIGHT=$(${BITCOIN_CLI_CALL} getblockcount)
PIVOT_BLOCK_HEIGHT=$(( GENERATE_AT_HEIGHT + 1 ))

if (( PIVOT_BLOCK_HEIGHT > CURRENT_BLOCK_HEIGHT )); then
(>&2 echo "Error: The node has not yet synchronized to block height ${PIVOT_BLOCK_HEIGHT}.")
(>&2 echo "Please wait until the node has synchronized past this block height and try again.")
exit 1
fi

# Early exit if file at OUTPUT_PATH already exists
if [[ -e "$OUTPUT_PATH" ]]; then
(>&2 echo "Error: $OUTPUT_PATH already exists or is not a valid path.")
Expand Down
1 change: 1 addition & 0 deletions contrib/seeds/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
seeds_main.txt
seeds_test.txt
asmap-filled.dat
15 changes: 11 additions & 4 deletions contrib/seeds/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,20 @@ and remove old versions as necessary (at a minimum when SeedsServiceFlags()
changes its default return value, as those are the services which seeds are added
to addrman with).

The seeds compiled into the release are created from sipa's DNS seed and AS map
data. Run the following commands from the `/contrib/seeds` directory:
The seeds compiled into the release are created from sipa's, achow101's and luke-jr's
DNS seed, virtu's crawler, and fjahr's community AS map data. Run the following commands
from the `/contrib/seeds` directory:

```
curl https://bitcoin.sipa.be/seeds.txt.gz | gzip -dc > seeds_main.txt
curl https://bitcoin.sipa.be/asmap-filled.dat > asmap-filled.dat
curl https://mainnet.achownodes.xyz/seeds.txt.gz | gzip -dc >> seeds_main.txt
curl https://21.ninja/seeds.txt.gz | gzip -dc >> seeds_main.txt
curl https://luke.dashjr.org/programs/bitcoin/files/charts/seeds.txt >> seeds_main.txt
curl https://testnet.achownodes.xyz/seeds.txt.gz | gzip -dc > seeds_test.txt
curl https://raw.githubusercontent.com/fjahr/asmap-data/main/latest_asmap.dat > asmap-filled.dat
python3 makeseeds.py -a asmap-filled.dat -s seeds_main.txt > nodes_main.txt
cat nodes_main_manual.txt >> nodes_main.txt
python3 makeseeds.py -a asmap-filled.dat -s seeds_test.txt > nodes_test.txt
# TODO: Uncomment when a seeder publishes seeds.txt.gz for testnet4
# python3 makeseeds.py -a asmap-filled.dat -s seeds_testnet4.txt -m 30000 > nodes_testnet4.txt
python3 generate-seeds.py . > ../../src/chainparamsseeds.h
```
36 changes: 23 additions & 13 deletions contrib/seeds/makeseeds.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import collections
import ipaddress
from pathlib import Path
import random
import re
import sys
from typing import Union
Expand All @@ -25,7 +26,7 @@
'ipv6': 10,
}

MIN_BLOCKS = 730000
MIN_BLOCKS = 840000

PATTERN_IPV4 = re.compile(r"^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})):(\d+)$")
PATTERN_IPV6 = re.compile(r"^\[([0-9a-z:]+)\]:(\d+)$")
Expand All @@ -41,11 +42,13 @@
r"0.19.(0|1|2|99)|"
r"0.20.(0|1|2|99)|"
r"0.21.(0|1|2|99)|"
r"22.(0|1|99)|"
r"23.(0|1|99)|"
r"24.(0|1|99)|"
r"25.(0|1|99)|"
r"26.(0|99)|"
r"22.(0|1|99).0|"
r"23.(0|1|99).0|"
r"24.(0|1|2|99).(0|1)|"
r"25.(0|1|2|99).0|"
r"26.(0|1|99).0|"
r"27.(0|1|99).0|"
r"28.(0|99).0|"
r")")

def parseline(line: str) -> Union[dict, None]:
Expand Down Expand Up @@ -86,6 +89,8 @@ def parseline(line: str) -> Union[dict, None]:
if m.group(1) in ['::']: # Not interested in localhost
return None
ipstr = m.group(1)
if ipstr.startswith("fc"): # cjdns looks like ipv6 but always begins with fc
net = "cjdns"
sortkey = ipstr # XXX parse IPv6 into number, could use name_to_ipv6 from generate-seeds
port = int(m.group(2))
else:
Expand Down Expand Up @@ -152,6 +157,7 @@ def filterbyasn(asmap: ASMap, ips: list[dict], max_per_asn: dict, max_per_net: i
ips_ipv46 = [ip for ip in ips if ip['net'] in ['ipv4', 'ipv6']]
ips_onion = [ip for ip in ips if ip['net'] == 'onion']
ips_i2p = [ip for ip in ips if ip['net'] == 'i2p']
ips_cjdns = [ip for ip in ips if ip["net"] == "cjdns"]

# Filter IPv46 by ASN, and limit to max_per_net per network
result = []
Expand All @@ -176,6 +182,7 @@ def filterbyasn(asmap: ASMap, ips: list[dict], max_per_asn: dict, max_per_net: i
# Add back Onions (up to max_per_net)
result.extend(ips_onion[0:max_per_net])
result.extend(ips_i2p[0:max_per_net])
result.extend(ips_cjdns[0:max_per_net])
return result

def ip_stats(ips: list[dict]) -> str:
Expand All @@ -185,12 +192,13 @@ def ip_stats(ips: list[dict]) -> str:
if ip is not None:
hist[ip['net']] += 1

return f"{hist['ipv4']:6d} {hist['ipv6']:6d} {hist['onion']:6d} {hist['i2p']:6d}"
return f"{hist['ipv4']:6d} {hist['ipv6']:6d} {hist['onion']:6d} {hist['i2p']:6d} {hist['cjdns']:6d}"

def parse_args():
argparser = argparse.ArgumentParser(description='Generate a list of bitcoin node seed ip addresses.')
argparser.add_argument("-a","--asmap", help='the location of the asmap asn database file (required)', required=True)
argparser.add_argument("-s","--seeds", help='the location of the DNS seeds file (required)', required=True)
argparser.add_argument("-m", "--minblocks", help="The minimum number of blocks each node must have", default=MIN_BLOCKS, type=int)
return argparser.parse_args()

def main():
Expand All @@ -205,9 +213,10 @@ def main():
with open(args.seeds, 'r', encoding='utf8') as f:
lines = f.readlines()
ips = [parseline(line) for line in lines]
random.shuffle(ips)
print('Done.', file=sys.stderr)

print('\x1b[7m IPv4 IPv6 Onion I2P Pass \x1b[0m', file=sys.stderr)
print('\x1b[7m IPv4 IPv6 Onion I2P CJDNS Pass \x1b[0m', file=sys.stderr)
print(f'{ip_stats(ips):s} Initial', file=sys.stderr)
# Skip entries with invalid address.
ips = [ip for ip in ips if ip is not None]
Expand All @@ -216,17 +225,18 @@ def main():
ips = dedup(ips)
print(f'{ip_stats(ips):s} After removing duplicates', file=sys.stderr)
# Enforce minimal number of blocks.
ips = [ip for ip in ips if ip['blocks'] >= MIN_BLOCKS]
ips = [ip for ip in ips if ip['blocks'] >= args.minblocks]
print(f'{ip_stats(ips):s} Enforce minimal number of blocks', file=sys.stderr)
# Require service bit 1.
ips = [ip for ip in ips if (ip['service'] & 1) == 1]
print(f'{ip_stats(ips):s} Require service bit 1', file=sys.stderr)
# Require at least 50% 30-day uptime for clearnet, 10% for onion and i2p.
# Require at least 50% 30-day uptime for clearnet, onion and i2p; 10% for cjdns
req_uptime = {
'ipv4': 50,
'ipv6': 50,
'onion': 10,
'i2p' : 10,
'onion': 50,
'i2p': 50,
'cjdns': 10,
}
ips = [ip for ip in ips if ip['uptime'] > req_uptime[ip['net']]]
print(f'{ip_stats(ips):s} Require minimum uptime', file=sys.stderr)
Expand All @@ -244,7 +254,7 @@ def main():
# Sort the results by IP address (for deterministic output).
ips.sort(key=lambda x: (x['net'], x['sortkey']))
for ip in ips:
if ip['net'] == 'ipv6':
if ip['net'] == 'ipv6' or ip["net"] == "cjdns":
print(f"[{ip['ip']}]:{ip['port']}", end="")
else:
print(f"{ip['ip']}:{ip['port']}", end="")
Expand Down
Loading

0 comments on commit 7f73e23

Please sign in to comment.