Skip to content

Commit

Permalink
Merge bitcoin#29561: Fixed seeds update for 27.0
Browse files Browse the repository at this point in the history
7ab5439 seeds: Update testnet seeds (Ava Chow)
34a233b seeds: Update mainnet seeds (Ava Chow)
9701bc4 makeseeds: Check i2p seeds too (Ava Chow)
a8ec9ee makeseeds: Update PATTERN_AGENT (Ava Chow)

Pull request description:

  The ipv4 and ipv6 seeds are updated from sipa's crawler, as outlined in contrib/seeds/README.md. The onion and i2p seeds are pulled from my node's addrman using `getrawaddrman` and then a connection was made to each node to retrieve the current service flags, block height, and user agent string before filtering through makeseeds.py. The CJDNS nodes were not updated as my node is not connected to that network.

  makeseeds.py is also updated for more recent user agent strings as well as being able to handle i2p addresses.

  Also updated the testnet seeds.

ACKs for top commit:
  fanquake:
    ACK 7ab5439

Tree-SHA512: 5edba63d51116e5d9a8ae23561ba5a311f4df88c555c60b2d7a6066e63f8cdfd256be7dac9acea4b370879d0d3c3a4b55328c15de4284b5f0d86e6cac2e5ba9b
  • Loading branch information
fanquake committed Mar 6, 2024
2 parents 6c77dbf + 7ab5439 commit 55bd5d8
Show file tree
Hide file tree
Showing 5 changed files with 4,183 additions and 1,646 deletions.
21 changes: 16 additions & 5 deletions contrib/seeds/makeseeds.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
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+)$")
PATTERN_ONION = re.compile(r"^([a-z2-7]{56}\.onion):(\d+)$")
PATTERN_I2P = re.compile(r"^([a-z2-7]{52}\.b32.i2p):(\d+)$")
PATTERN_AGENT = re.compile(
r"^/Satoshi:("
r"0.14.(0|1|2|3|99)|"
Expand All @@ -40,7 +41,8 @@
r"22.(0|1|99)|"
r"23.(0|1|99)|"
r"24.(0|1|99)|"
r"25.99"
r"25.(0|1|99)|"
r"26.(0|99)|"
r")")

def parseline(line: str) -> Union[dict, None]:
Expand All @@ -65,7 +67,13 @@ def parseline(line: str) -> Union[dict, None]:
if m is None:
m = PATTERN_ONION.match(sline[0])
if m is None:
return None
m = PATTERN_I2P.match(sline[0])
if m is None:
return None
else:
net = 'i2p'
ipstr = sortkey = m.group(1)
port = int(m.group(2))
else:
net = 'onion'
ipstr = sortkey = m.group(1)
Expand Down Expand Up @@ -140,6 +148,7 @@ def filterbyasn(asmap: ASMap, ips: list[dict], max_per_asn: dict, max_per_net: i
# Sift out ips by type
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']

# Filter IPv46 by ASN, and limit to max_per_net per network
result = []
Expand All @@ -163,6 +172,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])
return result

def ip_stats(ips: list[dict]) -> str:
Expand All @@ -172,7 +182,7 @@ 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}"
return f"{hist['ipv4']:6d} {hist['ipv6']:6d} {hist['onion']:6d} {hist['i2p']:6d}"

def parse_args():
argparser = argparse.ArgumentParser(description='Generate a list of bitcoin node seed ip addresses.')
Expand All @@ -194,7 +204,7 @@ def main():
ips = [parseline(line) for line in lines]
print('Done.', file=sys.stderr)

print('\x1b[7m IPv4 IPv6 Onion Pass \x1b[0m', file=sys.stderr)
print('\x1b[7m IPv4 IPv6 Onion I2P 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 @@ -208,11 +218,12 @@ def main():
# 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.
# Require at least 50% 30-day uptime for clearnet, 10% for onion and i2p.
req_uptime = {
'ipv4': 50,
'ipv6': 50,
'onion': 10,
'i2p' : 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 Down
Loading

0 comments on commit 55bd5d8

Please sign in to comment.