diff options
-rw-r--r-- | contrib/misc/example-linearize.cfg | 12 | ||||
-rwxr-xr-x | contrib/misc/linearize.py | 129 |
2 files changed, 141 insertions, 0 deletions
diff --git a/contrib/misc/example-linearize.cfg b/contrib/misc/example-linearize.cfg new file mode 100644 index 0000000000..9e5aa404c2 --- /dev/null +++ b/contrib/misc/example-linearize.cfg @@ -0,0 +1,12 @@ + +# bitcoind RPC settings +rpcuser=someuser +rpcpass=somepassword +host=127.0.0.1 +port=8332 + +# bootstrap.dat settings +netmagic=f9beb4d9 +max_height=250000 +output=bootstrap.dat + diff --git a/contrib/misc/linearize.py b/contrib/misc/linearize.py new file mode 100755 index 0000000000..b4f02b7954 --- /dev/null +++ b/contrib/misc/linearize.py @@ -0,0 +1,129 @@ +#!/usr/bin/python +# +# linearize.py: Construct a linear, no-fork, best version of the blockchain. +# +# +# Copyright (c) 2013 The Bitcoin developers +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# + +import json +import struct +import re +import base64 +import httplib +import sys + +ERR_SLEEP = 15 +MAX_NONCE = 1000000L + +settings = {} + +class BitcoinRPC: + OBJID = 1 + + def __init__(self, host, port, username, password): + authpair = "%s:%s" % (username, password) + self.authhdr = "Basic %s" % (base64.b64encode(authpair)) + self.conn = httplib.HTTPConnection(host, port, False, 30) + def rpc(self, method, params=None): + self.OBJID += 1 + obj = { 'version' : '1.1', + 'method' : method, + 'id' : self.OBJID } + if params is None: + obj['params'] = [] + else: + obj['params'] = params + self.conn.request('POST', '/', json.dumps(obj), + { 'Authorization' : self.authhdr, + 'Content-type' : 'application/json' }) + + resp = self.conn.getresponse() + if resp is None: + print "JSON-RPC: no response" + return None + + body = resp.read() + resp_obj = json.loads(body) + if resp_obj is None: + print "JSON-RPC: cannot JSON-decode body" + return None + if 'error' in resp_obj and resp_obj['error'] != None: + return resp_obj['error'] + if 'result' not in resp_obj: + print "JSON-RPC: no result in object" + return None + + return resp_obj['result'] + def getblock(self, hash, verbose=True): + return self.rpc('getblock', [hash, verbose]) + def getblockhash(self, index): + return self.rpc('getblockhash', [index]) + +def getblock(rpc, settings, n): + hash = rpc.getblockhash(n) + hexdata = rpc.getblock(hash, False) + data = hexdata.decode('hex') + + return data + +def get_blocks(settings): + rpc = BitcoinRPC(settings['host'], settings['port'], + settings['rpcuser'], settings['rpcpass']) + + outf = open(settings['output'], 'wb') + + for height in xrange(settings['max_height']+1): + data = getblock(rpc, settings, height) + + outhdr = settings['netmagic'] + outhdr += struct.pack("<i", len(data)) + + outf.write(outhdr) + outf.write(data) + + if (height % 1000) == 0: + sys.stdout.write("Wrote block " + str(height) + "\n") + +if __name__ == '__main__': + if len(sys.argv) != 2: + print "Usage: mkbootstrap.py CONFIG-FILE" + sys.exit(1) + + f = open(sys.argv[1]) + for line in f: + # skip comment lines + m = re.search('^\s*#', line) + if m: + continue + + # parse key=value lines + m = re.search('^(\w+)\s*=\s*(\S.*)$', line) + if m is None: + continue + settings[m.group(1)] = m.group(2) + f.close() + + if 'netmagic' not in settings: + settings['netmagic'] = 'f9beb4d9' + if 'output' not in settings: + settings['output'] = 'bootstrap.dat' + if 'host' not in settings: + settings['host'] = '127.0.0.1' + if 'port' not in settings: + settings['port'] = 8332 + if 'max_height' not in settings: + settings['max_height'] = 250000 + if 'rpcuser' not in settings or 'rpcpass' not in settings: + print "Missing username and/or password in cfg file" + sys.exit(1) + + settings['netmagic'] = settings['netmagic'].decode('hex') + settings['port'] = int(settings['port']) + settings['max_height'] = int(settings['max_height']) + + get_blocks(settings) + + |