Example #1
0
    def setUp(self) -> None:
        self.blockchain_name = 'testblockchain'
        self.logger = logging.getLogger('dummy')

        self.blockchain = Blockchain(name=self.blockchain_name, redis=None)

        self.counter_channel = CounterChannel(self.logger)
        self.channel_set = ChannelSet([self.counter_channel], TestInternalConf)

        self.dummy_referendum_count, self.dummy_public_prop_count, \
        self.dummy_council_prop_count = 10, 10, 10
        self.dummy_validator_set_size = 120
        self.dummy_referendum_info_ongoing = {
            'Ongoing': {
                'proposalHash': '0x345jtg8ergfg8df89h9we9t9sd9g9gsd9g9sdfg',
                'end': 124143848,
                'threshold': 'Supermajorityapproval',
                'delay': 11549,
                'tally': {
                    'ayes': '4544545 KSM',
                    'nayes': '3454 KSM',
                    'turnout': '4545454454 KSM'
                }
            }
        }
        self.dummy_referendum_info_finished = {
            'Finished': {
                'approved': False,
                'end': 124143848
            }
        }
    def setUp(self) -> None:
        self.blockchain_name = 'testblockchain'
        self.redis_prefix = self.blockchain_name
        self.logger = logging.getLogger('dummy')
        self.counter_channel = CounterChannel(self.logger)
        self.channel_set = ChannelSet([self.counter_channel])

        self.db = TestInternalConf.redis_test_database
        self.host = TestUserConf.redis_host
        self.port = TestUserConf.redis_port
        self.password = TestUserConf.redis_password
        self.redis = RedisApi(self.logger, self.db, self.host, self.port,
                              self.password)
        self.redis.delete_all_unsafe()

        try:
            self.redis.ping_unsafe()
        except RedisConnectionError:
            self.fail('Redis is not online.')

        self.blockchain = Blockchain(self.blockchain_name, self.redis)
        self.dummy_referendum_count = 10
        self.dummy_council_prop_count = 10
        self.dummy_public_prop_count = 10
        self.dummy_validator_set_size = 120
Example #3
0
    def setUp(self) -> None:
        self.logger = logging.getLogger('dummy')
        self.monitor_name = 'testblockchainmonitor'
        self.counter_channel = CounterChannel(self.logger)
        self.channel_set = ChannelSet([self.counter_channel], TestInternalConf)
        self.redis = None
        self.data_sources = []
        self.polkadot_api_endpoint = 'api_endpoint'

        self.dummy_ws_url_1 = "11.22.33.11:9944"
        self.dummy_ws_url_2 = "11.22.33.12:9944"
        self.dummy_ws_url_3 = "11.22.33.13:9944"
        self.dummy_ws_url_4 = "11.22.33.14:9944"
        self.dummy_node_name_1 = "testnode1"
        self.dummy_node_name_2 = "testnode2"
        self.dummy_node_name_3 = "testnode3"
        self.dummy_node_name_4 = "testnode4"
        self.dummy_chain_name = "testchain"
        self.validator_stash_account_address = "DFJGDF8G898fdghb98dg9wetg9we00w"
        self.dummy_full_node_1 = Node(name=self.dummy_node_name_1,
                                      ws_url=self.dummy_ws_url_1,
                                      node_type=NodeType.NON_VALIDATOR_FULL_NODE,
                                      stash_account_address='',
                                      chain=self.dummy_chain_name, redis=None,
                                      is_archive_node=True,
                                      internal_conf=TestInternalConf)
        self.dummy_full_node_2 = Node(name=self.dummy_node_name_2,
                                      ws_url=self.dummy_ws_url_2,
                                      node_type=NodeType.NON_VALIDATOR_FULL_NODE,
                                      stash_account_address='',
                                      chain=self.dummy_chain_name, redis=None,
                                      is_archive_node=True,
                                      internal_conf=TestInternalConf)
        self.dummy_full_node_3 = Node(name=self.dummy_node_name_3,
                                      ws_url=self.dummy_ws_url_3,
                                      node_type=NodeType.NON_VALIDATOR_FULL_NODE,
                                      stash_account_address='',
                                      chain=self.dummy_chain_name, redis=None,
                                      is_archive_node=True,
                                      internal_conf=TestInternalConf)
        self.dummy_validator_node_1 = Node(
            name=self.dummy_node_name_4, ws_url=self.dummy_ws_url_4,
            node_type=NodeType.VALIDATOR_FULL_NODE,
            stash_account_address=self.validator_stash_account_address,
            chain=self.dummy_chain_name, redis=None, is_archive_node=False,
            internal_conf=TestInternalConf)

        self.dummy_blockchain = Blockchain(self.dummy_chain_name, None)
        self.monitor = BlockchainMonitor(self.monitor_name,
                                         self.dummy_blockchain,
                                         self.channel_set, self.logger,
                                         self.redis, self.data_sources,
                                         self.polkadot_api_endpoint,
                                         TestInternalConf)
        self.dummy_referendum_count = 10
        self.dummy_public_prop_count = 10
        self.dummy_council_prop_count = 10
        self.dummy_validator_set_size = 120
    def setUp(self) -> None:
        self.blockchain_name = 'testblockchain'
        self.logger = logging.getLogger('dummy')

        self.blockchain = Blockchain(name=self.blockchain_name, redis=None)

        self.counter_channel = CounterChannel(self.logger)
        self.channel_set = ChannelSet([self.counter_channel])

        self.dummy_referendum_count, self.dummy_public_prop_count, \
        self.dummy_council_prop_count = 10, 10, 10
        self.dummy_validator_set_size = 120
        self.dummy_referendum_info = {'end': '8568'}
