10 from __future__
import print_function, division
23 from collections
import namedtuple
28 return x & 0xffffffffL
31 return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) |
32 (((x) >> 8) & 0x0000ff00) | ((x) >> 24) ))
36 for i
in range(0, len(in_buf), 4):
37 word = struct.unpack(
'@I', in_buf[i:i+4])[0]
38 out_words.append(struct.pack(
'@I',
bytereverse(word)))
39 return ''.join(out_words)
43 for i
in range(0, len(in_buf), 4):
44 out_words.append(in_buf[i:i+4])
46 return ''.join(out_words)
58 pow_hash = dash_hash.getPoWHash(blk_hdr)
65 hash_str = hash.encode(
'hex')
69 members = struct.unpack(
"<I", blk_hdr[68:68+4])
71 dt = datetime.datetime.fromtimestamp(nTime)
72 dt_ym = datetime.datetime(dt.year, dt.month, 1)
77 f = open(settings[
'hashlist'],
"r") 82 print(
"Read " + str(len(blkindex)) +
" hashes")
88 for height,hash
in enumerate(blkindex):
93 BlockExtent = namedtuple(
'BlockExtent', [
'fn',
'offset',
'inhdr',
'blkhdr',
'size'])
96 def __init__(self, settings, blkindex, blkmap):
116 if 'output' in settings:
118 if settings[
'file_timestamp'] != 0:
120 if settings[
'split_timestamp'] != 0:
128 blockSizeOnDisk = len(inhdr) + len(blk_hdr) + len(rawblock)
132 os.utime(outFname, (int(time.time()), highTS))
140 print(
"New month " + blkDate.strftime(
"%Y-%m") +
" @ " + hash_str)
145 os.utime(outFname, (int(time.time()), highTS))
153 outFname = self.
settings[
'output_file']
155 outFname = os.path.join(self.
settings[
'output'],
"blk%05d.dat" % self.
outFn)
156 print(
"Output file " + outFname)
157 self.
outF = open(outFname,
"wb")
159 self.
outF.write(inhdr)
160 self.
outF.write(blk_hdr)
161 self.
outF.write(rawblock)
162 self.
outsz = self.
outsz + len(inhdr) + len(blk_hdr) + len(rawblock)
169 print(
'%i blocks scanned, %i blocks written (of %i, %.1f%% complete)' %
173 return os.path.join(self.
settings[
'input'],
"blk%05d.dat" % fn)
176 '''Fetch block contents from disk given extents''' 177 with open(self.
inFileName(extent.fn),
"rb")
as f:
178 f.seek(extent.offset)
179 return f.read(extent.size)
182 '''Find the next block to be written in the input, and copy it to the output.''' 191 self.
writeBlock(extent.inhdr, extent.blkhdr, rawblock)
197 print(
"Input file " + fname)
199 self.
inF = open(fname,
"rb")
201 print(
"Premature end of block data")
204 inhdr = self.
inF.read(8)
205 if (
not inhdr
or (inhdr[0] ==
"\0")):
212 if (inMagic != self.
settings[
'netmagic']):
213 print(
"Invalid magic: " + inMagic.encode(
'hex'))
216 su = struct.unpack(
"<I", inLenLE)
218 blk_hdr = self.
inF.read(80)
222 if not hash_str
in blkmap:
223 print(
"Skipping unknown block " + hash_str)
224 self.
inF.seek(inLen, os.SEEK_CUR)
227 blkHeight = self.
blkmap[hash_str]
232 rawblock = self.
inF.read(inLen)
248 self.
inF.seek(inLen, os.SEEK_CUR)
250 print(
"Done (%i blocks written)" % (self.
blkCountOut))
252 if __name__ ==
'__main__':
253 if len(sys.argv) != 2:
254 print(
"Usage: linearize-data.py CONFIG-FILE")
257 f = open(sys.argv[1])
260 m = re.search(
'^\s*#', line)
265 m = re.search(
'^(\w+)\s*=\s*(\S.*)$', line)
268 settings[m.group(1)] = m.group(2)
271 if 'netmagic' not in settings:
272 settings[
'netmagic'] =
'cee2caff' 273 if 'genesis' not in settings:
274 settings[
'genesis'] =
'00000bafbc94add76cb75e2ec92894837288a481e5c005f6563d91623bf8bc2c' 275 if 'input' not in settings:
276 settings[
'input'] =
'input' 277 if 'hashlist' not in settings:
278 settings[
'hashlist'] =
'hashlist.txt' 279 if 'file_timestamp' not in settings:
280 settings[
'file_timestamp'] = 0
281 if 'split_timestamp' not in settings:
282 settings[
'split_timestamp'] = 0
283 if 'max_out_sz' not in settings:
284 settings[
'max_out_sz'] = 1000L * 1000 * 1000
285 if 'out_of_order_cache_sz' not in settings:
286 settings[
'out_of_order_cache_sz'] = 100 * 1000 * 1000
288 settings[
'max_out_sz'] =
long(settings[
'max_out_sz'])
289 settings[
'split_timestamp'] = int(settings[
'split_timestamp'])
290 settings[
'file_timestamp'] = int(settings[
'file_timestamp'])
291 settings[
'netmagic'] = settings[
'netmagic'].decode(
'hex')
292 settings[
'out_of_order_cache_sz'] = int(settings[
'out_of_order_cache_sz'])
294 if 'output_file' not in settings
and 'output' not in settings:
295 print(
"Missing output file / directory")
301 if not settings[
'genesis']
in blkmap:
302 print(
"Genesis block not found in hashlist")
def calc_hdr_hash(blk_hdr)
def writeBlock(self, inhdr, blk_hdr, rawblock)
def fetchBlock(self, extent)
def get_block_hashes(settings)
def __init__(self, settings, blkindex, blkmap)
def calc_hash_str(blk_hdr)