2017-02-11 08:46:00 +01:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# Copyright (c) 2014-2017 Wladimir J. van der Laan
|
2014-10-28 03:10:59 +01:00
|
|
|
# Distributed under the MIT software license, see the accompanying
|
2014-07-24 13:52:57 +02:00
|
|
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
'''
|
|
|
|
Script to generate list of seed nodes for chainparams.cpp.
|
|
|
|
|
|
|
|
This script expects two text files in the directory that is passed as an
|
|
|
|
argument:
|
|
|
|
|
|
|
|
nodes_main.txt
|
|
|
|
nodes_test.txt
|
|
|
|
|
2018-06-16 15:21:01 +02:00
|
|
|
These files must consist of lines in the format
|
2014-07-24 13:52:57 +02:00
|
|
|
|
|
|
|
<ip>
|
|
|
|
<ip>:<port>
|
|
|
|
[<ipv6>]
|
|
|
|
[<ipv6>]:<port>
|
|
|
|
<onion>.onion
|
|
|
|
0xDDBBCCAA (IPv4 little-endian old pnSeeds format)
|
|
|
|
|
|
|
|
The output will be two data structures with the peers in binary format:
|
|
|
|
|
|
|
|
static SeedSpec6 pnSeed6_main[]={
|
|
|
|
...
|
|
|
|
}
|
|
|
|
static SeedSpec6 pnSeed6_test[]={
|
|
|
|
...
|
|
|
|
}
|
|
|
|
|
|
|
|
These should be pasted into `src/chainparamsseeds.h`.
|
|
|
|
'''
|
2017-02-11 08:46:00 +01:00
|
|
|
|
2014-07-24 13:52:57 +02:00
|
|
|
from base64 import b32decode
|
|
|
|
from binascii import a2b_hex
|
Merge #12987: tests/tools: Enable additional Python flake8 rules for automatic linting via Travis
643aad17fa Enable additional flake8 rules (practicalswift)
f020aca297 Minor Python cleanups to make flake8 pass with the new rules enabled (practicalswift)
Pull request description:
Enabled rules:
```
* E242: tab after ','
* E266: too many leading '#' for block comment
* E401: multiple imports on one line
* E402: module level import not at top of file
* E701: multiple statements on one line (colon)
* E901: SyntaxError: invalid syntax
* E902: TokenError: EOF in multi-line string
* F821: undefined name 'Foo'
* W293: blank line contains whitespace
* W606: 'async' and 'await' are reserved keywords starting with Python 3.7
```
Note to reviewers:
* In general we don't allow whitespace cleanups to existing code, but in order to allow for enabling Travis checking for these rules a few smaller whitespace cleanups had to made as part of this PR.
* Use [this `?w=1` link](https://github.com/bitcoin/bitcoin/pull/12987/files?w=1) to show a diff without whitespace changes.
Before this commit:
```
$ flake8 -qq --statistics --ignore=B,C,E,F,I,N,W --select=E112,E113,E115,E116,E125,E131,E133,E223,E224,E242,E266,E271,E272,E273,E274,E275,E304,E306,E401,E402,E502,E701,E702,E703,E714,E721,E741,E742,E743,F401,E901,E902,F402,F404,F406,F407,F601,F602,F621,F622,F631,F701,F702,F703,F704,F705,F706,F707,F811,F812,F821,F822,F823,F831,F841,W292,W293,W504,W601,W602,W603,W604,W605,W606 .
5 E266 too many leading '#' for block comment
4 E401 multiple imports on one line
6 E402 module level import not at top of file
5 E701 multiple statements on one line (colon)
1 F812 list comprehension redefines 'n' from line 159
4 F821 undefined name 'ConnectionRefusedError'
28 W293 blank line contains whitespace
```
After this commit:
```
$ flake8 -qq --statistics --ignore=B,C,E,F,I,N,W --select=E112,E113,E115,E116,E125,E131,E133,E223,E224,E242,E266,E271,E272,E273,E274,E275,E304,E306,E401,E402,E502,E701,E702,E703,E714,E721,E741,E742,E743,F401,E901,E902,F402,F404,F406,F407,F601,F602,F621,F622,F631,F701,F702,F703,F704,F705,F706,F707,F811,F812,F821,F822,F823,F831,F841,W292,W293,W504,W601,W602,W603,W604,W605,W606 .
$
```
Tree-SHA512: fc7d5e752298a50d4248afc620ee2c173135b4ca008e48e02913ac968e5a24a5fd5396926047ec62f1d580d537434ccae01f249bb2f3338fa59dc630bf97ca7a
Signed-off-by: pasta <pasta@dashboost.org>
2018-04-16 17:49:49 +02:00
|
|
|
import sys
|
|
|
|
import os
|
2014-07-24 13:52:57 +02:00
|
|
|
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'):
|
|
|
|
vchAddr = b32decode(addr[0:-6], True)
|
|
|
|
if len(vchAddr) != 16-len(pchOnionCat):
|
Merge #12987: tests/tools: Enable additional Python flake8 rules for automatic linting via Travis
643aad17fa Enable additional flake8 rules (practicalswift)
f020aca297 Minor Python cleanups to make flake8 pass with the new rules enabled (practicalswift)
Pull request description:
Enabled rules:
```
* E242: tab after ','
* E266: too many leading '#' for block comment
* E401: multiple imports on one line
* E402: module level import not at top of file
* E701: multiple statements on one line (colon)
* E901: SyntaxError: invalid syntax
* E902: TokenError: EOF in multi-line string
* F821: undefined name 'Foo'
* W293: blank line contains whitespace
* W606: 'async' and 'await' are reserved keywords starting with Python 3.7
```
Note to reviewers:
* In general we don't allow whitespace cleanups to existing code, but in order to allow for enabling Travis checking for these rules a few smaller whitespace cleanups had to made as part of this PR.
* Use [this `?w=1` link](https://github.com/bitcoin/bitcoin/pull/12987/files?w=1) to show a diff without whitespace changes.
Before this commit:
```
$ flake8 -qq --statistics --ignore=B,C,E,F,I,N,W --select=E112,E113,E115,E116,E125,E131,E133,E223,E224,E242,E266,E271,E272,E273,E274,E275,E304,E306,E401,E402,E502,E701,E702,E703,E714,E721,E741,E742,E743,F401,E901,E902,F402,F404,F406,F407,F601,F602,F621,F622,F631,F701,F702,F703,F704,F705,F706,F707,F811,F812,F821,F822,F823,F831,F841,W292,W293,W504,W601,W602,W603,W604,W605,W606 .
5 E266 too many leading '#' for block comment
4 E401 multiple imports on one line
6 E402 module level import not at top of file
5 E701 multiple statements on one line (colon)
1 F812 list comprehension redefines 'n' from line 159
4 F821 undefined name 'ConnectionRefusedError'
28 W293 blank line contains whitespace
```
After this commit:
```
$ flake8 -qq --statistics --ignore=B,C,E,F,I,N,W --select=E112,E113,E115,E116,E125,E131,E133,E223,E224,E242,E266,E271,E272,E273,E274,E275,E304,E306,E401,E402,E502,E701,E702,E703,E714,E721,E741,E742,E743,F401,E901,E902,F402,F404,F406,F407,F601,F602,F621,F622,F631,F701,F702,F703,F704,F705,F706,F707,F811,F812,F821,F822,F823,F831,F841,W292,W293,W504,W601,W602,W603,W604,W605,W606 .
$
```
Tree-SHA512: fc7d5e752298a50d4248afc620ee2c173135b4ca008e48e02913ac968e5a24a5fd5396926047ec62f1d580d537434ccae01f249bb2f3338fa59dc630bf97ca7a
Signed-off-by: pasta <pasta@dashboost.org>
2018-04-16 17:49:49 +02:00
|
|
|
raise ValueError('Invalid onion %s' % vchAddr)
|
2014-07-24 13:52:57 +02:00
|
|
|
return pchOnionCat + vchAddr
|
|
|
|
elif '.' in addr: # IPv4
|
|
|
|
return pchIPv4 + bytearray((int(x) for x in addr.split('.')))
|
|
|
|
elif ':' in addr: # IPv6
|
|
|
|
sub = [[], []] # prefix, suffix
|
|
|
|
x = 0
|
|
|
|
addr = addr.split(':')
|
|
|
|
for i,comp in enumerate(addr):
|
|
|
|
if comp == '':
|
|
|
|
if i == 0 or i == (len(addr)-1): # skip empty component at beginning or end
|
|
|
|
continue
|
|
|
|
x += 1 # :: skips to suffix
|
|
|
|
assert(x < 2)
|
|
|
|
else: # two bytes per component
|
|
|
|
val = int(comp, 16)
|
|
|
|
sub[x].append(val >> 8)
|
|
|
|
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:])))
|
|
|
|
else:
|
|
|
|
raise ValueError('Could not parse address %s' % addr)
|
|
|
|
|
|
|
|
def parse_spec(s, defaultport):
|
|
|
|
match = re.match('\[([0-9a-fA-F:]+)\](?::([0-9]+))?$', s)
|
|
|
|
if match: # ipv6
|
|
|
|
host = match.group(1)
|
|
|
|
port = match.group(2)
|
2015-06-23 21:31:47 +02:00
|
|
|
elif s.count(':') > 1: # ipv6, no port
|
|
|
|
host = s
|
|
|
|
port = ''
|
2014-07-24 13:52:57 +02:00
|
|
|
else:
|
|
|
|
(host,_,port) = s.partition(':')
|
|
|
|
|
|
|
|
if not port:
|
|
|
|
port = defaultport
|
|
|
|
else:
|
|
|
|
port = int(port)
|
|
|
|
|
|
|
|
host = name_to_ipv6(host)
|
|
|
|
|
|
|
|
return (host,port)
|
|
|
|
|
|
|
|
def process_nodes(g, f, structname, defaultport):
|
|
|
|
g.write('static SeedSpec6 %s[] = {\n' % structname)
|
|
|
|
first = True
|
|
|
|
for line in f:
|
|
|
|
comment = line.find('#')
|
|
|
|
if comment != -1:
|
|
|
|
line = line[0:comment]
|
|
|
|
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')
|
|
|
|
|
|
|
|
def main():
|
|
|
|
if len(sys.argv)<2:
|
|
|
|
print(('Usage: %s <path_to_nodes_txt>' % sys.argv[0]), file=sys.stderr)
|
2017-08-28 22:53:34 +02:00
|
|
|
sys.exit(1)
|
2014-07-24 13:52:57 +02:00
|
|
|
g = sys.stdout
|
|
|
|
indir = sys.argv[1]
|
2020-11-08 15:45:32 +01:00
|
|
|
g.write('#ifndef BITCOIN_CHAINPARAMSSEEDS_H\n')
|
|
|
|
g.write('#define BITCOIN_CHAINPARAMSSEEDS_H\n')
|
2014-10-28 03:10:59 +01:00
|
|
|
g.write('/**\n')
|
2015-04-05 23:56:58 +02:00
|
|
|
g.write(' * List of fixed seed nodes for the dash network\n')
|
2015-06-23 21:31:47 +02:00
|
|
|
g.write(' * AUTOGENERATED by contrib/seeds/generate-seeds.py\n')
|
2014-10-28 03:10:59 +01:00
|
|
|
g.write(' *\n')
|
|
|
|
g.write(' * Each line contains a 16-byte IPv6 address and a port.\n')
|
2018-02-12 10:47:05 +01:00
|
|
|
g.write(' * IPv4 as well as onion addresses are wrapped inside an IPv6 address accordingly.\n')
|
2014-10-28 03:10:59 +01:00
|
|
|
g.write(' */\n')
|
2018-06-16 15:21:01 +02:00
|
|
|
with open(os.path.join(indir,'nodes_main.txt'), 'r', encoding="utf8") as f:
|
2015-04-05 23:56:58 +02:00
|
|
|
process_nodes(g, f, 'pnSeed6_main', 9999)
|
2014-07-24 13:52:57 +02:00
|
|
|
g.write('\n')
|
2018-06-16 15:21:01 +02:00
|
|
|
with open(os.path.join(indir,'nodes_test.txt'), 'r', encoding="utf8") as f:
|
2015-04-05 23:56:58 +02:00
|
|
|
process_nodes(g, f, 'pnSeed6_test', 19999)
|
2020-11-08 15:45:32 +01:00
|
|
|
g.write('#endif // BITCOIN_CHAINPARAMSSEEDS_H\n')
|
2018-06-16 15:21:01 +02:00
|
|
|
|
2014-07-24 13:52:57 +02:00
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|
|
|
|
|