Beispiel #1
0
def ShutdownClient(chain_info):
    chain_id = chain_info["chain-id"]
    key_name = chain_info["key-name"]
    RelayerHelper.DeleteKey(
        chain_id, key_name)  # rly keys delete kira-alpha prefix_kira-alpha
    RelayerHelper.DeleteLiteClient(chain_id)  # rly lite delete kira-alpha
    RelayerHelper.ChainDelete(chain_id)  # rly chains delete kira-alpha
Beispiel #2
0
def QueryFeeTokenBalance(chain_info):
    chain_id = chain_info["chain-id"]
    denom = chain_info.get("default-denom")
    if not denom:
        print(
            f"WARNING: Chain {chain_id} does not have a default denom for the fee token defined"
        )
        return 0
    balances = RelayerHelper.TryQueryBalance(chain_id)
    return RelayerHelper.GetAmountByDenom(balances, denom)
Beispiel #3
0
def AssertRefreshBalances(chain_info):
    chain_id = chain_info["chain-id"]
    denom = chain_info["default-denom"]
    address = chain_info.get("address", "undefined")
    chain_info["balance"] = balances = RelayerHelper.TryQueryBalance(chain_id)
    if RelayerHelper.GetAmountByDenom(balances, denom) <= 0:
        raise Exception(
            f"Insufficient {denom} balance of the account '{chain_id}:{address}', client will not be able to further continue the connections unless {denom} tokens are available."
        )
    return chain_info
Beispiel #4
0
def ShutdownConnection(connection):
    chain_info_src = connection.get("src", None)
    chain_info_dst = connection.get("dst", None)
    chain_id_src = None if not chain_info_src else chain_info_src["chain-id"]
    chain_id_dst = None if not chain_info_dst else chain_info_dst["chain-id"]
    path = connection.get(
        "path", f"{chain_id_src}_{chain_id_dst}"
    )  # delete default path if custom one was not defined
    if path:  # rly pth delete kira-alpha_gameofzoneshub-1 | rly pth delete kira-1_kira-alpha
        print(f"INFO: Shutting down {path} connection...")
        RelayerHelper.DeletePath(path)
    else:
        print(
            f"WARNING: Path was not present in the connection object, can't remove None"
        )
    if chain_info_src and len(chain_info_src) > 0:
        ClientHelper.ShutdownClient(chain_info_src)
    else:
        print(
            f"WARNING: Source chain was not present in the connection object, can't remove None"
        )
    if chain_info_dst and len(chain_info_dst) > 0:
        ClientHelper.ShutdownClient(chain_info_dst)
    else:
        print(
            f"WARNING: Destination chain not present in the connection object, can't remove None"
        )
Beispiel #5
0
def ReConnect(connection, timeout):
    chain_info_src = connection["src"]
    chain_info_dst = connection["dst"]
    chain_id_src = chain_info_src["chain-id"]
    chain_id_dst = chain_info_dst["chain-id"]
    path = f"{chain_id_src}_{chain_id_dst}"

    status = QueryStatus(path)
    # TO DO disconnect gracefully if status exists
    if (not (not status)):
        print("WARNING! TODO: Disconnect gracefully")
        RelayerHelper.DeletePath(path)
    else:
        RelayerHelper.DeletePath(path)

    return Connect(connection, timeout)
Beispiel #6
0
def DeleteLiteClient(chain_info):
    chain_id = chain_info["chain-id"]
    print(f"INFO: Re-starting {chain_id} lite client...")
    if not RelayerHelper.DeleteLiteClient(chain_id):
        print(f"ERROR: Failed to update {chain_id} lite client")
        return False
    print(f"SUCCESS: Updated {chain_id} lite client")
    return True
