Skip to content

Commit

Permalink
Mat/fix error handling version check (#131)
Browse files Browse the repository at this point in the history
* feat: improve error logging when connecting with wrong chain.

* refactor: make version check in a function

* fix: make option to not check for chain version

* chore: add test
  • Loading branch information
matthiasmatt authored Sep 8, 2022
1 parent 57ba53b commit d36197c
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 5 deletions.
51 changes: 48 additions & 3 deletions nibiru/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@

import nibiru.query_clients
from nibiru.network import Network
from nibiru.utils import init_logger

DEFAULT_TIMEOUTHEIGHT = 20 # blocks
GITHUB_COMMIT_HASH_LEN = 40


class GrpcClient:
Expand All @@ -31,7 +33,17 @@ def __init__(
network: Network,
insecure=False,
credentials: grpc.ChannelCredentials = None,
bypass_version_check: bool = False,
):
"""
_summary_
Args:
network (Network): The network object
insecure (bool, optional): Wether the network should use ssl or not. Defaults to False.
credentials (grpc.ChannelCredentials, optional): Ssl creds. Defaults to None.
bypass_version_check (bool, optional): Wether to bypass the check for correct version of the chain/py-sdk
"""

# load root CA cert
if not insecure:
Expand Down Expand Up @@ -61,10 +73,43 @@ def __init__(
self.perp = nibiru.query_clients.PerpQueryClient(self.chain_channel)
self.vpool = nibiru.query_clients.VpoolQueryClient(self.chain_channel)

# Assert that we use the correct version of the chain
nibiru_proto_version = importlib_metadata.version("nibiru_proto")
if not bypass_version_check:
self.assert_compatible_versions(
nibiru_proto_version=importlib_metadata.version("nibiru_proto"),
chain_nibiru_version=str(self.get_version()),
)

def assert_compatible_versions(self, nibiru_proto_version, chain_nibiru_version):
"""
Assert that this version of the python sdk is compatible with the chain.
If you run the chain from a non tagged release, the version query will be returning something like
master-6a315bab3db46f5fa1158199acc166ed2d192c2f. Otherwise, it should be for example `v0.14.0`.
assert nibiru_proto_version.split(".") >= self.get_version()[1:].split(".")
If the chain is running a custom non tagged release, you are free to use the python sdk at your own risk.
"""
if nibiru_proto_version[0] == "v":
nibiru_proto_version = nibiru_proto_version[1:]
if chain_nibiru_version[0] == "v":
chain_nibiru_version = chain_nibiru_version[1:]

if len(chain_nibiru_version) >= GITHUB_COMMIT_HASH_LEN:
logger = init_logger("client-logger")
logger.warning(
f"The chain is running a custom release from branch/commit {chain_nibiru_version}. "
"We bypass the compatibility assertion"
)
logger.warning(
f"The chain is running a custom release from branch/commit {chain_nibiru_version}"
)
else:
nibiru_proto_version = tuple(map(int, nibiru_proto_version.split(".")))
chain_nibiru_version = tuple(map(int, chain_nibiru_version.split(".")))

error_string = (
f"Version error, Python sdk runs with nibiru protobuf version {nibiru_proto_version}, but the "
f"remote chain is running with version {chain_nibiru_version}"
)
assert nibiru_proto_version >= chain_nibiru_version, error_string

def close_chain_channel(self):
self.chain_channel.close()
Expand Down
11 changes: 9 additions & 2 deletions nibiru/sdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,26 @@ def authorize(cls, key: str = None) -> "Sdk":

return self

def with_network(self, network: Network, insecure=False) -> "Sdk":
def with_network(
self, network: Network, insecure=False, bypass_version_check: bool = False
) -> "Sdk":
"""
Change the network of the sdk to the specified network.
Args:
network (Network): A network object
insecure (bool, optional): Wether the connection should be insecure or not. Defaults to False.
bypass_version_check (bool, optional): Wether to bypass the check for correct version of the chain/py-sdk
Returns:
Sdk: The updated sdk object
"""
self.network = network
self._with_query_client(GrpcClient(self.network, insecure))
self._with_query_client(
GrpcClient(
self.network, insecure, bypass_version_check=bypass_version_check
)
)
return self

def with_config(self, config: TxConfig) -> "Sdk":
Expand Down
21 changes: 21 additions & 0 deletions tests/chain_info_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os
from typing import Any, Dict, List, Union

import pytest
import requests

from nibiru import Sdk
Expand All @@ -23,6 +24,26 @@ def test_get_chain_id(val_node: Sdk):
assert val_node.network.chain_id == val_node.query.get_chain_id()


def test_version_works(val_node: Sdk):
tests = [
{"should_fail": False, "versions": ["0.3.2", "0.3.2"]},
{"should_fail": True, "versions": ["0.3.2", "0.3.4"]},
{"should_fail": True, "versions": ["0.3.2", "0.4.1"]},
{"should_fail": True, "versions": ["0.3.2", "1.0.0"]},
{
"should_fail": False,
"versions": ["0.3.2", "master-6a315bab3db46f5fa1158199acc166ed2d192c2f"],
},
]

for test in tests:
if test["should_fail"]:
with pytest.raises(AssertionError, match="Version error"):
val_node.query.assert_compatible_versions(*test["versions"])
else:
val_node.query.assert_compatible_versions(*test["versions"])


def test_query_perp_params(val_node: Sdk):
params: Dict[str, Union[float, str]] = val_node.query.perp.params()
perp_param_names: List[str] = [
Expand Down

0 comments on commit d36197c

Please sign in to comment.