diff --git a/blockchain_parser/blockchain.py b/blockchain_parser/blockchain.py index 23e7411..220b749 100644 --- a/blockchain_parser/blockchain.py +++ b/blockchain_parser/blockchain.py @@ -15,6 +15,7 @@ import pickle import stat import plyvel +from xor_cipher import cyclic_xor from blockchain_parser.transaction import Transaction from blockchain_parser.index import DBTransactionIndex @@ -43,52 +44,70 @@ def get_files(path): files = map(lambda x: os.path.join(path, x), files) return sorted(files) -def get_undo_files(path): - """ - Given the path to the .bitcoin directory, returns the sorted list of rev*.dat - files contained in that directory - """ - if not stat.S_ISDIR(os.stat(path)[stat.ST_MODE]): - return [path] - files = os.listdir(path) - files = [f for f in files if f.startswith("rev") and f.endswith(".dat")] - files = map(lambda x: os.path.join(path, x), files) - return sorted(files) - -def get_blocks(blockfile): +def get_blocks(blockfile, xor_key=None): """ - Given the name of a .dat file, for every block contained in the file, + Given the name of a .blk file, for every block contained in the file, yields its raw hexadecimal value """ - with open(blockfile, "rb") as f: - if os.name == 'nt': - size = os.path.getsize(f.name) - raw_data = mmap.mmap(f.fileno(), size, access=mmap.ACCESS_READ) - else: - # Unix-only call, will not work on Windows, see python doc. - raw_data = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) - length = len(raw_data) - offset = 0 - block_count = 0 - while offset < (length - 4): - if raw_data[offset:offset+4] == BITCOIN_CONSTANT: - offset += 4 - size = struct.unpack(" -1: @@ -194,18 +236,18 @@ def get_ordered_blocks(self, index, start=0, end=None, cache=None): # if this block is confirmed, the unconfirmed block is # the previous one. Remove it. - stale_blocks.append(blockIndexes[i - 1].hash) + orphans.append(blockIndexes[i - 1].hash) else: # if this block isn't confirmed, remove it. - stale_blocks.append(blockIndexes[i].hash) + orphans.append(blockIndexes[i].hash) last_height = blockIdx.height - # filter out stale blocks, so we are left only with block indexes + # filter out the orphan blocks, so we are left only with block indexes # that have been confirmed # (or are new enough that they haven't yet been confirmed) - blockIndexes = list(filter(lambda block: block.hash not in stale_blocks, blockIndexes)) + blockIndexes = list(filter(lambda block: block.hash not in orphans, blockIndexes)) if end is None: end = len(blockIndexes) @@ -219,7 +261,7 @@ def get_ordered_blocks(self, index, start=0, end=None, cache=None): if blkIdx.file == -1 or blkIdx.data_pos == -1: break blkFile = os.path.join(self.path, "blk%05d.dat" % blkIdx.file) - yield Block(get_block(blkFile, blkIdx.data_pos), blkIdx.height) + yield Block(get_block(blkFile, blkIdx.data_pos, self.xor_key), blkIdx.height) def get_transaction(self, txid, db): """Yields the transaction contained in the .blk files as a python @@ -237,7 +279,7 @@ def get_transaction(self, txid, db): tx_idx = DBTransactionIndex(utils.format_hash(tx_hash_fmtd), raw_hex) blk_file = os.path.join(self.path, "blk%05d.dat" % tx_idx.blockfile_no) - raw_hex = get_block(blk_file, tx_idx.file_offset) + raw_hex = get_block(blk_file, tx_idx.file_offset, self.xor_key) offset = tx_idx.block_offset