Beispiel #7
0
def TestConnection(connection):
    src_chain_info = connection["src"]
    dst_chain_info = connection["dst"]
    src_id = src_chain_info["chain-id"]
    dst_id = dst_chain_info["chain-id"]
    path = connection["path"]
    min_ttl = connection["min-ttl"]

    if not RelayerHelper.UpdateLiteClient(src_id) or (
            not RelayerHelper.QueryLiteClientHeader(src_id)):
        print(
            f"FAILURE: Could not update source '{src_id}' lite client or fetch header"
        )
        return False
    if not RelayerHelper.UpdateLiteClient(dst_id) or (
            not RelayerHelper.QueryLiteClientHeader(dst_id)):
        print(
            f"FAILURE: Could not update destination '{dst_id}' lite client or fetch header"
        )
        return False

    status = QueryStatus(path)
    is_connected = TestStatus(status)
    ttl = RelayerHelper.GetRemainingTimesToLive(connection)

    if is_connected:
        print(
            f"SUCCESS: Connection of the path {path} is maitained, testing ttl..."
        )
        if not ttl or ttl["min"] <= 0:
            print(
                f"FAILURE: Could not acquire remaining TTL or {ttl} indicates dropped connection."
            )
            is_connected = False
    else:
        print(f"FAILURE: Connection of the path {path} is faulty.")

    if None != status:
        print(
            f"INFO: Path {path} status: Chains {status['chains']} | Clients {status['clients']} | Connection {status['connection']} | Channel {status['channel']}, TTL: {ttl}"
        )
    else:
        print(f"WARNING: Failed to query connection status")

    return is_connected
Beispiel #8
0
def S3FileExists(bucket, s3_key_path):
    out = RelayerHelper.callRaw(
        f"AWSHelper s3 object-exists --bucket='{bucket}' --path='{s3_key_path}' --throw-if-not-found=False --silent=True",
        True)
    if None == out:
        raise Exception(
            f"Call failed when checking if file exists as {s3_key_path} in the {bucket} S3 bucket"
        )
    return StringHelper.ToBool(out)
Beispiel #9
0
def GasUpdateAssert(chain_info, gas):
    chain_id = chain_info["chain-id"]
    if not RelayerHelper.ConfigureDefaultGas(
            chain_id, gas):  # rly ch edit kira-alpha gas 100000
        raise Exception(
            f"WARNING: Failed to configure gas of the {chain_id} chain")
    if not UpdateLiteClient(chain_info):
        raise Exception(
            "Failed to update lite client after adjusting gas prices")
    print(f"SUCCESS: New gas price for {chain_id} chain was set to {gas}")
    return True
Beispiel #10
0
def TryS3ReadText(bucket, s3_key_path):
    out = RelayerHelper.callRaw(
        f"AWSHelper s3 download-text --bucket='{bucket}' --path='{s3_key_path}' --silent=true",
        True)
    if None == out:
        print(
            f"ERROR: Failed to read {s3_key_path} file from {bucket} bucket in S3"
        )
    else:
        print(
            f"SUCCESS: Read all {len(out)} characters from {bucket}/{s3_key_path} path in S3"
        )
    return out
Beispiel #11
0
def S3WriteText(text, bucket, s3_key_path):
    tmp_file = f"/tmp/{str(uuid.uuid4())}"
    StringHelper.WriteJsonToFile(text, tmp_file)
    print(f"INFO: Writing {tmp_file} to {bucket}/{s3_key_path} file in S3...")
    result = RelayerHelper.callRaw(
        f"AWSHelper s3 upload-object --bucket='{bucket}' --path='{s3_key_path}' --input='{tmp_file}'",
        True)
    os.remove(tmp_file)
    if result == None:
        raise Exception(
            f"ERROR: Failed to upload {tmp_file} into {bucket}/{s3_key_path} path on S3."
        )
    return True
Beispiel #12
0
def IsConnected(connection):
    path = connection["path"]
    status = QueryStatus(path)
    if status == None:
        return None
    if not TestStatus(status):
        print(f"WARNING: Path {path} is not connected, status: {status}")
        return False
    ttl = RelayerHelper.GetRemainingTimesToLive(connection)
    if ttl == None:
        return None
    if not ttl or ttl["min"] <= 0:
        print(f"WARNING: Path {path} expired, TTL: {ttl}")
        return False
    return True
Beispiel #13
0
def S3ReadText(bucket, s3_key_path):
    if not S3FileExists(bucket, s3_key_path):
        print(f"WARNING: File {bucket}/{s3_key_path} does not exist in S3")
        return {}

    out = RelayerHelper.callRaw(
        f"AWSHelper s3 download-text --bucket='{bucket}' --path='{s3_key_path}' --silent=true --throw-if-not-found=False",
        True)
    if None == out:
        raise Exception(
            f"Failed to read {s3_key_path} file from {bucket} bucket in S3")
    else:
        print(
            f"SUCCESS: Read all {len(out)} characters from {bucket}/{s3_key_path} path in S3"
        )
        return out
