forked from laanwj/blockdb-troubleshoot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlist-blocks.py
executable file
·138 lines (113 loc) · 3.51 KB
/
list-blocks.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/python
#
# linearize-data.py: Construct a linear, no-fork version of the chain.
#
# Copyright (c) 2013-2014 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
from __future__ import print_function, division
import json
import struct
import re
import os
import base64
import httplib
import sys
import hashlib
import datetime
import time
from collections import namedtuple
settings = {}
MAX_BLOCK_SIZE = 1024*1024
def uint32(x):
return x & 0xffffffffL
def bytereverse(x):
return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) |
(((x) >> 8) & 0x0000ff00) | ((x) >> 24) ))
def bufreverse(in_buf):
out_words = []
for i in range(0, len(in_buf), 4):
word = struct.unpack('@I', in_buf[i:i+4])[0]
out_words.append(struct.pack('@I', bytereverse(word)))
return ''.join(out_words)
def wordreverse(in_buf):
out_words = []
for i in range(0, len(in_buf), 4):
out_words.append(in_buf[i:i+4])
out_words.reverse()
return ''.join(out_words)
def calc_hdr_hash(blk_hdr):
hash1 = hashlib.sha256()
hash1.update(blk_hdr)
hash1_o = hash1.digest()
hash2 = hashlib.sha256()
hash2.update(hash1_o)
hash2_o = hash2.digest()
return hash2_o
def calc_hash_str(blk_hdr):
hash = calc_hdr_hash(blk_hdr)
hash = bufreverse(hash)
hash = wordreverse(hash)
hash_str = hash.encode('hex')
return hash_str
def get_block_hashes(settings):
blkindex = []
f = open(settings['hashlist'], "r")
for line in f:
line = line.rstrip()
blkindex.append(line)
print("Read " + str(len(blkindex)) + " hashes")
return blkindex
def mkblockmap(blkindex):
blkmap = {}
for height,hash in enumerate(blkindex):
blkmap[hash] = height
return blkmap
def run(fname, settings, blkmap):
print("Input file " + fname)
try:
inF = open(fname, "rb")
except IOError:
print("Premature end of block data")
return
data = inF.read()
ptr = 0
last_start = last_end = None
while True:
ptr = data.find(settings['netmagic'], ptr)
if ptr == -1:
return
inhdr = data[ptr:ptr+8]
inMagic = inhdr[:4]
inLenLE = inhdr[4:]
su = struct.unpack("<I", inLenLE)
if (inMagic != settings['netmagic']) or su[0] > MAX_BLOCK_SIZE:
ptr += 1
continue
inLen = su[0] - 80 # length without header
blk_hdr = data[ptr+8:ptr+88]
hash_str = calc_hash_str(blk_hdr)
data_end = ptr + 88 + inLen
warning = ''
if last_end is not None:
if ptr < last_end:
warning = 'Overlap with last block (%08x,%08x)' %(last_start, last_end)
elif ptr != last_end:
warning = 'Block doesn\'t start at expected position %08x' % (data_end)
blknum = blkmap.get(hash_str,-1)
#if warning or blknum == -1:
print('%08x-%08x %08x %s %6d %s' % (ptr, data_end, ptr+8, hash_str,blknum, warning))
last_start = ptr
last_end = data_end
ptr += 1
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Usage: list-blocks.py blkXXX.dat")
sys.exit(1)
settings['netmagic'] = 'f9beb4d9'.decode('hex')
settings['hashlist'] = 'hashes.txt'
blkindex = get_block_hashes(settings)
blkmap = mkblockmap(blkindex)
for fname in sys.argv[1:]:
run(fname, settings, blkmap)