diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py index 257474e000..44345e3987 100755 --- a/contrib/seeds/generate-seeds.py +++ b/contrib/seeds/generate-seeds.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2017 Wladimir J. van der Laan +# Copyright (c) 2014-2021 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' @@ -13,19 +13,14 @@ argument: These files must consist of lines in the format - : - [] []: - .onion - 0xDDBBCCAA (IPv4 little-endian old pnSeeds format) + .onion: + .b32.i2p: The output will be two data structures with the peers in binary format: - static SeedSpec6 pnSeed6_main[]={ - ... - } - static SeedSpec6 pnSeed6_test[]={ + static const uint8_t chainparams_seed_{main,test}[]={ ... } @@ -33,25 +28,40 @@ These should be pasted into `src/chainparamsseeds.h`. ''' from base64 import b32decode -from binascii import a2b_hex +from enum import Enum +import struct import sys import os import re -# ipv4 in ipv6 prefix -pchIPv4 = bytearray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff]) -# tor-specific ipv6 prefix -pchOnionCat = bytearray([0xFD,0x87,0xD8,0x7E,0xEB,0x43]) - -def name_to_ipv6(addr): - if len(addr)>6 and addr.endswith('.onion'): +class BIP155Network(Enum): + IPV4 = 1 + IPV6 = 2 + TORV2 = 3 # no longer supported + TORV3 = 4 + I2P = 5 + CJDNS = 6 + +def name_to_bip155(addr): + '''Convert address string to BIP155 (networkID, addr) tuple.''' + if addr.endswith('.onion'): vchAddr = b32decode(addr[0:-6], True) - if len(vchAddr) != 16-len(pchOnionCat): + if len(vchAddr) == 35: + assert vchAddr[34] == 3 + return (BIP155Network.TORV3, vchAddr[:32]) + elif len(vchAddr) == 10: + return (BIP155Network.TORV2, vchAddr) + else: raise ValueError('Invalid onion %s' % vchAddr) - return pchOnionCat + vchAddr + elif addr.endswith('.b32.i2p'): + vchAddr = b32decode(addr[0:-8] + '====', True) + if len(vchAddr) == 32: + return (BIP155Network.I2P, vchAddr) + else: + raise ValueError(f'Invalid I2P {vchAddr}') elif '.' in addr: # IPv4 - return pchIPv4 + bytearray((int(x) for x in addr.split('.'))) - elif ':' in addr: # IPv6 + return (BIP155Network.IPV4, bytes((int(x) for x in addr.split('.')))) + elif ':' in addr: # IPv6 or CJDNS sub = [[], []] # prefix, suffix x = 0 addr = addr.split(':') @@ -67,13 +77,19 @@ def name_to_ipv6(addr): sub[x].append(val & 0xff) nullbytes = 16 - len(sub[0]) - len(sub[1]) assert((x == 0 and nullbytes == 0) or (x == 1 and nullbytes > 0)) - return bytearray(sub[0] + ([0] * nullbytes) + sub[1]) - elif addr.startswith('0x'): # IPv4-in-little-endian - return pchIPv4 + bytearray(reversed(a2b_hex(addr[2:]))) + addr_bytes = bytes(sub[0] + ([0] * nullbytes) + sub[1]) + if addr_bytes[0] == 0xfc: + # Assume that seeds with fc00::/8 addresses belong to CJDNS, + # not to the publicly unroutable "Unique Local Unicast" network, see + # RFC4193: https://datatracker.ietf.org/doc/html/rfc4193#section-8 + return (BIP155Network.CJDNS, addr_bytes) + else: + return (BIP155Network.IPV6, addr_bytes) else: raise ValueError('Could not parse address %s' % addr) -def parse_spec(s, defaultport): +def parse_spec(s): + '''Convert endpoint string to BIP155 (networkID, addr, port) tuple.''' match = re.match(r'\[([0-9a-fA-F:]+)\](?::([0-9]+))?$', s) if match: # ipv6 host = match.group(1) @@ -85,17 +101,42 @@ def parse_spec(s, defaultport): (host,_,port) = s.partition(':') if not port: - port = defaultport + port = 0 else: port = int(port) - host = name_to_ipv6(host) - - return (host,port) + host = name_to_bip155(host) -def process_nodes(g, f, structname, defaultport): - g.write('static SeedSpec6 %s[] = {\n' % structname) - first = True + if host[0] == BIP155Network.TORV2: + return None # TORV2 is no longer supported, so we ignore it + else: + return host + (port, ) + +def ser_compact_size(l): + r = b"" + if l < 253: + r = struct.pack("B", l) + elif l < 0x10000: + r = struct.pack("H', spec[2]) + return r + +def process_nodes(g, f, structname): + g.write('static const uint8_t %s[] = {\n' % structname) for line in f: comment = line.find('#') if comment != -1: @@ -103,14 +144,14 @@ def process_nodes(g, f, structname, defaultport): line = line.strip() if not line: continue - if not first: - g.write(',\n') - first = False - (host,port) = parse_spec(line, defaultport) - hoststr = ','.join(('0x%02x' % b) for b in host) - g.write(' {{%s}, %i}' % (hoststr, port)) - g.write('\n};\n') + spec = parse_spec(line) + if spec is None: # ignore this entry (e.g. no longer supported addresses like TORV2) + continue + blob = bip155_serialize(spec) + hoststr = ','.join(('0x%02x' % b) for b in blob) + g.write(f' {hoststr},\n') + g.write('};\n') def main(): if len(sys.argv)<2: @@ -121,17 +162,16 @@ def main(): g.write('#ifndef BITCOIN_CHAINPARAMSSEEDS_H\n') g.write('#define BITCOIN_CHAINPARAMSSEEDS_H\n') g.write('/**\n') - g.write(' * List of fixed seed nodes for the litecoin network\n') + g.write(' * List of fixed seed nodes for the bitcoin network\n') g.write(' * AUTOGENERATED by contrib/seeds/generate-seeds.py\n') g.write(' *\n') - g.write(' * Each line contains a 16-byte IPv6 address and a port.\n') - g.write(' * IPv4 as well as onion addresses are wrapped inside an IPv6 address accordingly.\n') + g.write(' * Each line contains a BIP155 serialized (networkID, addr, port) tuple.\n') g.write(' */\n') with open(os.path.join(indir,'nodes_main.txt'), 'r', encoding="utf8") as f: - process_nodes(g, f, 'pnSeed6_main', 9333) + process_nodes(g, f, 'chainparams_seed_main') g.write('\n') with open(os.path.join(indir,'nodes_test.txt'), 'r', encoding="utf8") as f: - process_nodes(g, f, 'pnSeed6_test', 19335) + process_nodes(g, f, 'chainparams_seed_test') g.write('#endif // BITCOIN_CHAINPARAMSSEEDS_H\n') if __name__ == '__main__': diff --git a/contrib/seeds/nodes_main.txt b/contrib/seeds/nodes_main.txt index 26c7aec77d..a7b1cd9ad9 100644 --- a/contrib/seeds/nodes_main.txt +++ b/contrib/seeds/nodes_main.txt @@ -12,4 +12,6 @@ 154.22.123.138:9333 174.62.70.234:9333 178.62.46.195:9333 -213.244.192.149:9333 \ No newline at end of file +213.244.192.149:9333 +xtmsopiy2ssu2vumfmnjq3nyflnq2pkpcxndi6rxgwnkljmzijafozqd.onion:9333 +37am23y5vro3iorqlmjjty7ctsgz6myoaushxrfqct4ngakl7d7idgid.onion:9333 \ No newline at end of file diff --git a/contrib/seeds/nodes_test.txt b/contrib/seeds/nodes_test.txt index e8d57265d8..b1d909ef27 100644 --- a/contrib/seeds/nodes_test.txt +++ b/contrib/seeds/nodes_test.txt @@ -27,3 +27,5 @@ 202.238.193.15:19335 203.216.0.105:19335 212.83.174.255:19335 +mxk7vkfxvtap2aikbjqcx7b4eex2yiag5v5vhuljnvurpybv4a6q5cqd.onion:19335 +octnr6yzgosiupuuivgla67p3ml6pc5qpozqn7zpmpbxge6pq5iq4had.onion:19335 \ No newline at end of file diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 5a703e5f40..cd42901544 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -139,7 +139,7 @@ public: bech32_hrp = "ltc"; mweb_hrp = "ltcmweb"; - vFixedSeeds = std::vector(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main)); + vFixedSeeds = std::vector(std::begin(chainparams_seed_main), std::end(chainparams_seed_main)); fDefaultConsistencyChecks = false; fRequireStandard = true; @@ -249,7 +249,7 @@ public: bech32_hrp = "tltc"; mweb_hrp = "tmweb"; - vFixedSeeds = std::vector(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test)); + vFixedSeeds = std::vector(std::begin(chainparams_seed_test), std::end(chainparams_seed_test)); fDefaultConsistencyChecks = false; fRequireStandard = false; diff --git a/src/chainparams.h b/src/chainparams.h index a48fbd8535..ffeb1f30a2 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -90,7 +90,7 @@ public: const std::vector& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } const std::string& Bech32HRP() const { return bech32_hrp; } const std::string& MWEB_HRP() const { return mweb_hrp; } - const std::vector& FixedSeeds() const { return vFixedSeeds; } + const std::vector& FixedSeeds() const { return vFixedSeeds; } const CCheckpointData& Checkpoints() const { return checkpointData; } const ChainTxData& TxData() const { return chainTxData; } protected: @@ -108,7 +108,7 @@ protected: std::string mweb_hrp; std::string strNetworkID; CBlock genesis; - std::vector vFixedSeeds; + std::vector vFixedSeeds; bool fDefaultConsistencyChecks; bool fRequireStandard; bool m_is_test_chain; diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index 47f019fadf..143f2f8ca3 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -1,59 +1,62 @@ #ifndef BITCOIN_CHAINPARAMSSEEDS_H #define BITCOIN_CHAINPARAMSSEEDS_H /** - * List of fixed seed nodes for the litecoin network + * List of fixed seed nodes for the bitcoin network * AUTOGENERATED by contrib/seeds/generate-seeds.py * - * Each line contains a 16-byte IPv6 address and a port. - * IPv4 as well as onion addresses are wrapped inside an IPv6 address accordingly. + * Each line contains a BIP155 serialized (networkID, addr, port) tuple. */ -static SeedSpec6 pnSeed6_main[] = { - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x08,0xd6,0x9a,0x19}, 9333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x27,0x68,0xa3,0xc8}, 9333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x5a,0x89,0x79}, 9333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0xfd,0x39,0xd7}, 9333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd7,0x7f,0x49}, 9333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xa4,0xc4,0xef}, 9333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x3f,0xaa,0x56}, 9333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x02,0x44,0xfa}, 9333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x0a,0x6e,0x8f}, 9333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x03,0x26,0xf7}, 9333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8f,0xb2,0x39,0x03}, 9333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9a,0x16,0x7b,0x8a}, 9333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x3e,0x46,0xea}, 9333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x2e,0xc3}, 9333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xf4,0xc0,0x95}, 9333} +static const uint8_t chainparams_seed_main[] = { + 0x01,0x04,0x08,0xd6,0x9a,0x19,0x24,0x75, + 0x01,0x04,0x27,0x68,0xa3,0xc8,0x24,0x75, + 0x01,0x04,0x2f,0x5a,0x89,0x79,0x24,0x75, + 0x01,0x04,0x2f,0xfd,0x39,0xd7,0x24,0x75, + 0x01,0x04,0x3e,0xd7,0x7f,0x49,0x24,0x75, + 0x01,0x04,0x45,0xa4,0xc4,0xef,0x24,0x75, + 0x01,0x04,0x46,0x3f,0xaa,0x56,0x24,0x75, + 0x01,0x04,0x55,0x02,0x44,0xfa,0x24,0x75, + 0x01,0x04,0x56,0x0a,0x6e,0x8f,0x24,0x75, + 0x01,0x04,0x68,0x03,0x26,0xf7,0x24,0x75, + 0x01,0x04,0x8f,0xb2,0x39,0x03,0x24,0x75, + 0x01,0x04,0x9a,0x16,0x7b,0x8a,0x24,0x75, + 0x01,0x04,0xae,0x3e,0x46,0xea,0x24,0x75, + 0x01,0x04,0xb2,0x3e,0x2e,0xc3,0x24,0x75, + 0x01,0x04,0xd5,0xf4,0xc0,0x95,0x24,0x75, + 0x04,0x20,0xbc,0xd9,0x27,0x3d,0x18,0xd4,0xa5,0x4d,0x56,0x8c,0x2b,0x1a,0x98,0x6d,0xb8,0x2a,0xdb,0x0d,0x3d,0x4f,0x15,0xda,0x34,0x7a,0x37,0x35,0x9a,0xa5,0xa5,0x99,0x42,0x40,0x24,0x75, + 0x04,0x20,0xdf,0xc0,0xcd,0x6f,0x1d,0xac,0x5d,0xb4,0x3a,0x30,0x5b,0x12,0x99,0xe3,0xe2,0x9c,0x8d,0x9f,0x33,0x0e,0x05,0x24,0x7b,0xc4,0xb0,0x14,0xf8,0xd3,0x01,0x4b,0xf8,0xfe,0x24,0x75, }; -static SeedSpec6 pnSeed6_test[] = { - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x03,0x89,0x44,0x8c}, 49333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x96,0x70}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x3b,0x39,0x60}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x27,0x64,0x63,0x74}, 30008}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x0f,0x73,0x61}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0x0d,0x2a,0x7d}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xff,0x80,0x6e}, 19333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xab,0xa1,0xcb}, 19333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0xe3,0x13,0x5c}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x1c,0xe1,0xa0}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x62,0x9f,0x07}, 19333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x26,0x03,0xc7}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x27,0x68,0xa7}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xa0,0x9f,0x2d}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x4f,0x37,0x1c}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd8,0x4c,0xe0}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x64,0x19,0x78,0x9a}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xe7,0xbf,0x07}, 19333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xed,0x83,0x8a}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8e,0x5d,0xc6,0x68}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x93,0x87,0x0b,0x7c}, 49333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xd1,0x28,0x3d}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xd1,0x2a,0x07}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x2e,0xc3}, 19333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xb4,0xdd,0xc9}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x3a,0x66,0x12}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0xee,0xc1,0x0f}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0xd8,0x00,0x69}, 19335}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x53,0xae,0xff}, 19335} +static const uint8_t chainparams_seed_test[] = { + 0x01,0x04,0x03,0x89,0x44,0x8c,0xc0,0xb5, + 0x01,0x04,0x05,0x09,0x96,0x70,0x4b,0x87, + 0x01,0x04,0x25,0x3b,0x39,0x60,0x4b,0x87, + 0x01,0x04,0x27,0x64,0x63,0x74,0x75,0x38, + 0x01,0x04,0x33,0x0f,0x73,0x61,0x4b,0x87, + 0x01,0x04,0x34,0x0d,0x2a,0x7d,0x4b,0x87, + 0x01,0x04,0x36,0xff,0x80,0x6e,0x4b,0x85, + 0x01,0x04,0x3e,0xab,0xa1,0xcb,0x4b,0x85, + 0x01,0x04,0x40,0xe3,0x13,0x5c,0x4b,0x87, + 0x01,0x04,0x4e,0x1c,0xe1,0xa0,0x4b,0x87, + 0x01,0x04,0x4f,0x62,0x9f,0x07,0x4b,0x85, + 0x01,0x04,0x54,0x26,0x03,0xc7,0x4b,0x87, + 0x01,0x04,0x59,0x27,0x68,0xa7,0x4b,0x87, + 0x01,0x04,0x59,0xa0,0x9f,0x2d,0x4b,0x87, + 0x01,0x04,0x5e,0x4f,0x37,0x1c,0x4b,0x87, + 0x01,0x04,0x5f,0xd8,0x4c,0xe0,0x4b,0x87, + 0x01,0x04,0x64,0x19,0x78,0x9a,0x4b,0x87, + 0x01,0x04,0x67,0xe7,0xbf,0x07,0x4b,0x85, + 0x01,0x04,0x68,0xed,0x83,0x8a,0x4b,0x87, + 0x01,0x04,0x8e,0x5d,0xc6,0x68,0x4b,0x87, + 0x01,0x04,0x93,0x87,0x0b,0x7c,0xc0,0xb5, + 0x01,0x04,0xad,0xd1,0x28,0x3d,0x4b,0x87, + 0x01,0x04,0xad,0xd1,0x2a,0x07,0x4b,0x87, + 0x01,0x04,0xb2,0x3e,0x2e,0xc3,0x4b,0x85, + 0x01,0x04,0xb9,0xb4,0xdd,0xc9,0x4b,0x87, + 0x01,0x04,0xc6,0x3a,0x66,0x12,0x4b,0x87, + 0x01,0x04,0xca,0xee,0xc1,0x0f,0x4b,0x87, + 0x01,0x04,0xcb,0xd8,0x00,0x69,0x4b,0x87, + 0x01,0x04,0xd4,0x53,0xae,0xff,0x4b,0x87, + 0x04,0x20,0x65,0xd5,0xfa,0xa8,0xb7,0xac,0xc0,0xfd,0x01,0x0a,0x0a,0x60,0x2b,0xfc,0x3c,0x21,0x2f,0xac,0x20,0x06,0xed,0x7b,0x53,0xd1,0x69,0x6d,0x69,0x17,0xe0,0x35,0xe0,0x3d,0x4b,0x87, + 0x04,0x20,0x70,0xa6,0xd8,0xfb,0x19,0x33,0xa4,0x8a,0x3e,0x94,0x45,0x4c,0xb0,0x7b,0xef,0xdb,0x17,0xe7,0x8b,0xb0,0x7b,0xb3,0x06,0xff,0x2f,0x63,0xc3,0x73,0x13,0xcf,0x87,0x51,0x4b,0x87, }; #endif // BITCOIN_CHAINPARAMSSEEDS_H diff --git a/src/net.cpp b/src/net.cpp index b3d1d1da6c..46e53924db 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -157,22 +157,23 @@ bool GetLocal(CService& addr, const CNetAddr *paddrPeer) return nBestScore >= 0; } -//! Convert the pnSeed6 array into usable address objects. -static std::vector convertSeed6(const std::vector &vSeedsIn) +//! Convert the serialized seeds into usable address objects. +static std::vector ConvertSeeds(const std::vector& vSeedsIn) { // It'll only connect to one or two seed nodes because once it connects, // it'll get a pile of addresses with newer timestamps. // Seed nodes are given a random 'last seen time' of between one and two // weeks ago. - const int64_t nOneWeek = 7*24*60*60; + const int64_t nOneWeek = 7 * 24 * 60 * 60; std::vector vSeedsOut; - vSeedsOut.reserve(vSeedsIn.size()); FastRandomContext rng; - for (const auto& seed_in : vSeedsIn) { - struct in6_addr ip; - memcpy(&ip, seed_in.addr, sizeof(ip)); - CAddress addr(CService(ip, seed_in.port), GetDesirableServiceFlags(NODE_NONE)); + CDataStream s(vSeedsIn, SER_NETWORK, PROTOCOL_VERSION | ADDRV2_FORMAT); + while (!s.eof()) { + CService endpoint; + s >> endpoint; + CAddress addr{endpoint, GetDesirableServiceFlags(NODE_NONE)}; addr.nTime = GetTime() - rng.randrange(nOneWeek) - nOneWeek; + LogPrint(BCLog::NET, "Added hardcoded seed: %s\n", addr.ToString()); vSeedsOut.push_back(addr); } return vSeedsOut; @@ -1906,7 +1907,7 @@ void CConnman::ThreadOpenConnections(const std::vector connect) LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n"); CNetAddr local; local.SetInternal("fixedseeds"); - addrman.Add(convertSeed6(Params().FixedSeeds()), local); + addrman.Add(ConvertSeeds(Params().FixedSeeds()), local); done = true; } }