Dash Core  0.12.2.1
P2P Digital Currency
linearize-hashes.py
Go to the documentation of this file.
1 #!/usr/bin/python
2 #
3 # linearize-hashes.py: List blocks in a linear, no-fork version of the chain.
4 #
5 # Copyright (c) 2013-2014 The Bitcoin Core developers
6 # Distributed under the MIT software license, see the accompanying
7 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
8 #
9 
10 from __future__ import print_function
11 import json
12 import struct
13 import re
14 import base64
15 import httplib
16 import sys
17 
18 settings = {}
19 
20 class BitcoinRPC:
21  def __init__(self, host, port, username, password):
22  authpair = "%s:%s" % (username, password)
23  self.authhdr = "Basic %s" % (base64.b64encode(authpair))
24  self.conn = httplib.HTTPConnection(host, port, False, 30)
25 
26  def execute(self, obj):
27  self.conn.request('POST', '/', json.dumps(obj),
28  { 'Authorization' : self.authhdr,
29  'Content-type' : 'application/json' })
30 
31  resp = self.conn.getresponse()
32  if resp is None:
33  print("JSON-RPC: no response", file=sys.stderr)
34  return None
35 
36  body = resp.read()
37  resp_obj = json.loads(body)
38  return resp_obj
39 
40  @staticmethod
41  def build_request(idx, method, params):
42  obj = { 'version' : '1.1',
43  'method' : method,
44  'id' : idx }
45  if params is None:
46  obj['params'] = []
47  else:
48  obj['params'] = params
49  return obj
50 
51  @staticmethod
52  def response_is_error(resp_obj):
53  return 'error' in resp_obj and resp_obj['error'] is not None
54 
55 def get_block_hashes(settings, max_blocks_per_call=10000):
56  rpc = BitcoinRPC(settings['host'], settings['port'],
57  settings['rpcuser'], settings['rpcpassword'])
58 
59  height = settings['min_height']
60  while height < settings['max_height']+1:
61  num_blocks = min(settings['max_height']+1-height, max_blocks_per_call)
62  batch = []
63  for x in range(num_blocks):
64  batch.append(rpc.build_request(x, 'getblockhash', [height + x]))
65 
66  reply = rpc.execute(batch)
67 
68  for x,resp_obj in enumerate(reply):
69  if rpc.response_is_error(resp_obj):
70  print('JSON-RPC: error at height', height+x, ': ', resp_obj['error'], file=sys.stderr)
71  exit(1)
72  assert(resp_obj['id'] == x) # assume replies are in-sequence
73  print(resp_obj['result'])
74 
75  height += num_blocks
76 
77 if __name__ == '__main__':
78  if len(sys.argv) != 2:
79  print("Usage: linearize-hashes.py CONFIG-FILE")
80  sys.exit(1)
81 
82  f = open(sys.argv[1])
83  for line in f:
84  # skip comment lines
85  m = re.search('^\s*#', line)
86  if m:
87  continue
88 
89  # parse key=value lines
90  m = re.search('^(\w+)\s*=\s*(\S.*)$', line)
91  if m is None:
92  continue
93  settings[m.group(1)] = m.group(2)
94  f.close()
95 
96  if 'host' not in settings:
97  settings['host'] = '127.0.0.1'
98  if 'port' not in settings:
99  settings['port'] = 9998
100  if 'min_height' not in settings:
101  settings['min_height'] = 0
102  if 'max_height' not in settings:
103  settings['max_height'] = 313000
104  if 'rpcuser' not in settings or 'rpcpassword' not in settings:
105  print("Missing username and/or password in cfg file", file=stderr)
106  sys.exit(1)
107 
108  settings['port'] = int(settings['port'])
109  settings['min_height'] = int(settings['min_height'])
110  settings['max_height'] = int(settings['max_height'])
111 
112  get_block_hashes(settings)
113 
def get_block_hashes(settings, max_blocks_per_call=10000)
def build_request(idx, method, params)
def __init__(self, host, port, username, password)