def read_chain_from_disk() -> CoinState: if os.path.isfile('chain.cache'): print("Reading cached chain") with open('chain.cache', 'rb') as file: coinstate = CoinState.load(lambda: pickle.load(file)) else: coinstate = CoinState.zero() rewrite = False if os.path.isdir('chain'): # the code below is no longer needed by normal users, but some old testcases still rely on it: for filename in sorted(os.listdir('chain')): (height_str, hash_str) = filename.split("-") (height, hash) = (int(height_str), computer(hash_str)) if hash not in coinstate.block_by_hash: if height % 1000 == 0: print(filename) if os.path.getsize(f"chain/{filename}") == 0: print("Stopping at empty block file: %s" % filename) break with open(Path("chain") / filename, 'rb') as f: try: block = Block.stream_deserialize(f) except Exception as e: raise Exception("Corrupted block on disk: %s" % filename) from e try: coinstate = coinstate.add_block_no_validation(block) except Exception: print("Failed to add block at height=%d, previous_hash=%s" % (block.height, human(block.header.summary.previous_block_hash))) break rewrite = True if rewrite: DiskInterface().write_chain_cache_to_disk(coinstate) return coinstate
def read_chain_from_disk() -> CoinState: if os.path.isfile('chain.cache'): print("Reading cached chain") with open('chain.cache', 'rb') as file: coinstate = CoinState.load(lambda: pickle.load(file)) else: try: print("Pre-download blockchain from trusted source to 'chain.zip'") with urllib.request.urlopen(TRUSTED_BLOCKCHAIN_ZIP) as resp: with open('chain.zip', 'wb') as outfile: outfile.write(resp.read()) print("Reading initial chain from zipfile") coinstate = CoinState.zero() with zipfile.ZipFile('chain.zip') as zip: for entry in zip.infolist(): if not entry.is_dir(): filename = entry.filename.split('/')[1] height = int(filename.split("-")[0]) if height % 1000 == 0: print(filename) data = zip.read(entry) block = Block.stream_deserialize(BytesIO(data)) coinstate = coinstate.add_block_no_validation(block) except Exception: print( "Error reading zip file. We'll start with an empty blockchain instead." + traceback.format_exc()) coinstate = CoinState.zero() rewrite = False if os.path.isdir('chain'): # the code below is no longer needed by normal users, but some old testcases still rely on it: for filename in sorted(os.listdir('chain')): (height_str, hash_str) = filename.split("-") (height, hash) = (int(height_str), computer(hash_str)) if hash not in coinstate.block_by_hash: if height % 1000 == 0: print(filename) if os.path.getsize(f"chain/{filename}") == 0: print("Stopping at empty block file: %s" % filename) break with open(Path("chain") / filename, 'rb') as f: try: block = Block.stream_deserialize(f) except Exception as e: raise Exception("Corrupted block on disk: %s" % filename) from e try: coinstate = coinstate.add_block_no_validation(block) except Exception: print( "Failed to add block at height=%d, previous_hash=%s" % (block.height, human(block.header.summary.previous_block_hash))) break rewrite = True if rewrite: DiskInterface().write_chain_cache_to_disk(coinstate) return coinstate
def test_faster_read(): with open('test.tmp', 'rb') as file: with cProfile.Profile() as pr: pr.runcall(lambda: CoinState.load(lambda: pickle.load(file))) pr.print_stats()