Beispiel #14
0
def InitializeClientWithJsonFile(json_path, key_prefix, mnemonic, bucket):
    print(f"INFO: Initializing IBC client with JSON file: {json_path}")
    chain_info = json.load(open(json_path))
    chain_info["file-path"] = json_path
    chain_info["bucket"] = bucket
    chain_info = InitializeClient(chain_info, key_prefix, mnemonic)
    chain_id = chain_info["chain-id"]
    denom = chain_info["default-denom"]
    address = chain_info.get("address", "undefined")

    print(f"INFO: Requesting {denom} tokens from {chain_id} faucet...")
    if not RelayerHelper.TryRequestTokens(chain_id):
        print(
            f"WARNING: Failed to request {denom} tokens from the {chain_id} faucet..."
        )
    chain_info = AssertRefreshBalances(chain_info)
    return chain_info
Beispiel #15
0
def S3ReadJson(
    bucket, s3_key_path
):  # AWSHelper s3 object-exists --bucket='kira-core-goz' --path='relayer/kira-alpha_kira-1-1b/alpha/state.json' --throw-if-not-found=False
    if not S3FileExists(bucket, s3_key_path):
        print(f"WARNING: File {bucket}/{s3_key_path} does not exist in S3")
        return {}

    out = RelayerHelper.callJson(
        f"AWSHelper s3 download-text --bucket='{bucket}' --path='{s3_key_path}' --silent=true --throw-if-not-found=False",
        True)
    if None == out:
        raise Exception(
            f"Failed to read {s3_key_path} file from {bucket} bucket in S3")
    else:
        print(
            f"SUCCESS: Read all {len(out)} json elements from {bucket}/{s3_key_path} path in S3"
        )
        return out
Beispiel #16
0
 def Transfer(token):
     amount = 0 if not token["amount"] else int(token["amount"])
     denom = token["denom"]
     if len(denom.split("/")) >= 5:
         print(
             f"FAILURE: Failed sending {min_amount} {denom} from {src_id} to {dst_id}, tokens with too long paths are not transferable."
         )
     elif amount <= min_amount:
         print(
             f"WARNING: Failed sending {min_amount} {denom} from {src_id} to {dst_id}, source address has only {amount} {denom} left."
         )
     elif (not RelayerHelper.TransferTokens(
             src_id, dst_id, f"{min_amount}{denom}", dst_address)):
         print(
             f"FAILURE: Failed sending {min_amount} {denom} from {src_id} to {dst_id}"
         )
     else:
         print(
             f"SUCCESS: Sent {min_amount}{denom} from {src_id} to {dst_id}")
Beispiel #17
0
def TransferEachToken(src_chain_info, dst_chain_info, path, min_amount):
    src_id = src_chain_info["chain-id"]
    dst_id = dst_chain_info["chain-id"]
    src_balance = src_chain_info["balance"]
    dst_balance = dst_chain_info["balance"]
    dst_address = dst_chain_info["address"]

    def Transfer(token):
        amount = 0 if not token["amount"] else int(token["amount"])
        denom = token["denom"]
        if len(denom.split("/")) >= 5:
            print(
                f"FAILURE: Failed sending {min_amount} {denom} from {src_id} to {dst_id}, tokens with too long paths are not transferable."
            )
        elif amount <= min_amount:
            print(
                f"WARNING: Failed sending {min_amount} {denom} from {src_id} to {dst_id}, source address has only {amount} {denom} left."
            )
        elif (not RelayerHelper.TransferTokens(
                src_id, dst_id, f"{min_amount}{denom}", dst_address)):
            print(
                f"FAILURE: Failed sending {min_amount} {denom} from {src_id} to {dst_id}"
            )
        else:
            print(
                f"SUCCESS: Sent {min_amount}{denom} from {src_id} to {dst_id}")

    if (len(src_balance) <= 0) or (len(dst_balance) <= 0):
        print(
            f"WARNING: Can't send tokens from {src_id} to {dst_id}, source or destination address does not have any tokens left."
        )
    else:
        for token in src_balance:  #Parallel(n_jobs=max_parallelism)(delayed(Transfer)(token) for token in src_balance)
            Transfer(token)

        if not RelayerHelper.TransactRelay(path):
            print(f"ERROR: Failed sending remaining packets")
