From 0fda10d4e6f4c8eef7eefc62ed997638baf5dd78 Mon Sep 17 00:00:00 2001 From: holgern <holgernahrstaedt@gmx.de> Date: Wed, 8 Apr 2020 13:17:59 +0200 Subject: [PATCH] Add default_chain to storage * Add get_blockchain_name to Steem, returns either steem or hive * Add switch_blockchain to Steem, can be used to switch between hive and steem * Storage has now a new config "default_chain", can be either hive or steem * updatenode --hive switches to hive and use hive nodes * updatenode --steem switches to steem and use steem nodes --- CHANGELOG.rst | 5 +++ beem/cli.py | 41 ++++++++++++++++------ beem/nodelist.py | 28 ++++++++------- beem/steem.py | 70 ++++++++++++++++++++++++++++--------- beem/storage.py | 9 ++++- tests/beem/test_cli.py | 4 +-- tests/beem/test_nodelist.py | 18 +++++++++- 7 files changed, 132 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a3f1a2ae..a2c0b79b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,6 +8,11 @@ Changelog * Add get_hive_nodes and get_steem_nodes functions to NodeList * beempy command resteem renamed to reblog * When using in shell mode, beempy walletinfo --unlock can be used to unlock the wallet and walletinfo --lock to unlock it again +* Add get_blockchain_name to Steem, returns either steem or hive +* Add switch_blockchain to Steem, can be used to switch between hive and steem +* Storage has now a new config "default_chain", can be either hive or steem +* updatenode --hive switches to hive and use hive nodes +* updatenode --steem switches to steem and use steem nodes 0.22.13 ------- diff --git a/beem/cli.py b/beem/cli.py index 0849598a..cfad9d5a 100644 --- a/beem/cli.py +++ b/beem/cli.py @@ -257,6 +257,8 @@ def set(key, value): stm.set_default_nodes(value) else: stm.set_default_nodes("") + elif key == "default_chain": + stm.config["default_chain"] = value elif key == "password_storage": stm.config["password_storage"] = value if KEYRING_AVAILABLE and value == "keyring": @@ -418,7 +420,7 @@ def currentnode(version, url): t.add_row(["Node-Url", node[0]]) if not offline: t.add_row(["Version", stm.get_blockchain_version()]) - t.add_row(["HIVE", stm.is_hive]) + t.add_row(["Chain", stm.get_blockchain_name()]) else: t.add_row(["Version", "steempy is in offline mode..."]) print(t) @@ -430,7 +432,10 @@ def currentnode(version, url): help="Prints the updated nodes") @click.option( '--hive', '-h', is_flag=True, default=False, - help="Use only HIVE nodes, when set to true.") + help="Switch to HIVE blockchain, when set to true.") +@click.option( + '--steem', '-e', is_flag=True, default=False, + help="Switch to STEEM nodes, when set to true.") @click.option( '--test', '-t', is_flag=True, default=False, help="Do change the node list, only print the newest nodes setup.") @@ -440,23 +445,37 @@ def currentnode(version, url): @click.option( '--only-wss', '-w', is_flag=True, default=False, help="Use only websocket nodes.") -@click.option( - '--only-appbase', '-a', is_flag=True, default=False, - help="Use only appbase nodes") -@click.option( - '--only-non-appbase', '-n', is_flag=True, default=False, - help="Use only non-appbase nodes") -def updatenodes(show, hive, test, only_https, only_wss, only_appbase, only_non_appbase): +def updatenodes(show, hive, steem, test, only_https, only_wss): """ Update the nodelist from @fullnodeupdate """ stm = shared_steem_instance() if stm.rpc is not None: stm.rpc.rpcconnect() + if steem and hive: + print("hive and steem cannot be active both") + return t = PrettyTable(["node", "Version", "score"]) t.align = "l" + if steem: + blockchain = "steem" + elif hive: + blockchain = "hive" + else: + blockchain = stm.config["default_chain"] nodelist = NodeList() nodelist.update_nodes(steem_instance=stm) - nodes = nodelist.get_nodes(hive=hive, exclude_limited=False, normal=not only_appbase, appbase=not only_non_appbase, wss=not only_https, https=not only_wss) + if hive: + nodes = nodelist.get_hive_nodes(wss=not only_https, https=not only_wss) + if stm.config["default_chain"] == "steem": + stm.config["default_chain"] = "hive" + elif steem: + nodes = nodelist.get_steem_nodes(wss=not only_https, https=not only_wss) + if stm.config["default_chain"] == "hive": + stm.config["default_chain"] = "steem" + elif stm.config["default_chain"] == "steem": + nodes = nodelist.get_steem_nodes(wss=not only_https, https=not only_wss) + else: + nodes = nodelist.get_hive_nodes(wss=not only_https, https=not only_wss) if show or test: sorted_nodes = sorted(nodelist, key=lambda node: node["score"], reverse=True) for node in sorted_nodes: @@ -480,7 +499,9 @@ def config(): if key in availableConfigurationKeys and key != "nodes" and key != "node": t.add_row([key, stm.config[key]]) node = stm.get_default_nodes() + blockchain = stm.config["default_chain"] nodes = json.dumps(node, indent=4) + t.add_row(["default_chain", blockchain]) t.add_row(["nodes", nodes]) if "password_storage" not in availableConfigurationKeys: t.add_row(["password_storage", stm.config["password_storage"]]) diff --git a/beem/nodelist.py b/beem/nodelist.py index a95b4581..4c90509d 100644 --- a/beem/nodelist.py +++ b/beem/nodelist.py @@ -50,14 +50,6 @@ class NodeList(list): "hive": False, "score": -10 }, - { - "url": "https://steemd.privex.io", - "version": "0.20.2", - "type": "appbase", - "owner": "privex", - "hive": False, - "score": 50 - }, { "url": "https://steemd.minnowsupportproject.org", "version": "0.19.12", @@ -307,17 +299,22 @@ class NodeList(list): return [node["url"] for node in sorted(node_list, key=lambda self: self['score'], reverse=True)] - def get_hive_nodes(self, not_working=False, wss=True, https=True): + def get_hive_nodes(self, testnet=False, not_working=False, wss=True, https=True): """ Returns hive only nodes as list + :param bool testnet: when True, testnet nodes are included :param bool not_working: When True, all nodes including not working ones will be returned """ node_list = [] node_type_list = [] - + for node in self: - if node["hive"] and (node["score"] >= 0 or not_working): + if not node["hive"]: + continue + if (node["score"] < 0 and not not_working): + continue + if (testnet and node["type"] == "testnet") or (not testnet and node["type"] != "testnet"): if not https and node["url"][:5] == 'https': continue if not wss and node["url"][:3] == 'wss': @@ -326,9 +323,10 @@ class NodeList(list): return [node["url"] for node in sorted(node_list, key=lambda self: self['score'], reverse=True)] - def get_steem_nodes(self, not_working=False, wss=True, https=True): + def get_steem_nodes(self, testnet=False, not_working=False, wss=True, https=True): """ Returns steem only nodes as list + :param bool testnet: when True, testnet nodes are included :param bool not_working: When True, all nodes including not working ones will be returned """ @@ -336,7 +334,11 @@ class NodeList(list): node_type_list = [] for node in self: - if not node["hive"] and (node["score"] >= 0 or not_working): + if node["hive"]: + continue + if (node["score"] < 0 and not not_working): + continue + if (testnet and node["type"] == "testnet") or (not testnet and node["type"] != "testnet"): if not https and node["url"][:5] == 'https': continue if not wss and node["url"][:3] == 'wss': diff --git a/beem/steem.py b/beem/steem.py index 7360620f..1fff34b4 100644 --- a/beem/steem.py +++ b/beem/steem.py @@ -194,22 +194,7 @@ class Steem(object): rpcpassword=rpcpassword, **kwargs) - self.data = {'last_refresh': None, 'last_node': None, - 'last_refresh_dynamic_global_properties': None, - 'dynamic_global_properties': None, - 'feed_history': None, - 'get_feed_history': None, - 'last_refresh_feed_history': None, - 'hardfork_properties': None, - 'last_refresh_hardfork_properties': None, - 'network': None, - 'last_refresh_network': None, - 'witness_schedule': None, - 'last_refresh_witness_schedule': None, - 'config': None, - 'last_refresh_config': None, - 'reward_funds': None, - 'last_refresh_reward_funds': None} + self.clear_data() self.data_refresh_time_seconds = data_refresh_time_seconds # self.refresh_data() @@ -264,6 +249,25 @@ class Steem(object): return "<%s, nobroadcast=%s>" % ( self.__class__.__name__, str(self.nobroadcast)) + def clear_data(self): + """ Clears all stored blockchain parameters""" + self.data = {'last_refresh': None, 'last_node': None, + 'last_refresh_dynamic_global_properties': None, + 'dynamic_global_properties': None, + 'feed_history': None, + 'get_feed_history': None, + 'last_refresh_feed_history': None, + 'hardfork_properties': None, + 'last_refresh_hardfork_properties': None, + 'network': None, + 'last_refresh_network': None, + 'witness_schedule': None, + 'last_refresh_witness_schedule': None, + 'config': None, + 'last_refresh_config': None, + 'reward_funds': None, + 'last_refresh_reward_funds': None} + def refresh_data(self, property, force_refresh=False, data_refresh_time_seconds=None): """ Read and stores steem blockchain parameters If the last data refresh is older than data_refresh_time_seconds, data will be refreshed @@ -511,6 +515,17 @@ class Steem(object): blockchain_version = props[key] return blockchain_version + def get_blockchain_name(self, use_stored_data=True): + """Returns the blockchain version""" + props = self.get_config(use_stored_data=use_stored_data) + blockchain_name = '' + if props is None: + return blockchain_version + for key in props: + if key[-18:] == "BLOCKCHAIN_VERSION": + blockchain_name = key.split("_")[0].lower() + return blockchain_name + def get_dust_threshold(self, use_stored_data=True): """Returns the vote dust threshold""" props = self.get_config(use_stored_data=use_stored_data) @@ -893,6 +908,29 @@ class Steem(object): Account(account, steem_instance=self) self.config["default_account"] = account + def switch_blockchain(self, blockchain, update_nodes=False): + """ Switches the connected blockchain. Can be either hive or steem. + + :param str blockchain: can be "hive" or "steem" + :param bool update_nodes: When true, the nodes are updated, using + NodeList.update_nodes() + """ + assert blockchain in ["hive", "steem"] + if blockchain == self.config["default_chain"] and not update_nodes: + return + from beem.nodelist import NodeList + nodelist = NodeList() + if update_nodes: + nodelist.update_nodes() + if blockchain == "hive": + self.set_default_nodes(nodelist.get_hive_nodes()) + else: + self.set_default_nodes(nodelist.get_steem_nodes()) + self.config["default_chain"] = blockchain + if not self.offline: + self.connect(node="") + + def set_password_storage(self, password_storage): """ Set the password storage mode. diff --git a/beem/storage.py b/beem/storage.py index 87b6cb6e..8c0a51cf 100644 --- a/beem/storage.py +++ b/beem/storage.py @@ -404,9 +404,16 @@ class Configuration(DataDir): #: Default configuration nodelist = NodeList() - nodes = nodelist.get_nodes(normal=True, appbase=True, dev=False, testnet=False) + blockchain = "steem" # will be changed to hive in the next release + if blockchain == "hive": + nodes = nodelist.get_hive_nodes(testnet=False) + elif blockchain == "steem": + nodes = nodelist.get_steem_nodes(testnet=False) + else: + nodes = [] config_defaults = { "node": nodes, + "default_chain": blockchain, "password_storage": "environment", "rpcpassword": "", "rpcuser": "", diff --git a/tests/beem/test_cli.py b/tests/beem/test_cli.py index 90a53735..33af36fd 100644 --- a/tests/beem/test_cli.py +++ b/tests/beem/test_cli.py @@ -322,9 +322,9 @@ class Testcases(unittest.TestCase): result = runner.invoke(cli, ['openorders']) self.assertEqual(result.exit_code, 0) - def test_resteem(self): + def test_reblog(self): runner = CliRunner() - result = runner.invoke(cli, ['-dto', 'resteem', '@steemit/firstposte'], input="test\n") + result = runner.invoke(cli, ['-dto', 'reblog', '@steemit/firstpost'], input="test\n") self.assertEqual(result.exit_code, 0) def test_follow_unfollow(self): diff --git a/tests/beem/test_nodelist.py b/tests/beem/test_nodelist.py index 6bd1eebb..baf1fd80 100644 --- a/tests/beem/test_nodelist.py +++ b/tests/beem/test_nodelist.py @@ -15,7 +15,7 @@ class Testcases(unittest.TestCase): def setUpClass(cls): nodelist = NodeList() cls.bts = Steem( - node=nodelist.get_nodes(exclude_limited=False), + node=nodelist.get_nodes(), nobroadcast=True, num_retries=10 ) @@ -28,6 +28,22 @@ class Testcases(unittest.TestCase): https_nodes = nodelist.get_nodes(wss=False) self.assertEqual(https_nodes[0][:5], 'https') + def test_hive_nodes(self): + nodelist = NodeList() + nodelist.update_nodes() + hive_nodes = nodelist.get_hive_nodes() + for node in hive_nodes: + blockchainobject = Steem(node=node) + assert blockchainobject.is_hive + + def test_steem_nodes(self): + nodelist = NodeList() + nodelist.update_nodes() + steem_nodes = nodelist.get_steem_nodes() + for node in steem_nodes: + blockchainobject = Steem(node=node) + assert not blockchainobject.is_hive + def test_nodes_update(self): nodelist = NodeList() all_nodes = nodelist.get_nodes(exclude_limited=False, dev=True, testnet=True) -- GitLab