예제 #1
0
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))
예제 #2
0
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))