Beispiel #18
0
    time_to_upload = int(upload_period - upload_elapsed)
    total_uptime = connection["total-uptime"] = total_uptime + loop_elapsed
    loop_start = time.time()
    current_session = time.time() - time_start

    if failed_tx_counter > 10:
        print(f"FAILURE: More than 10 transactions failed in the row")
        break

    if not IBCHelper.TestConnection(connection):
        print(
            f"FAILURE: Connection was dropped or failed to query status. Current session duration: {timedelta(seconds=current_session)}"
        )
        break

    ttl = RelayerHelper.GetRemainingTimesToLive(connection)

    if not ttl:
        print(f"FAILURE: Could not fetch remaining TTL")
        break

    ttl_src = int(ttl["src"])  # source connection time to live
    ttl_dst = int(ttl["dst"])  # destination connection time to live

    connection["src"] = src = ClientHelper.AssertRefreshBalances(src)
    connection["dst"] = dst = ClientHelper.AssertRefreshBalances(dst)
    src_balances = src["balance"]
    dst_balances = dst["balance"]
    src_tokens = RelayerHelper.GetAmountByDenom(src_balances, src_denom)
    dst_tokens = RelayerHelper.GetAmountByDenom(dst_balances, dst_denom)
    src_cfg = RelayerHelper.ShowChain(
Beispiel #19
0
def QueryStatus(path):
    path_info = RelayerHelper.QueryPath(
        path)  # rly pth show kira-alpha_kira-1-b -j
    status = None if (not path_info) else path_info["status"]
    return status
Beispiel #20
0
def TryS3FileExists(bucket, s3_key_path):
    return False if None == RelayerHelper.callRaw(
        f"AWSHelper s3 object-exists --bucket='{bucket}' --path='{s3_key_path}' --throw-if-not-found=True",
        False) else True
Beispiel #21
0
dst_denom = dst["default-denom"]
src_key = src["key-name"]
dst_key = dst["key-name"]

connection["init-time"] = init_time
connection["max-init-time"] = max_init_time = state_file.get("max-init-time", init_time)
connection["min-init-time"] = min_init_time = state_file.get("min-init-time", init_time)
upload_time = connection["upload-time"] = state_file.get("upload-time", 0) # time when state_info was uploaded for the last time
total_uptime = connection["total-uptime"] = state_file.get("total-uptime", 0)
loop_start = time_start

src_gas_min = src.get("gas-min", 50000)
dst_gas_min = dst.get("gas-min", 50000)
src_gas_max = src.get("gas-max", src_gas_min)
dst_gas_max = dst.get("gas-max", src_gas_min)
src_cfg = RelayerHelper.ShowChain(src_chain_id) # rly ch show kira-alpha -j
dst_cfg = RelayerHelper.ShowChain(dst_chain_id) # rly ch show kira-1 -j
src_gas_default = src_cfg.get("gas", src_gas_min)
dst_gas_default = dst_cfg.get("gas", dst_gas_min)

print(f"INFO: Connection was established within {init_time}s")
print(f"INFO: Max init time: {max_init_time}s")
print(f"INFO: Min init time: {min_init_time}s")
print(f"INFO: SRC => Gas Min ({src_gas_min}), Gas Now ({src_gas_default}), Gas Max ({src_gas_max})")
print(f"INFO: DST => Gas Min ({dst_gas_min}), Gas Now ({dst_gas_default}), Gas Max ({dst_gas_max})")

while True:
    loop_elapsed = int(time.time() - loop_start)
    upload_elapsed = int(time.time() - upload_time)
    time_to_upload = int(upload_period - upload_elapsed)
    total_uptime = connection["total-uptime"] =  total_uptime + loop_elapsed
Beispiel #22
0
def InitializeClientWithMnemonic(chain_info, mnemonic):
    print(f"INFO: Initializing client with mnemonic...")
    chain_id = chain_info["chain-id"]
    chain_info_path = chain_info["file-path"]
    key_name = chain_info["key-name"]
    bucket = chain_info["bucket"]
    s3_key_path = chain_info["s3-path"]

    if not mnemonic:
        raise Exception(
            f"Failed to recover key {key_name}. Mnemonic was not defined.")

    if not RelayerHelper.UpsertChainFromFile(
            chain_info_path):  # rly chains add -f $TESTCHAIN_JSON_PATH
        raise Exception(
            f"Failed adding new chain from '{chain_info_path}' file :(")

    if not RelayerHelper.KeyExists(chain_id, key_name):
        print(
            f"WARNING: Key {key_name} of the {chain_id} chain does not exist, restoring..."
        )
        RelayerHelper.RestoreKey(
            chain_id, key_name,
            mnemonic)  # rly keys restore $s k$s "$RLYKEY_MNEMONIC"

        if not RelayerHelper.KeyExists(chain_id, key_name):
            raise Exception(
                f"Failed to restore key {key_name} of the chain {chain_id}")

        print(f"SUCCESS: Key {key_name} of the chain {chain_id} was restored")
    else:
        print(f"INFO: Key {key_name} of the {chain_id} already exists")

    if not RelayerHelper.ConfigureDefaultKey(
            chain_id,
            key_name):  # rly ch edit kira-alpha key prefix_kira-alpha
        raise Exception(
            f"Failed to configure chain {chain_id} to use {key_name} key by default"
        )
    print(
        f"SUCCESS: Key {key_name} was configured as default of the chain {chain_id}"
    )

    chain_info["address"] = address = RelayerHelper.QueryChainAddress(chain_id)

    if not address:
        raise Exception(f"Failed to query {chain_id} chain address")

    chain_info["address"] = str(chain_info["address"], "utf-8")

    if not StateHelper.TryS3FileExists(bucket, s3_key_path):
        print(
            f"INFO: Relayer key {key_name} was not present in S3, uploading..."
        )
        key = {"mnemonic": mnemonic, "address": address}
        StateHelper.S3WriteText(key, bucket,
                                s3_key_path)  # will throw if fails to upload

    chain_info["balance"] = balance = RelayerHelper.TryQueryBalance(chain_id)

    if (not balance) or (len(balance) <= 0):
        print(
            f"WARNING: Address {address} on the chain {chain_id} has no tokens deposited or query failed to fetch balance!"
        )
        chain_info["balance"] = balance = None

    return chain_info
Beispiel #23
0
def Connect(connection, timeout):
    chain_info_src = connection["src"]
    chain_info_dst = connection["dst"]

    chain_id_src = chain_info_src["chain-id"]
    chain_id_dst = chain_info_dst["chain-id"]
    path = connection["path"]
    min_ttl = connection["min-ttl"]
    path_info = connection.get("path-info", None)

    if (chain_id_src == chain_id_dst):
        raise Exception(
            f"Source chain and destination chain id's cant be the same, but both were: {chain_id_src}"
        )
        return connection

    if not RelayerHelper.PathExists(path):
        DeleteLiteClients(connection)
        if (not (not path_info)):
            print(
                f"INFO: Path {path} does not exists, but recovery state is available"
            )
            RelayerHelper.AddPath(connection)
        else:
            print(
                f"INFO: Path {path} does not exists and recovery is not available, re-generating path"
            )
            if not RelayerHelper.ReGeneratePath(chain_id_src, chain_id_dst,
                                                path):
                raise Exception(f"Failed to re-generate new {path} path")
            else:
                connection["path-info"] = path_info = None

    if not RelayerHelper.PathExists(path):  # by now path must exist
        raise Exception(f"Failed to assert {path} path existence"
                        )  # probably networking issues

    if not ReArmConnection(connection, timeout):
        print(f"WARNING: Failed to rearm {path} connection")
    else:
        print(f"SUCCESS, connection was re-armed. Status: {QueryStatus(path)}")

    if not RestartLiteClients(
            connection
    ):  # it should always be possible to restart lite clients
        raise Exception(
            f"Could NOT restart lite clients, it will not be possible to connect"
        )

    ttl = RelayerHelper.GetRemainingTimesToLive(connection)
    if None != ttl and ttl["min"] < min_ttl:  # connection expired
        print(f"WARNING: Path {path} expired, TTL: {ttl}")
        RelayerHelper.DeletePath(path)
        connection["path-info"] = None
        return Connect(connection, timeout)
    elif ttl == None:
        raise Exception(f"Failed to read TTL")

    if not IsConnected(connection):
        raise Exception(
            f"Failed to connect {chain_id_src} and {chain_id_dst} via {path}")

    connection["ttl"] = ttl = RelayerHelper.GetRemainingTimesToLive(connection)
    if not ttl:  # Assert there are no networking issues, NOTE: Auto rotate RPC add should occur before this section
        raise Exception(
            f"Failed to acquire TTL information of chain {chain_id_src} and {chain_id_dst} connected via {path} path"
        )

    print(
        f"SUCCESS: Chains {chain_id_src} and {chain_id_dst} are connected, TTL: {ttl}"
    )
    connection["path-info"] = path_info = RelayerHelper.QueryPath(
        path)  # rly pth show kira-alpha_gameofzoneshub-1 -j

    if not path_info:  # assert path info availability
        raise Exception(
            f"Failed to acquire path information of a successfully connected chain {chain_id_src} and {chain_id_dst} connected via {path}"
        )

    return connection
Beispiel #24
0
def ReArmConnection(connection, timeout):
    print(f"INFO: Re-arming connection...")
    chain_info_src = connection["src"]
    chain_info_dst = connection["dst"]
    chain_id_src = chain_info_src["chain-id"]
    chain_id_dst = chain_info_dst["chain-id"]
    path = connection["path"]

    print(f"INFO: Updating lite clients...")
    if not UpdateLiteClients(connection):
        print(f"WARNING: Failed to update lite clients, restarting...")
        if not RestartLiteClients(connection):
            raise Exception(
                f"Failed to restart lite clients, connection can't be established, exiting..."
            )

    status = QueryStatus(path)

    if TestStatus(status):
        print(f"INFO: Path {path} was already connected")
        return True

    if (not (not status)):
        print(
            f"INFO: Path {path} status: Chains {status['chains']} | Clients {status['clients']} | Connection {status['connection']} | Channel {status['channel']}"
        )

        if not status["clients"]:
            if not RelayerHelper.TransactClients(
                    path, timeout
            ):  # rly transact clients kira-alpha_kira-1-1b --debug
                print(
                    f"ERROR: Failed to create clients (Step 1) between {chain_id_src} and {chain_id_dst}, path: '{path}'"
                )
                return False
            else:
                print(
                    f"SUCCESS: Established clients (Step 1) between {chain_id_src} and {chain_id_dst}, path: '{path}'"
                )

        if not status["connection"]:
            if not RelayerHelper.TransactConnection(
                    path, timeout
            ):  # rly transact connection kira-alpha_kira-1-1b --debug
                print(
                    f"ERROR: Failed to create connection (step 2) between {chain_id_src} and {chain_id_dst}, path: '{path}'"
                )
                return False
            else:
                print(
                    f"SUCCESS: Established connection (Step 2) between {chain_id_src} and {chain_id_dst}, path: '{path}'"
                )

        if not status[
                "channel"]:  # rly transact channel kira-alpha_kira-1-1b --debug
            if not RelayerHelper.TransactChannel(path, timeout):
                print(
                    f"ERROR: Failed to create channel (step 3) between {chain_id_src} and {chain_id_dst}, path: '{path}'"
                )
                return False
            else:
                print(
                    f"SUCCESS: Established channel (Step 3) between {chain_id_src} and {chain_id_dst}, path: '{path}'"
                )
    return True
Beispiel #25
0
    "max-init-time", init_time)
