#!/usr/bin/env python # # Read the block database, parse and dump out results # from bsddb.db import * from datetime import date import logging import os import sys from BCDataStream import * from block import scan_blocks, _open_blkindex, read_block from collections import defaultdict from deserialize import parse_Block from util import determine_db_dir, create_env def target(bits): first = bits >> (6*4) last = bits & (~0xff000000) return last * 2**(8*(first - 3)) def diff_perc(h, bits): d = float(h) / target(bits) if d > 1: print d, bits, h raise ValueError print "%.11f" % d return d def diff_minus(h, bits): d = target(bits) - h if d < 0: print d, h, bits raise ValueError print "%r" % d return d max_diff = target(0x1d00ffff) def diff_hybrid(h, bits): max_diff = t = target(bits) diff = t - h d = diff / float(t) if d > 1: print d, t, h print "%.11f" % d return d def main(): import optparse parser = optparse.OptionParser(usage="%prog [options]") parser.add_option("--datadir", dest="datadir", default=None, help="Look for files here (defaults to bitcoin default)") (options, args) = parser.parse_args() if options.datadir is None: db_dir = determine_db_dir() else: db_dir = options.datadir try: db_env = create_env(db_dir) except DBNoSuchFileError: logging.error("Couldn't open " + db_dir) sys.exit(1) blockfile = open(os.path.join(db_dir, "blk%04d.dat"%(1,)), "rb") block_datastream = BCDataStream() block_datastream.map_file(blockfile, 0) num_blocks = 1 db = _open_blkindex(db_env) kds = BCDataStream() vds = BCDataStream() # Read the hashBestChain record: cursor = db.cursor() (key, value) = cursor.set_range("\x0dhashBestChain") vds.write(value) hashBestChain = vds.read_bytes(32) block_data = read_block(cursor, hashBestChain) last_hash = -1 while True: if block_data['nHeight'] == 0: break; block_data = read_block(cursor, block_data['hashPrev']) block_datastream.seek_file(block_data['nBlockPos']) data = parse_Block(block_datastream) if last_hash == -1: last_hash = int('0x' + data['hashPrev'][::-1].encode('hex_codec'), 16) continue d = diff_perc(last_hash, data['nBits']) last_hash = int('0x' + data['hashPrev'][::-1].encode('hex_codec'), 16) num_blocks += 1 db_env.close() if __name__ == '__main__': main()