Example #5
0
    def setUp(self) -> None:
        self.logger = logging.getLogger('dummy')
        self.monitor_name = 'testblockchainmonitor'
        self.blockchain_name = 'testblockchain'
        self.counter_channel = CounterChannel(self.logger)
        self.channel_set = ChannelSet([self.counter_channel], TestInternalConf)

        self.db = TestInternalConf.redis_test_database
        self.host = TestUserConf.redis_host
        self.port = TestUserConf.redis_port
        self.password = TestUserConf.redis_password
        self.redis = RedisApi(self.logger, self.db, self.host, self.port,
                              self.password)
        self.redis.delete_all_unsafe()

        try:
            self.redis.ping_unsafe()
        except RedisConnectionError:
            self.fail('Redis is not online.')

        self.data_sources = []
        self.blockchain = Blockchain(self.blockchain_name, self.redis)
        self.polkadot_api_endpoint = 'api_endpoint'
        self.monitor = BlockchainMonitor(self.monitor_name, self.blockchain,
                                         self.channel_set, self.logger,
                                         self.redis, self.data_sources,
                                         self.polkadot_api_endpoint,
                                         TestInternalConf)

        self.redis_alive_key_timeout = \
            TestInternalConf.redis_blockchain_monitor_alive_key_timeout
        self.alive_key_timeout = \
            TestInternalConf.redis_blockchain_monitor_alive_key_timeout
Example #6
0
def run_monitor_blockchain(blockchain_nodes_tuple: Tuple[str, List[Node]]):
    # Get blockchain and nodes
    blockchain_name = blockchain_nodes_tuple[0]
    data_sources = blockchain_nodes_tuple[1]

    # Monitor name based on blockchain
    monitor_name = 'Blockchain monitor ({})'.format(blockchain_name)

    # Initialisation
    try:
        # Logger initialisation
        logger_monitor_blockchain = create_logger(
            InternalConf.blockchain_monitor_general_log_file_template.format(
                blockchain_name),
            blockchain_name,
            InternalConf.logging_level,
            rotating=True)

        # Create blockchain object
        blockchain = Blockchain(blockchain_name, REDIS)

        # Initialise monitor
        blockchain_monitor = BlockchainMonitor(monitor_name, blockchain,
                                               full_channel_set,
                                               logger_monitor_blockchain,
                                               REDIS, data_sources,
                                               UserConf.polkadot_api_endpoint)
    except Exception as e:
        msg = '!!! Error when initialising {}: {} !!!'.format(monitor_name, e)
        log_and_print(msg)
        raise InitialisationException(msg)

    while True:
        # Start
        log_and_print('{} started'.format(monitor_name))
        sys.stdout.flush()
        try:
            start_blockchain_monitor(
                blockchain_monitor,
                InternalConf.blockchain_monitor_period_seconds,
                logger_monitor_blockchain)
        except (UnexpectedApiCallErrorException,
                UnexpectedApiErrorWhenReadingDataException) as e:
            full_channel_set.alert_error(
                TerminatedDueToFatalExceptionAlert(monitor_name, e))
            log_and_print('{} stopped.'.format(monitor_name))
            break
        except Exception as e:
            full_channel_set.alert_error(
                TerminatedDueToExceptionAlert(monitor_name, e))
        log_and_print('{} stopped.'.format(monitor_name))