connection["min-init-time"] = min_init_time = state_file.get(
    "min-init-time", init_time)
upload_time = connection["upload-time"] = state_file.get(
    "upload-time", 0)  # time when state_info was uploaded for the last time
total_uptime = connection["total-uptime"] = state_file.get("total-uptime", 0)
total_transactions = connection["total-transactions"] = state_file.get(
    "total-transactions", 0)
loop_start = time_start

failed_tx_counter = 0
src_gas_min = src.get("gas-min", 200001)
dst_gas_min = dst.get("gas-min", 200001)
src_gas_max = src.get("gas-max", src_gas_min)
dst_gas_max = dst.get("gas-max", src_gas_min)
src_cfg = RelayerHelper.ShowChain(src_chain_id)  # rly ch show kira-alpha -j
dst_cfg = RelayerHelper.ShowChain(dst_chain_id)  # rly ch show kira-1 -j
src_gas_default = src_cfg.get("gas", src_gas_min)
dst_gas_default = dst_cfg.get("gas", dst_gas_min)

print(f"INFO: Connection was established within {init_time}s")
print(f"INFO: Max init time: {max_init_time}s")
print(f"INFO: Min init time: {min_init_time}s")
print(
    f"INFO: SRC => Gas Min ({src_gas_min}), Gas Now ({src_gas_default}), Gas Max ({src_gas_max})"
)
print(
    f"INFO: DST => Gas Min ({dst_gas_min}), Gas Now ({dst_gas_default}), Gas Max ({dst_gas_max})"
)

while True: