def main(): global CONFIG global LOGGER CONFIG = lib.get_config() LOGGER = lib.get_logger(PROCESS) LOGGER.warn("=== Starting {}".format(PROCESS)) # Connect to DB database = lib.get_db() atexit.register(lib.teardown_db) # Get Config check_interval = float(CONFIG[PROCESS]["check_interval"]) # Find the height of the latest block record last_height = grin.blocking_get_current_height() - 1400 latest_block = Blocks.get_latest() if latest_block is not None: last_height = latest_block.height height = last_height + 1 height = max(0, height) LOGGER.warn("Starting at block height: {}".format(height)) while True: try: latest = grin.blocking_get_current_height() while latest >= height: response = grin.blocking_get_block_by_height(height) LOGGER.warn("New Block: {} at {}".format(response["header"]["hash"], response["header"]["height"])) #print("sleeping 60....") #sleep(60) #print(".....GO") try: new_block = Blocks(hash = response["header"]["hash"], version = response["header"]["version"], height = response["header"]["height"], previous = response["header"]["previous"], timestamp = datetime.strptime(response["header"]["timestamp"][:-1], "%Y-%m-%dT%H:%M:%S+00:0"), output_root = response["header"]["output_root"], range_proof_root = response["header"]["range_proof_root"], kernel_root = response["header"]["kernel_root"], nonce = response["header"]["nonce"], edge_bits = response["header"]["edge_bits"], total_difficulty = response["header"]["total_difficulty"], secondary_scaling = response["header"]["secondary_scaling"], num_inputs = len(response["inputs"]), num_outputs = len(response["outputs"]), num_kernels = len(response["kernels"]), fee = sum(k["fee"] for k in response["kernels"]), lock_height = response["kernels"][0]["lock_height"] if(len(response["kernels"])>0) else 0, total_kernel_offset = response["header"]["total_kernel_offset"], state = "new") # Batch inserts when catching up database.db.getSession().add(new_block) if( (height % BATCHSZ == 0) or (height >= (latest-10)) ): database.db.getSession().commit() height = height + 1 except (sqlalchemy.exc.IntegrityError, pymysql.err.IntegrityError): LOGGER.warn("Attempted to re-add block: {}".format(response["header"]["height"])) database.db.getSession().rollback() latest_block = Blocks.get_latest() height = latest_block.height + 1 sleep(check_interval) sys.stdout.flush() sleep(check_interval) except Exception as e: LOGGER.error("Something went wrong: {}\n{}".format(e, traceback.format_exc().splitlines())) database.db.getSession().rollback() sys.stdout.flush() sleep(check_interval) # Should never get here, but.... LOGGER.warn("=== Completed {}".format(PROCESS))
def main(): global LOGGER global CONFIG CONFIG = lib.get_config() LOGGER = lib.get_logger(PROCESS) LOGGER.warn("=== Starting {}".format(PROCESS)) # Connect to DB database = lib.get_db() atexit.register(lib.teardown_db) validation_depth = int(CONFIG[PROCESS]["validation_depth"]) latest = grin.get_current_height( ) - 10 # stop 10 blocks from current to avoid overrunning the blockWatcher last_block_record = Blocks.get_latest() if last_block_record == None: last_block_record_height = 0 else: last_block_record_height = last_block_record.height last = min(latest - validation_depth, last_block_record_height - validation_depth) # start a reasonable distance back if last < 0: last = 0 LOGGER.warn("Starting from block #{}".format(last)) for i in range(last, latest + 1): if i % 100 == 0: LOGGER.warn("Processing #{}".format(i)) response = grin.blocking_get_block_by_height(i) assert (response is not None) assert (int(response["header"]["height"]) == i) #print("{}: {}".format(response["header"]["height"], response["header"]["hash"])) try: database.db.initializeSession() rec = Blocks.get_by_height( i) # Get existing entry from the DB (if any) if rec is not None: # Test if we have an orphan thats not already marked # Dont update any block info in the orphan, just mark the state if rec.hash != response["header"][ "hash"] and rec.state != "orphan": LOGGER.warn( "Found an orphan - height: {}, hash: {} vs {}".format( rec.height, rec.hash, response["header"]["hash"])) rec.state = "orphan" database.db.getSession().commit() else: # If it was not in the DB then we should add it now LOGGER.warn("Adding missing block - height: {}".format( response["header"]["height"])) missing_block = Blocks( hash=response["header"]["hash"], version=response["header"]["version"], height=response["header"]["height"], previous=response["header"]["previous"], timestamp=datetime.strptime( response["header"]["timestamp"][:-1], "%Y-%m-%dT%H:%M:%S+00:0"), output_root=response["header"]["output_root"], range_proof_root=response["header"]["range_proof_root"], kernel_root=response["header"]["kernel_root"], nonce=response["header"]["nonce"], edge_bits=response["header"]["edge_bits"], total_difficulty=response["header"]["total_difficulty"], secondary_scaling=response["header"]["secondary_scaling"], num_inputs=len(response["inputs"]), num_outputs=len(response["outputs"]), num_kernels=len(response["kernels"]), fee=sum(k["fee"] for k in response["kernels"]), lock_height=response["kernels"][0]["lock_height"] if len(response["kernels"]) > 0 else 0, total_kernel_offset=response["header"] ["total_kernel_offset"], state="missing") database.db.createDataObj(missing_block) except Exception as e: LOGGER.error("Something went wrong: {} - {}".format( e, traceback.print_stack())) database.db.getSession().rollback() database.db.destroySession() sys.stdout.flush() time.sleep(0.1) # dont be too aggressive LOGGER.warn("=== Completed {}".format(PROCESS))