class TestBlockchainWithRedis(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        # Same as in setUp(), to avoid running all tests if Redis is offline

        logger = logging.getLogger('dummy')
        db = TestInternalConf.redis_test_database
        host = TestUserConf.redis_host
        port = TestUserConf.redis_port
        password = TestUserConf.redis_password
        redis = RedisApi(logger, db, host, port, password)

        try:
            redis.ping_unsafe()
        except RedisConnectionError:
            raise Exception('Redis is not online.')

    def setUp(self) -> None:
        self.blockchain_name = 'testblockchain'
        self.redis_prefix = self.blockchain_name
        self.logger = logging.getLogger('dummy')
        self.counter_channel = CounterChannel(self.logger)
        self.channel_set = ChannelSet([self.counter_channel])

        self.db = TestInternalConf.redis_test_database
        self.host = TestUserConf.redis_host
        self.port = TestUserConf.redis_port
        self.password = TestUserConf.redis_password
        self.redis = RedisApi(self.logger, self.db, self.host, self.port,
                              self.password)
        self.redis.delete_all_unsafe()

        try:
            self.redis.ping_unsafe()
        except RedisConnectionError:
            self.fail('Redis is not online.')

        self.blockchain = Blockchain(self.blockchain_name, self.redis)
        self.dummy_referendum_count = 10
        self.dummy_council_prop_count = 10
        self.dummy_public_prop_count = 10
        self.dummy_validator_set_size = 120

    def test_load_state_changes_nothing_if_nothing_saved(self):
        self.blockchain.load_state(self.logger)

        self.assertIsNone(self.blockchain.validator_set_size)
        self.assertIsNone(self.blockchain.public_prop_count)
        self.assertIsNone(self.blockchain.council_prop_count)
        self.assertIsNone(self.blockchain.validator_set_size)

    def test_load_state_sets_values_to_saved_values(self):
        # Set Redis values manually
        self.redis.set_unsafe(self.redis_prefix + '_referendum_count',
                              self.dummy_referendum_count)
        self.redis.set_unsafe(self.redis_prefix + '_public_prop_count',
                              self.dummy_public_prop_count)
        self.redis.set_unsafe(self.redis_prefix + '_council_prop_count',
                              self.dummy_council_prop_count)
        self.redis.set_unsafe(self.redis_prefix + '_validator_set_size',
                              self.dummy_validator_set_size)

        # Load the Redis values
        self.blockchain.load_state(self.logger)

        # Assert
        self.assertEqual(self.blockchain.referendum_count,
                         self.dummy_referendum_count)
        self.assertEqual(self.blockchain.public_prop_count,
                         self.dummy_public_prop_count)
        self.assertEqual(self.blockchain.council_prop_count,
                         self.dummy_council_prop_count)
        self.assertEqual(self.blockchain.validator_set_size,
                         self.dummy_validator_set_size)

    def test_save_state_sets_values_to_current_values(self):
        # Set blockchain values manually
        self.blockchain.set_referendum_count(self.dummy_referendum_count,
                                             self.channel_set, self.logger)
        self.blockchain.set_council_prop_count(self.dummy_council_prop_count,
                                               self.channel_set, self.logger)
        self.blockchain.set_public_prop_count(self.dummy_public_prop_count,
                                              self.channel_set, self.logger)
        self.blockchain.set_validator_set_size(self.dummy_validator_set_size,
                                               self.channel_set, self.logger)

        # Save the values to Redis
        self.blockchain.save_state(self.logger)

        # Assert
        self.assertEqual(
            self.redis.get_int_unsafe(self.redis_prefix + '_referendum_count'),
            self.dummy_referendum_count)
        self.assertEqual(
            self.redis.get_int_unsafe(self.redis_prefix +
                                      '_public_prop_count'),
            self.dummy_public_prop_count)
        self.assertEqual(
            self.redis.get_int_unsafe(self.redis_prefix +
                                      '_council_prop_count'),
            self.dummy_council_prop_count)
        self.assertEqual(
            self.redis.get_int_unsafe(self.redis_prefix +
                                      '_validator_set_size'),
            self.dummy_validator_set_size)
class TestBlockchainWithoutRedis(unittest.TestCase):
    def setUp(self) -> None:
        self.blockchain_name = 'testblockchain'
        self.logger = logging.getLogger('dummy')

        self.blockchain = Blockchain(name=self.blockchain_name, redis=None)

        self.counter_channel = CounterChannel(self.logger)
        self.channel_set = ChannelSet([self.counter_channel])

        self.dummy_referendum_count, self.dummy_public_prop_count, \
        self.dummy_council_prop_count = 10, 10, 10
        self.dummy_validator_set_size = 120
        self.dummy_referendum_info = {'end': '8568'}

    def test_str_returns_blockchain_name(self) -> None:
        self.assertEqual(self.blockchain_name, str(self.blockchain))

    def test_referendum_count_None_by_default(self) -> None:
        self.assertIsNone(self.blockchain.referendum_count)

    def test_public_prop_count_None_by_default(self) -> None:
        self.assertIsNone(self.blockchain.public_prop_count)

    def test_council_prop_count_None_by_default(self) -> None:
        self.assertIsNone(self.blockchain.council_prop_count)

    def test_validator_set_size_None_by_default(self) -> None:
        self.assertIsNone(self.blockchain.validator_set_size)

    def test_status_returns_as_expected(self) -> None:
        self.blockchain.set_validator_set_size(self.dummy_validator_set_size,
                                               self.channel_set, self.logger)
        self.blockchain.set_public_prop_count(self.dummy_public_prop_count,
                                              self.channel_set, self.logger)
        self.blockchain.set_council_prop_count(self.dummy_council_prop_count,
                                               self.channel_set, self.logger)
        self.blockchain.set_referendum_count(self.dummy_referendum_count,
                                             self.channel_set, self.logger)

        self.assertEqual(
            self.blockchain.status(),
            "referendum_count={}, public_prop_count={}, "
            "council_prop_count={}, validator_set_size ={}".format(
                self.dummy_referendum_count, self.dummy_public_prop_count,
                self.dummy_council_prop_count, self.dummy_validator_set_size))

    def test_set_referendum_count_raises_no_alerts_first_time_round(
            self) -> None:
        self.blockchain.set_referendum_count(self.dummy_referendum_count,
                                             self.channel_set, self.logger)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.referendum_count,
                         self.dummy_referendum_count)

    def test_set_referendum_count_raises_no_alerts_if_same_referendum_count(
            self) -> None:
        self.blockchain.set_referendum_count(self.dummy_referendum_count,
                                             self.channel_set, self.logger)
        self.blockchain.set_referendum_count(self.dummy_referendum_count,
                                             self.channel_set, self.logger)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.referendum_count,
                         self.dummy_referendum_count)

    def test_set_referendum_count_raises_no_alerts_if_new_referendum_expired(
            self) -> None:
        self.blockchain.set_referendum_count(self.dummy_referendum_count,
                                             self.channel_set, self.logger)
        new_referendum_count = self.dummy_referendum_count + 1
        self.blockchain.set_referendum_count(new_referendum_count,
                                             self.channel_set, self.logger,
                                             None)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.referendum_count,
                         new_referendum_count)

    def test_set_referendum_count_info_alert_if_new_referendum_not_expired(
            self) -> None:
        self.blockchain.set_referendum_count(self.dummy_referendum_count,
                                             self.channel_set, self.logger)
        new_referendum_count = self.dummy_referendum_count + 1
        self.blockchain.set_referendum_count(new_referendum_count,
                                             self.channel_set, self.logger,
                                             self.dummy_referendum_info)

        self.assertEqual(self.counter_channel.info_count, 1)
        self.assertIsInstance(self.counter_channel.latest_alert,
                              NewReferendumAlert)
        self.assertEqual(self.blockchain.referendum_count,
                         new_referendum_count)

    def test_set_public_prop_count_raises_no_alerts_first_time_round(
            self) -> None:
        self.blockchain.set_public_prop_count(self.dummy_public_prop_count,
                                              self.channel_set, self.logger)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.public_prop_count,
                         self.dummy_public_prop_count)

    def test_set_public_prop_count_raises_no_alerts_if_same_count(
            self) -> None:
        self.blockchain.set_public_prop_count(self.dummy_public_prop_count,
                                              self.channel_set, self.logger)
        self.blockchain.set_public_prop_count(self.dummy_public_prop_count,
                                              self.channel_set, self.logger)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.public_prop_count,
                         self.dummy_public_prop_count)

    def test_set_public_prop_count_1_info_alert_if_increase_by_1(self) -> None:
        self.blockchain.set_public_prop_count(self.dummy_public_prop_count,
                                              self.channel_set, self.logger)
        new_public_prop_count = self.dummy_public_prop_count + 1
        self.blockchain.set_public_prop_count(new_public_prop_count,
                                              self.channel_set, self.logger)

        self.assertEqual(self.counter_channel.info_count, 1)
        self.assertIsInstance(self.counter_channel.latest_alert,
                              NewPublicProposalAlert)
        self.assertEqual(self.blockchain.public_prop_count,
                         new_public_prop_count)

    def test_set_public_prop_count_2_info_alerts_if_increase_by_2(
            self) -> None:
        self.blockchain.set_public_prop_count(self.dummy_public_prop_count,
                                              self.channel_set, self.logger)
        new_public_prop_count = self.dummy_public_prop_count + 2
        self.blockchain.set_public_prop_count(new_public_prop_count,
                                              self.channel_set, self.logger)

        self.assertEqual(self.counter_channel.info_count, 2)
        self.assertIsInstance(self.counter_channel.latest_alert,
                              NewPublicProposalAlert)
        self.assertEqual(self.blockchain.public_prop_count,
                         new_public_prop_count)

    def test_set_council_prop_count_raises_no_alerts_first_time_round(
            self) -> None:
        self.blockchain.set_council_prop_count(self.dummy_council_prop_count,
                                               self.channel_set, self.logger)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.council_prop_count,
                         self.dummy_council_prop_count)

    def test_set_council_prop_count_raises_no_alerts_if_same_count(
            self) -> None:
        self.blockchain.set_council_prop_count(self.dummy_council_prop_count,
                                               self.channel_set, self.logger)
        self.blockchain.set_public_prop_count(self.dummy_council_prop_count,
                                              self.channel_set, self.logger)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.council_prop_count,
                         self.dummy_council_prop_count)

    def test_set_council_prop_count_info_alert_if_increase_by_1(self) -> None:
        self.blockchain.set_council_prop_count(self.dummy_council_prop_count,
                                               self.channel_set, self.logger)
        new_council_prop_count = self.dummy_council_prop_count + 1
        self.blockchain.set_council_prop_count(new_council_prop_count,
                                               self.channel_set, self.logger)

        self.assertEqual(self.counter_channel.info_count, 1)
        self.assertIsInstance(self.counter_channel.latest_alert,
                              NewCouncilProposalAlert)
        self.assertEqual(self.blockchain.council_prop_count,
                         new_council_prop_count)

    def test_set_council_prop_count_info_alert_if_increase_by_2(self) -> None:
        self.blockchain.set_council_prop_count(self.dummy_council_prop_count,
                                               self.channel_set, self.logger)
        new_council_prop_count = self.dummy_council_prop_count + 2
        self.blockchain.set_council_prop_count(new_council_prop_count,
                                               self.channel_set, self.logger)

        self.assertEqual(self.counter_channel.info_count, 2)
        self.assertIsInstance(self.counter_channel.latest_alert,
                              NewCouncilProposalAlert)
        self.assertEqual(self.blockchain.council_prop_count,
                         new_council_prop_count)

    def test_set_validator_set_size_no_alerts_first_time_round(self) -> None:
        self.blockchain.set_validator_set_size(self.dummy_validator_set_size,
                                               self.channel_set, self.logger)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.validator_set_size,
                         self.dummy_validator_set_size)

    def test_set_validator_set_size_no_alerts_if_same_size(self) -> None:
        self.blockchain.set_validator_set_size(self.dummy_validator_set_size,
                                               self.channel_set, self.logger)
        self.blockchain.set_validator_set_size(self.dummy_validator_set_size,
                                               self.channel_set, self.logger)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.validator_set_size,
                         self.dummy_validator_set_size)

    def test_set_validator_set_size_info_alert_if_size_decreased(self) -> None:
        self.blockchain.set_validator_set_size(self.dummy_validator_set_size,
                                               self.channel_set, self.logger)
        new_validator_set_size = self.dummy_validator_set_size - 2
        self.blockchain.set_validator_set_size(new_validator_set_size,
                                               self.channel_set, self.logger)

        self.assertEqual(self.counter_channel.info_count, 1)
        self.assertIsInstance(self.counter_channel.latest_alert,
                              ValidatorSetSizeDecreasedAlert)
        self.assertEqual(self.blockchain.validator_set_size,
                         new_validator_set_size)

    def test_set_validator_set_size_info_alert_if_size_increased(self) -> None:
        self.blockchain.set_validator_set_size(self.dummy_validator_set_size,
                                               self.channel_set, self.logger)
        new_validator_set_size = self.dummy_validator_set_size + 2
        self.blockchain.set_validator_set_size(new_validator_set_size,
                                               self.channel_set, self.logger)

        self.assertEqual(self.counter_channel.info_count, 1)
        self.assertIsInstance(self.counter_channel.latest_alert,
                              ValidatorSetSizeIncreasedAlert)
        self.assertEqual(self.blockchain.validator_set_size,
                         new_validator_set_size)
