diff --git a/indy_node/server/config_req_handler.py b/indy_node/server/config_req_handler.py index 8cee34dc4..987667dc6 100644 --- a/indy_node/server/config_req_handler.py +++ b/indy_node/server/config_req_handler.py @@ -47,7 +47,7 @@ def _doStaticValidationPoolUpgrade(self, identifier, reqId, operation): force = operation.get(FORCE) force = str(force) == 'True' isValid, msg = self.upgrader.isScheduleValid( - schedule, self.poolManager.nodeIds, force) + schedule, self.poolManager.getNodesServices(), force) if not isValid: raise InvalidClientRequest(identifier, reqId, "{} not a valid schedule since {}". diff --git a/indy_node/server/upgrader.py b/indy_node/server/upgrader.py index faf54edf2..4189423e5 100644 --- a/indy_node/server/upgrader.py +++ b/indy_node/server/upgrader.py @@ -253,19 +253,20 @@ def didLastExecutedUpgradeSucceeded(self) -> bool: return self.compareVersions(currentVersion, scheduledVersion) == 0 return False - def isScheduleValid(self, schedule, nodeIds, force) -> (bool, str): + def isScheduleValid(self, schedule, node_srvs, force) -> (bool, str): """ Validates schedule of planned node upgrades :param schedule: dictionary of node ids and upgrade times - :param nodeIds: real node ids + :param nodeSrvs: dictionary of node ids and services :return: whether schedule valid """ # flag "force=True" ignore basic checks! only datetime format is # checked times = [] - if not force and set(schedule.keys()) != nodeIds: + non_demoted_nodes = set([k for k, v in node_srvs.items() if v]) + if not force and set(schedule.keys()) != non_demoted_nodes: return False, 'Schedule should contain id of all nodes' now = datetime.utcnow().replace(tzinfo=dateutil.tz.tzutc()) for dateStr in schedule.values(): diff --git a/indy_node/test/upgrade/test_upgrade_pool_with_demoted_nodes.py b/indy_node/test/upgrade/test_upgrade_pool_with_demoted_nodes.py new file mode 100644 index 000000000..34c6cb1f9 --- /dev/null +++ b/indy_node/test/upgrade/test_upgrade_pool_with_demoted_nodes.py @@ -0,0 +1,30 @@ +from indy_node.test import waits +from stp_core.loop.eventually import eventually +from plenum.common.constants import ALIAS, SERVICES, VERSION +from indy_common.constants import SCHEDULE +from indy_node.test.upgrade.helper import ensureUpgradeSent, checkUpgradeScheduled + +from plenum.test.pool_transactions.helper import updateNodeData +from plenum.test.conftest import pool_txn_stewards_data, stewards_and_wallets + + +def test_update_with_demoted_node(looper, nodeSet, validUpgrade, + stewards_and_wallets, trustee, trusteeWallet): + # demote one node + node_steward_cl, steward_wallet = stewards_and_wallets[3] + node_data = { + ALIAS: nodeSet[3].name, + SERVICES: [] + } + updateNodeData(looper, node_steward_cl, steward_wallet, nodeSet[3], node_data) + + # remove demoted node from upgrade schedule + upgr = validUpgrade + del upgr[SCHEDULE][nodeSet[3].id] + + # send upgrade + ensureUpgradeSent(looper, trustee, trusteeWallet, upgr) + + # check upg scheduled + looper.run(eventually(checkUpgradeScheduled, nodeSet[:3], upgr[VERSION], retryWait=1, + timeout=waits.expectedUpgradeScheduled())) diff --git a/setup.py b/setup.py index 640125826..3c7c6f898 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ data_files=[( (BASE_DIR, ['data/nssm_original.exe']) )], - install_requires=['indy-plenum-dev==1.2.225', + install_requires=['indy-plenum-dev==1.2.226', 'indy-anoncreds-dev==1.0.32', 'python-dateutil', 'timeout-decorator'],