Example #9
0
class TestBlockchainMonitorWithoutRedis(unittest.TestCase):
    def setUp(self) -> None:
        self.logger = logging.getLogger('dummy')
        self.monitor_name = 'testblockchainmonitor'
        self.counter_channel = CounterChannel(self.logger)
        self.channel_set = ChannelSet([self.counter_channel], TestInternalConf)
        self.redis = None
        self.data_sources = []
        self.polkadot_api_endpoint = 'api_endpoint'

        self.dummy_ws_url_1 = "11.22.33.11:9944"
        self.dummy_ws_url_2 = "11.22.33.12:9944"
        self.dummy_ws_url_3 = "11.22.33.13:9944"
        self.dummy_ws_url_4 = "11.22.33.14:9944"
        self.dummy_node_name_1 = "testnode1"
        self.dummy_node_name_2 = "testnode2"
        self.dummy_node_name_3 = "testnode3"
        self.dummy_node_name_4 = "testnode4"
        self.dummy_chain_name = "testchain"
        self.validator_stash_account_address = "DFJGDF8G898fdghb98dg9wetg9we00w"
        self.dummy_full_node_1 = Node(
            name=self.dummy_node_name_1,
            ws_url=self.dummy_ws_url_1,
            node_type=NodeType.NON_VALIDATOR_FULL_NODE,
            stash_account_address='',
            chain=self.dummy_chain_name,
            redis=None,
            is_archive_node=True,
            internal_conf=TestInternalConf)
        self.dummy_full_node_2 = Node(
            name=self.dummy_node_name_2,
            ws_url=self.dummy_ws_url_2,
            node_type=NodeType.NON_VALIDATOR_FULL_NODE,
            stash_account_address='',
            chain=self.dummy_chain_name,
            redis=None,
            is_archive_node=True,
            internal_conf=TestInternalConf)
        self.dummy_full_node_3 = Node(
            name=self.dummy_node_name_3,
            ws_url=self.dummy_ws_url_3,
            node_type=NodeType.NON_VALIDATOR_FULL_NODE,
            stash_account_address='',
            chain=self.dummy_chain_name,
            redis=None,
            is_archive_node=True,
            internal_conf=TestInternalConf)
        self.dummy_validator_node_1 = Node(
            name=self.dummy_node_name_4,
            ws_url=self.dummy_ws_url_4,
            node_type=NodeType.VALIDATOR_FULL_NODE,
            stash_account_address=self.validator_stash_account_address,
            chain=self.dummy_chain_name,
            redis=None,
            is_archive_node=False,
            internal_conf=TestInternalConf)

        self.dummy_blockchain = Blockchain(self.dummy_chain_name, None)
        self.monitor = BlockchainMonitor(self.monitor_name,
                                         self.dummy_blockchain,
                                         self.channel_set, self.logger,
                                         self.redis, self.data_sources,
                                         self.polkadot_api_endpoint,
                                         TestInternalConf)
        self.dummy_referendum_count = 10
        self.dummy_public_prop_count = 10
        self.dummy_council_prop_count = 10
        self.dummy_validator_set_size = 120

    @patch(PING_NODE_FUNCTION, return_value=None)
    @patch(GET_WEB_SOCKETS_FUNCTION)
    def test_data_source_chooses_an_online_full_node_connected_to_the_API(
            self, mock_get_web_sockets, _) -> None:
        self.dummy_full_node_1.set_as_down(self.channel_set, self.logger)
        self.dummy_validator_node_1.set_as_down(self.channel_set, self.logger)
        self.monitor.data_sources = [
            self.dummy_full_node_1, self.dummy_validator_node_1,
            self.dummy_full_node_2, self.dummy_full_node_3
        ]
        mock_get_web_sockets.return_value = [
            self.dummy_ws_url_1, self.dummy_ws_url_2
        ]
        node = self.monitor.data_source

        self.assertEqual(node.name, self.dummy_node_name_2)

    @patch(PING_NODE_FUNCTION, return_value=None)
    @patch(GET_WEB_SOCKETS_FUNCTION)
    def test_data_source_chooses_an_online_validator_node_connected_to_the_API(
            self, mock_get_web_sockets, _) -> None:
        self.dummy_full_node_1.set_as_down(self.channel_set, self.logger)
        self.dummy_full_node_2.set_as_down(self.channel_set, self.logger)
        self.monitor.data_sources = [
            self.dummy_full_node_1, self.dummy_validator_node_1,
            self.dummy_full_node_2, self.dummy_full_node_3
        ]
        mock_get_web_sockets.return_value = [
            self.dummy_ws_url_1, self.dummy_ws_url_4
        ]
        node = self.monitor.data_source

        self.assertEqual(node.name, self.dummy_validator_node_1.name)

    @patch(GET_WEB_SOCKETS_FUNCTION)
    def test_data_source_raises_exception_if_no_node_is_eligible_for_choosing(
            self, mock_get_web_sockets) -> None:
        self.dummy_full_node_1.set_as_down(self.channel_set, self.logger)
        self.dummy_full_node_3.set_as_down(self.channel_set, self.logger)
        self.monitor.data_sources = [
            self.dummy_full_node_1, self.dummy_full_node_2,
            self.dummy_full_node_3, self.dummy_validator_node_1
        ]
        mock_get_web_sockets.return_value = [self.dummy_ws_url_1]

        try:
            _ = self.monitor.data_source
            self.fail('Expected NoLiveNodeConnectedWithAnApiServerException'
                      ' exception to be thrown.')
        except NoLiveNodeConnectedWithAnApiServerException:
            pass

    def test_status_returns_as_expected(self) -> None:
        self.dummy_blockchain.set_referendum_count(self.dummy_referendum_count,
                                                   self.channel_set,
                                                   self.logger)
        self.dummy_blockchain.set_validator_set_size(
            self.dummy_validator_set_size, self.channel_set, self.logger)
        self.dummy_blockchain.set_public_prop_count(
            self.dummy_public_prop_count, self.channel_set, self.logger)
        self.dummy_blockchain.set_council_prop_count(
            self.dummy_council_prop_count, self.channel_set, self.logger)

        expected_output = "referendum_count={}, public_prop_count={}, " \
                          "council_prop_count={}, validator_set_size ={}" \
            .format(self.dummy_referendum_count, self.dummy_public_prop_count,
                    self.dummy_council_prop_count,
                    self.dummy_validator_set_size)
        self.assertEqual(expected_output, self.monitor.status())

    def test_check_for_new_referendums_calls_ref_setter_once_if_ref_count_None(
            self) -> None:
        self.dummy_blockchain.set_referendum_count = MagicMock(
            side_effect=self.dummy_blockchain.set_referendum_count)
        self.monitor._check_for_new_referendums(self.dummy_referendum_count)

        self.assertEqual(self.dummy_blockchain.set_referendum_count.call_count,
                         1)

    @patch(GET_REFERENDUM_INFO_OF_FUNCTION, return_value=None)
    def test_check_for_new_referendums_calls_ref_setter_5_times_if_5_new_refs(
            self, _) -> None:
        with mock.patch(DATA_SOURCE_PATH, new_callable=PropertyMock) \
                as mock_data_source:
            mock_data_source.return_value = self.dummy_full_node_1

            self.dummy_blockchain.set_referendum_count(
                self.dummy_referendum_count, self.channel_set, self.logger)
            new_referendum_count = self.dummy_referendum_count + 5

            self.dummy_blockchain.set_referendum_count = MagicMock(
                side_effect=self.dummy_blockchain.set_referendum_count)
            self.monitor._check_for_new_referendums(new_referendum_count)

            self.assertEqual(
                self.dummy_blockchain.set_referendum_count.call_count, 5)

    def test_check_for_new_referendums_calls_ref_setter_0_times_if_same_count(
            self) -> None:
        self.dummy_blockchain.set_referendum_count(self.dummy_referendum_count,
                                                   self.channel_set,
                                                   self.logger)
        new_referendum_count = self.dummy_referendum_count

        self.dummy_blockchain.set_referendum_count = MagicMock(
            side_effect=self.dummy_blockchain.set_referendum_count)
        self.monitor._check_for_new_referendums(new_referendum_count)

        self.assertEqual(self.dummy_blockchain.set_referendum_count.call_count,
                         0)

    @patch(GET_REFERENDUM_COUNT_FUNCTION)
    @patch(GET_COUNCIL_PROPOSAL_COUNT_FUNCTION)
    @patch(GET_PUBLIC_PROPOSAL_COUNT_FUNCTION)
    @patch(GET_SESSION_VALIDATORS_FUNCTION)
    def test_monitor_sets_blockchain_state_to_retrieved_data(
            self, mock_session_val, mock_public_prop, mock_council_prop,
            mock_ref_count) -> None:
        with mock.patch(DATA_SOURCE_PATH, new_callable=PropertyMock) \
                as mock_data_source:
            mock_data_source.return_value = self.dummy_full_node_1
            mock_session_val.return_value = ['7DG7fdgfd', 'dgtdFG884']
            mock_public_prop.return_value = self.dummy_public_prop_count
            mock_council_prop.return_value = self.dummy_council_prop_count
            mock_ref_count.return_value = self.dummy_referendum_count
            self.monitor.last_data_source_used = self.dummy_full_node_1

            self.monitor.monitor()
            self.assertEqual(self.dummy_blockchain.referendum_count,
                             self.dummy_referendum_count)
            self.assertEqual(self.dummy_blockchain.public_prop_count,
                             self.dummy_public_prop_count)
            self.assertEqual(self.dummy_blockchain.council_prop_count,
                             self.dummy_council_prop_count)
            self.assertEqual(self.dummy_blockchain.validator_set_size, 2)

    @patch(GET_REFERENDUM_COUNT_FUNCTION, return_value=None)
    @patch(GET_COUNCIL_PROPOSAL_COUNT_FUNCTION, return_value=None)
    @patch(GET_PUBLIC_PROPOSAL_COUNT_FUNCTION, return_value=None)
    @patch(GET_SESSION_VALIDATORS_FUNCTION, return_value=[])
    def test_monitor_sets_API_as_up_if_entire_data_obtained_successfully(
            self, _1, _2, _3, _4) -> None:
        with mock.patch(DATA_SOURCE_PATH, new_callable=PropertyMock) \
                as mock_data_source:
            mock_data_source.return_value = self.dummy_full_node_1
            self.monitor.last_data_source_used = self.dummy_full_node_1

            self.monitor.monitor()
            self.assertFalse(self.monitor.data_wrapper.is_api_down)

    @patch(GET_REFERENDUM_COUNT_FUNCTION, return_value=None)
    @patch(GET_COUNCIL_PROPOSAL_COUNT_FUNCTION, return_value=None)
    @patch(GET_PUBLIC_PROPOSAL_COUNT_FUNCTION, return_value=None)
    @patch(GET_SESSION_VALIDATORS_FUNCTION, return_value=[])
    def test_monitor_connects_data_source_with_api_if_entire_data_obtained_successfully(
            self, _1, _2, _3, _4) -> None:
        with mock.patch(DATA_SOURCE_PATH, new_callable=PropertyMock) \
                as mock_data_source:
            mock_data_source.return_value = self.dummy_full_node_1
            self.monitor.last_data_source_used = self.dummy_full_node_1
            self.monitor.last_data_source_used.disconnect_from_api(
                self.channel_set, self.logger)
            self.assertFalse(
                self.monitor.last_data_source_used.is_connected_to_api_server)
            self.monitor.monitor()
            self.assertTrue(
                self.monitor.last_data_source_used.is_connected_to_api_server)
Example #10
0
class TestBlockchainWithoutRedis(unittest.TestCase):
    def setUp(self) -> None:
        self.blockchain_name = 'testblockchain'
        self.logger = logging.getLogger('dummy')

        self.blockchain = Blockchain(name=self.blockchain_name, redis=None)

        self.counter_channel = CounterChannel(self.logger)
        self.channel_set = ChannelSet([self.counter_channel], TestInternalConf)

        self.dummy_referendum_count, self.dummy_public_prop_count, \
        self.dummy_council_prop_count = 10, 10, 10
        self.dummy_validator_set_size = 120
        self.dummy_referendum_info_ongoing = {
            'Ongoing': {
                'proposalHash': '0x345jtg8ergfg8df89h9we9t9sd9g9gsd9g9sdfg',
                'end': 124143848,
                'threshold': 'Supermajorityapproval',
                'delay': 11549,
                'tally': {
                    'ayes': '4544545 KSM',
                    'nayes': '3454 KSM',
                    'turnout': '4545454454 KSM'
                }
            }
        }
        self.dummy_referendum_info_finished = {
            'Finished': {
                'approved': False,
                'end': 124143848
            }
        }

    def test_str_returns_blockchain_name(self) -> None:
        self.assertEqual(self.blockchain_name, str(self.blockchain))

    def test_referendum_count_None_by_default(self) -> None:
        self.assertIsNone(self.blockchain.referendum_count)

    def test_public_prop_count_None_by_default(self) -> None:
        self.assertIsNone(self.blockchain.public_prop_count)

    def test_council_prop_count_None_by_default(self) -> None:
        self.assertIsNone(self.blockchain.council_prop_count)

    def test_validator_set_size_None_by_default(self) -> None:
        self.assertIsNone(self.blockchain.validator_set_size)

    def test_status_returns_as_expected(self) -> None:
        self.blockchain.set_validator_set_size(self.dummy_validator_set_size,
                                               self.channel_set, self.logger)
        self.blockchain.set_public_prop_count(self.dummy_public_prop_count,
                                              self.channel_set, self.logger)
        self.blockchain.set_council_prop_count(self.dummy_council_prop_count,
                                               self.channel_set, self.logger)
        self.blockchain.set_referendum_count(self.dummy_referendum_count,
                                             self.channel_set, self.logger)

        self.assertEqual(
            self.blockchain.status(),
            "referendum_count={}, public_prop_count={}, "
            "council_prop_count={}, validator_set_size ={}".format(
                self.dummy_referendum_count, self.dummy_public_prop_count,
                self.dummy_council_prop_count, self.dummy_validator_set_size))

    def test_set_referendum_count_raises_no_alerts_first_time_round(
            self) -> None:
        self.blockchain.set_referendum_count(self.dummy_referendum_count,
                                             self.channel_set, self.logger)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.referendum_count,
                         self.dummy_referendum_count)

    def test_set_referendum_count_raises_no_alerts_if_same_referendum_count(
            self) -> None:
        self.blockchain.set_referendum_count(self.dummy_referendum_count,
                                             self.channel_set, self.logger)
        self.blockchain.set_referendum_count(self.dummy_referendum_count,
                                             self.channel_set, self.logger)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.referendum_count,
                         self.dummy_referendum_count)

    def test_set_referendum_count_raises_no_alerts_if_referendum_data_cleared(
            self) -> None:
        self.blockchain.set_referendum_count(self.dummy_referendum_count,
                                             self.channel_set, self.logger)
        new_referendum_count = self.dummy_referendum_count + 1
        self.blockchain.set_referendum_count(new_referendum_count,
                                             self.channel_set, self.logger,
                                             None)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.referendum_count,
                         new_referendum_count)

    def test_set_referendum_count_raises_no_alerts_if_referendum_finished_not_cleared(
            self) -> None:
        self.blockchain.set_referendum_count(self.dummy_referendum_count,
                                             self.channel_set, self.logger)
        new_referendum_count = self.dummy_referendum_count + 1
        self.blockchain.set_referendum_count(
            new_referendum_count, self.channel_set, self.logger,
            self.dummy_referendum_info_finished)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.referendum_count,
                         new_referendum_count)

    def test_set_referendum_count_info_alert_if_new_referendum_ongoing(
            self) -> None:
        self.blockchain.set_referendum_count(self.dummy_referendum_count,
                                             self.channel_set, self.logger)
        new_referendum_count = self.dummy_referendum_count + 1
        self.blockchain.set_referendum_count(
            new_referendum_count, self.channel_set, self.logger,
            self.dummy_referendum_info_ongoing)

        self.assertEqual(self.counter_channel.info_count, 1)
        self.assertIsInstance(self.counter_channel.latest_alert,
                              NewReferendumAlert)
        self.assertEqual(self.blockchain.referendum_count,
                         new_referendum_count)

    def test_set_public_prop_count_raises_no_alerts_first_time_round(
            self) -> None:
        self.blockchain.set_public_prop_count(self.dummy_public_prop_count,
                                              self.channel_set, self.logger)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.public_prop_count,
                         self.dummy_public_prop_count)

    def test_set_public_prop_count_raises_no_alerts_if_same_count(
            self) -> None:
        self.blockchain.set_public_prop_count(self.dummy_public_prop_count,
                                              self.channel_set, self.logger)
        self.blockchain.set_public_prop_count(self.dummy_public_prop_count,
                                              self.channel_set, self.logger)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.public_prop_count,
                         self.dummy_public_prop_count)

    def test_set_public_prop_count_1_info_alert_if_increase_by_1(self) -> None:
        self.blockchain.set_public_prop_count(self.dummy_public_prop_count,
                                              self.channel_set, self.logger)
        new_public_prop_count = self.dummy_public_prop_count + 1
        self.blockchain.set_public_prop_count(new_public_prop_count,
                                              self.channel_set, self.logger)

        self.assertEqual(self.counter_channel.info_count, 1)
        self.assertIsInstance(self.counter_channel.latest_alert,
                              NewPublicProposalAlert)
        self.assertEqual(self.blockchain.public_prop_count,
                         new_public_prop_count)

    def test_set_public_prop_count_2_info_alerts_if_increase_by_2(
            self) -> None:
        self.blockchain.set_public_prop_count(self.dummy_public_prop_count,
                                              self.channel_set, self.logger)
        new_public_prop_count = self.dummy_public_prop_count + 2
        self.blockchain.set_public_prop_count(new_public_prop_count,
                                              self.channel_set, self.logger)

        self.assertEqual(self.counter_channel.info_count, 2)
        self.assertIsInstance(self.counter_channel.latest_alert,
                              NewPublicProposalAlert)
        self.assertEqual(self.blockchain.public_prop_count,
                         new_public_prop_count)

    def test_set_council_prop_count_raises_no_alerts_first_time_round(
            self) -> None:
        self.blockchain.set_council_prop_count(self.dummy_council_prop_count,
                                               self.channel_set, self.logger)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.council_prop_count,
                         self.dummy_council_prop_count)

    def test_set_council_prop_count_raises_no_alerts_if_same_count(
            self) -> None:
        self.blockchain.set_council_prop_count(self.dummy_council_prop_count,
                                               self.channel_set, self.logger)
        self.blockchain.set_public_prop_count(self.dummy_council_prop_count,
                                              self.channel_set, self.logger)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.council_prop_count,
                         self.dummy_council_prop_count)

    def test_set_council_prop_count_info_alert_if_increase_by_1(self) -> None:
        self.blockchain.set_council_prop_count(self.dummy_council_prop_count,
                                               self.channel_set, self.logger)
        new_council_prop_count = self.dummy_council_prop_count + 1
        self.blockchain.set_council_prop_count(new_council_prop_count,
                                               self.channel_set, self.logger)

        self.assertEqual(self.counter_channel.info_count, 1)
        self.assertIsInstance(self.counter_channel.latest_alert,
                              NewCouncilProposalAlert)
        self.assertEqual(self.blockchain.council_prop_count,
                         new_council_prop_count)

    def test_set_council_prop_count_info_alert_if_increase_by_2(self) -> None:
        self.blockchain.set_council_prop_count(self.dummy_council_prop_count,
                                               self.channel_set, self.logger)
        new_council_prop_count = self.dummy_council_prop_count + 2
        self.blockchain.set_council_prop_count(new_council_prop_count,
                                               self.channel_set, self.logger)

        self.assertEqual(self.counter_channel.info_count, 2)
        self.assertIsInstance(self.counter_channel.latest_alert,
                              NewCouncilProposalAlert)
        self.assertEqual(self.blockchain.council_prop_count,
                         new_council_prop_count)

    def test_set_validator_set_size_no_alerts_first_time_round(self) -> None:
        self.blockchain.set_validator_set_size(self.dummy_validator_set_size,
                                               self.channel_set, self.logger)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.validator_set_size,
                         self.dummy_validator_set_size)

    def test_set_validator_set_size_no_alerts_if_same_size(self) -> None:
        self.blockchain.set_validator_set_size(self.dummy_validator_set_size,
                                               self.channel_set, self.logger)
        self.blockchain.set_validator_set_size(self.dummy_validator_set_size,
                                               self.channel_set, self.logger)

        self.assertTrue(self.counter_channel.no_alerts())
        self.assertEqual(self.blockchain.validator_set_size,
                         self.dummy_validator_set_size)

    def test_set_validator_set_size_info_alert_if_size_decreased(self) -> None:
        self.blockchain.set_validator_set_size(self.dummy_validator_set_size,
                                               self.channel_set, self.logger)
        new_validator_set_size = self.dummy_validator_set_size - 2
        self.blockchain.set_validator_set_size(new_validator_set_size,
                                               self.channel_set, self.logger)

        self.assertEqual(self.counter_channel.info_count, 1)
        self.assertIsInstance(self.counter_channel.latest_alert,
                              ValidatorSetSizeDecreasedAlert)
        self.assertEqual(self.blockchain.validator_set_size,
                         new_validator_set_size)

    def test_set_validator_set_size_info_alert_if_size_increased(self) -> None:
        self.blockchain.set_validator_set_size(self.dummy_validator_set_size,
                                               self.channel_set, self.logger)
        new_validator_set_size = self.dummy_validator_set_size + 2
        self.blockchain.set_validator_set_size(new_validator_set_size,
                                               self.channel_set, self.logger)

        self.assertEqual(self.counter_channel.info_count, 1)
        self.assertIsInstance(self.counter_channel.latest_alert,
                              ValidatorSetSizeIncreasedAlert)
        self.assertEqual(self.blockchain.validator_set_size,
                         new_validator_set_size)