def test_process_missing_message_incorrect_inst_id( message_req_service: MessageReqService, external_bus, data): frm = "frm" missing_msg = MissingMessage(msg_type=PREPREPARE, key=data.last_ordered_3pc, inst_id=data.inst_id + 1, dst=[frm], stash_data=None) message_req_service.process_missing_message(missing_msg) assert len(external_bus.sent_messages) == 0
def test_process_message_req_preprepare_without_preprepare(message_req_service: MessageReqService, external_bus, data, pp): key = (pp.viewNo, pp.ppSeqNo) data.sent_preprepares.pop(key) message_req = MessageReq(**{ f.MSG_TYPE.nm: PREPREPARE, f.PARAMS.nm: {f.INST_ID.nm: data.inst_id, f.VIEW_NO.nm: key[0], f.PP_SEQ_NO.nm: key[1]}, }) frm = "frm" message_req_service.process_message_req(message_req, frm) assert len(external_bus.sent_messages) == 0
def test_process_missing_message_raise_ex( message_req_service: MessageReqService, external_bus, data): frm = "frm" msg_type = PREPREPARE missing_msg = MissingMessage(msg_type=msg_type, key=data.last_ordered_3pc, inst_id=data.inst_id + 1, dst=[frm], stash_data=None) message_req_service.handlers[ msg_type].prepare_msg_to_request = lambda msg: raise_ex() message_req_service.process_missing_message(missing_msg) assert len(external_bus.sent_messages) == 0
def test_process_message_req_incorrect_inst_id( message_req_service: MessageReqService, external_bus, data): key = (data.view_no, 1) message_req = MessageReq( **{ f.MSG_TYPE.nm: PREPREPARE, f.PARAMS.nm: { f.INST_ID.nm: data.inst_id + 1, f.VIEW_NO.nm: key[0], f.PP_SEQ_NO.nm: key[1] }, }) message_req_service.process_message_req(message_req, "frm") assert len(external_bus.sent_messages) == 0
def test_process_message_req_with_incorrect_type( message_req_service: MessageReqService, external_bus, data, pp): msg_type = LEDGER_STATUS key = (data.view_no, 1) message_req = MessageReq( **{ f.MSG_TYPE.nm: msg_type, f.PARAMS.nm: { f.INST_ID.nm: data.inst_id, f.VIEW_NO.nm: key[0], f.PP_SEQ_NO.nm: key[1] }, }) message_req_service.process_message_req(message_req, "frm") assert len(external_bus.sent_messages) == 0
def test_process_message_req_commit(message_req_service: MessageReqService, external_bus, data, commit): key = (commit.viewNo, commit.ppSeqNo) message_req = MessageReq(**{ f.MSG_TYPE.nm: COMMIT, f.PARAMS.nm: {f.INST_ID.nm: data.inst_id, f.VIEW_NO.nm: key[0], f.PP_SEQ_NO.nm: key[1]}, }) frm = "frm" message_req_service.process_message_req(message_req, frm) assert len(external_bus.sent_messages) == 1 assert external_bus.sent_messages[0] == (MessageRep(message_req.msg_type, message_req.params, data.commits[key].msg), [frm])
def test_process_message_rep_new_view_from_primary(message_req_service: MessageReqService, external_bus, data, new_view_message: NewView): primary = data.primary_name inst_id = data.inst_id message_req_service.handlers[NEW_VIEW].requested_messages[data.view_no] = None message_rep_from_primary = MessageRep(**{ f.MSG_TYPE.nm: NEW_VIEW, f.PARAMS.nm: {f.INST_ID.nm: inst_id, f.VIEW_NO.nm: data.view_no}, f.MSG.nm: dict(new_view_message.items()) }) network_handler = Mock() external_bus.subscribe(NewView, network_handler) message_req_service.process_message_rep(message_rep_from_primary, primary) network_handler.assert_called_once_with(new_view_message, primary)
def test_process_message_rep_preprepare(message_req_service: MessageReqService, external_bus, data, pp): key = (pp.viewNo, pp.ppSeqNo) message_req_service.handlers[PREPREPARE].requested_messages[key] = None message_rep = MessageRep(**{ f.MSG_TYPE.nm: PREPREPARE, f.PARAMS.nm: {f.INST_ID.nm: data.inst_id, f.VIEW_NO.nm: key[0], f.PP_SEQ_NO.nm: key[1]}, f.MSG.nm: dict(pp.items()) }) frm = "frm" network_handler = Mock() external_bus.subscribe(PrePrepare, network_handler) message_req_service.process_message_rep(message_rep, frm) network_handler.assert_called_once_with(pp, frm)
def test_process_message_req_preprepare(message_req_service: MessageReqService, external_bus, data, pp): key = (pp.viewNo, pp.ppSeqNo) message_req = MessageReq(**{ f.MSG_TYPE.nm: PREPREPARE, f.PARAMS.nm: {f.INST_ID.nm: data.inst_id, f.VIEW_NO.nm: key[0], f.PP_SEQ_NO.nm: key[1]}, }) frm = "frm" message_req_service.process_message_req(message_req, frm) assert len(external_bus.sent_messages) == 1 assert external_bus.sent_messages[0] == (MessageRep(message_req.msg_type, message_req.params, data.sent_preprepares[key]), [frm])
def test_process_message_rep_commit(message_req_service: MessageReqService, external_bus, data, commit): key = (commit.viewNo, commit.ppSeqNo) message_req_service.handlers[COMMIT].requested_messages[key] = None message_rep = MessageRep(**{ f.MSG_TYPE.nm: COMMIT, f.PARAMS.nm: {f.INST_ID.nm: data.inst_id, f.VIEW_NO.nm: key[0], f.PP_SEQ_NO.nm: key[1]}, f.MSG.nm: dict(commit.items()) }) frm = "frm" network_handler = Mock() external_bus.subscribe(Commit, network_handler) message_req_service.process_message_rep(message_rep, frm) network_handler.assert_called_once_with(commit, frm)
def test_process_missing_message_commit(message_req_service: MessageReqService, external_bus, data): frm = "frm" view_no = data.view_no pp_seq_no = data.last_ordered_3pc[1] + 1 missing_msg = MissingMessage(msg_type=COMMIT, key=(view_no, pp_seq_no), inst_id=data.inst_id, dst=[frm], stash_data=None) message_req_service.process_missing_message(missing_msg) assert len(external_bus.sent_messages) == 1 assert external_bus.sent_messages[0] == (MessageReq(COMMIT, {f.INST_ID.nm: data.inst_id, f.VIEW_NO.nm: view_no, f.PP_SEQ_NO.nm: pp_seq_no}), [frm])
def test_process_message_req_commit_without_commit(message_req_service: MessageReqService, external_bus, data, commit): key = (commit.viewNo, commit.ppSeqNo) other_node_name = "other_node" data.commits.clear() data.commits.addVote(commit, other_node_name) assert not data.commits.hasCommitFrom(commit, data.name) assert data.commits.hasCommitFrom(commit, other_node_name) message_req = MessageReq(**{ f.MSG_TYPE.nm: COMMIT, f.PARAMS.nm: {f.INST_ID.nm: data.inst_id, f.VIEW_NO.nm: key[0], f.PP_SEQ_NO.nm: key[1]}, }) frm = "frm" message_req_service.process_message_req(message_req, frm) assert len(external_bus.sent_messages) == 0
def __init__(self, name: str, validators: List[str], primary_name: str, timer: TimerService, bus: InternalBus, network: ExternalBus, write_manager: WriteRequestManager, bls_bft_replica: BlsBftReplica = None): # ToDo: Maybe ConsensusSharedData should be initiated before and passed already prepared? self._internal_bus = bus self._data = ConsensusSharedData(name, validators, 0) self._data.primary_name = generateName(primary_name, self._data.inst_id) self.config = getConfig() self.stasher = StashingRouter(self.config.REPLICA_STASH_LIMIT, buses=[bus, network]) self._write_manager = write_manager self._primaries_selector = RoundRobinNodeRegPrimariesSelector( self._write_manager.node_reg_handler) self._orderer = OrderingService( data=self._data, timer=timer, bus=bus, network=network, write_manager=self._write_manager, bls_bft_replica=bls_bft_replica, freshness_checker=FreshnessChecker( freshness_timeout=self.config.STATE_FRESHNESS_UPDATE_INTERVAL), primaries_selector=self._primaries_selector, stasher=self.stasher) self._checkpointer = CheckpointService(self._data, bus, network, self.stasher, write_manager.database_manager) self._view_changer = ViewChangeService(self._data, timer, bus, network, self.stasher, self._primaries_selector) self._message_requestor = MessageReqService(self._data, bus, network) self._add_ledgers() # TODO: This is just for testing purposes only self._data.checkpoints.append( Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=0, digest='4F7BsTMVPKFshM1MwLf6y23cid6fL3xMpazVoF9krzUw')) # ToDo: it should be done in Zero-view stage. write_manager.on_catchup_finished() self._data.primaries = self._view_changer._primaries_selector.select_primaries( self._data.view_no) # ToDo: ugly way to understand node_reg changing self._previous_node_reg = self._write_manager.node_reg_handler.committed_node_reg bus.subscribe(Ordered, self.emulate_ordered_processing)
def test_process_message_req_handler_raise_ex( message_req_service: MessageReqService, external_bus, data): msg_type = PREPREPARE key = (data.view_no, 1) message_req = MessageReq( **{ f.MSG_TYPE.nm: msg_type, f.PARAMS.nm: { f.INST_ID.nm: data.inst_id, f.VIEW_NO.nm: key[0], f.PP_SEQ_NO.nm: key[1] }, }) message_req_service.handlers[ msg_type].process_message_req = lambda msg: raise_ex() message_req_service.process_message_req(message_req, "frm") assert len(external_bus.sent_messages) == 0
def test_process_message_rep_with_incorrect_type( message_req_service: MessageReqService, external_bus, data, pp): key = (pp.viewNo, pp.ppSeqNo) message_rep = MessageRep( **{ f.MSG_TYPE.nm: LEDGER_STATUS, f.PARAMS.nm: { f.INST_ID.nm: data.inst_id, f.VIEW_NO.nm: key[0], f.PP_SEQ_NO.nm: key[1] }, f.MSG.nm: dict(pp.items()) }) frm = "frm" network_handler = Mock() external_bus.subscribe(PrePrepare, network_handler) external_bus.subscribe(Prepare, network_handler) external_bus.subscribe(Commit, network_handler) message_req_service.process_message_rep(message_rep, frm) network_handler.assert_not_called()
def test_process_message_rep_view_change_from_one(message_req_service: MessageReqService, external_bus, data, view_change_message: ViewChange): frm = "frm" inst_id = data.inst_id digest = view_change_digest(view_change_message) key = (frm, digest) message_req_service.handlers[VIEW_CHANGE].requested_messages[key] = None message_rep_from_primary = MessageRep(**{ f.MSG_TYPE.nm: VIEW_CHANGE, f.PARAMS.nm: {f.INST_ID.nm: inst_id, f.DIGEST.nm: digest, f.NAME.nm: frm}, f.MSG.nm: dict(view_change_message.items()) }) frm = "frm" network_handler = Mock() external_bus.subscribe(ViewChange, network_handler) network_handler.assert_not_called() message_req_service.process_message_rep(message_rep_from_primary, frm) network_handler.assert_called_once_with(view_change_message, frm)
def test_process_message_req_prepare_without_prepare( message_req_service: MessageReqService, external_bus, data, prepare): key = (prepare.viewNo, prepare.ppSeqNo) other_node_name = "other_node" data.prepares.clear() data.prepares.addVote(prepare, other_node_name) assert not data.prepares.hasPrepareFrom(prepare, data.name) assert data.prepares.hasPrepareFrom(prepare, other_node_name) message_req = MessageReq( **{ f.MSG_TYPE.nm: PREPARE, f.PARAMS.nm: { f.INST_ID.nm: data.inst_id, f.VIEW_NO.nm: key[0], f.PP_SEQ_NO.nm: key[1] }, }) frm = "frm" message_req_service.process_message_req(message_req, frm) assert len(external_bus.sent_messages) == 0
def test_process_message_rep_invalid_preprepare( message_req_service: MessageReqService, external_bus, data, pp): key = (pp.viewNo, pp.ppSeqNo) msg_type = PREPREPARE message_req_service.handlers[PREPREPARE].requested_messages[key] = None message_rep = MessageRep( **{ f.MSG_TYPE.nm: msg_type, f.PARAMS.nm: { f.INST_ID.nm: data.inst_id, f.VIEW_NO.nm: key[0], f.PP_SEQ_NO.nm: key[1] }, f.MSG.nm: dict(pp.items()) }) frm = "frm" network_handler = Mock() external_bus.subscribe(PrePrepare, network_handler) message_req_service.handlers[ msg_type].extract_message = lambda msg, frm: raise_ex() message_req_service.process_message_rep(message_rep, frm) network_handler.assert_not_called()
def _init_message_req_service(self) -> MessageReqService: return MessageReqService(data=self._consensus_data, bus=self.internal_bus, network=self._external_bus, metrics=self.metrics)
def message_req_service(data, internal_bus, external_bus): req_service = MessageReqService(data=data, bus=internal_bus, network=external_bus) return req_service
def __init__(self, name: str, validators: List[str], primary_name: str, timer: TimerService, bus: InternalBus, network: ExternalBus, write_manager: WriteRequestManager, bls_bft_replica: BlsBftReplica = None): # ToDo: Maybe ConsensusSharedData should be initiated before and passed already prepared? self._network = network self._data = ConsensusSharedData(name, validators, 0) self._data.primary_name = generateName(primary_name, self._data.inst_id) self._timer = timer self.config = getConfig() self.stasher = StashingRouter(self.config.REPLICA_STASH_LIMIT, buses=[bus, network]) self._write_manager = write_manager self._primaries_selector = RoundRobinNodeRegPrimariesSelector(self._write_manager.node_reg_handler) self._freshness_checker = FreshnessChecker(freshness_timeout=self.config.STATE_FRESHNESS_UPDATE_INTERVAL) for ledger_id in [POOL_LEDGER_ID, DOMAIN_LEDGER_ID, CONFIG_LEDGER_ID]: self._freshness_checker.register_ledger(ledger_id=ledger_id, initial_time=self.get_time_for_3pc_batch()) self._orderer = OrderingService(data=self._data, timer=self._timer, bus=bus, network=network, write_manager=self._write_manager, bls_bft_replica=bls_bft_replica, freshness_checker=self._freshness_checker, get_time_for_3pc_batch=self.get_time_for_3pc_batch, stasher=self.stasher) self._checkpointer = CheckpointService(self._data, bus, network, self.stasher, write_manager.database_manager) self._view_changer = ViewChangeService(self._data, self._timer, bus, network, self.stasher, self._primaries_selector) self._view_change_trigger = ViewChangeTriggerService(data=self._data, timer=self._timer, bus=bus, network=network, db_manager=write_manager.database_manager, is_master_degraded=lambda: False, stasher=self.stasher) self._primary_connection_monitor = PrimaryConnectionMonitorService(data=self._data, timer=self._timer, bus=bus, network=network) self._freshness_monitor = FreshnessMonitorService(data=self._data, timer=self._timer, bus=bus, network=network, freshness_checker=self._freshness_checker, get_time_for_3pc_batch=self.get_time_for_3pc_batch) self._message_requestor = MessageReqService(self._data, bus, network) self._add_ledgers() # TODO: This is just for testing purposes only self._data.checkpoints.append( Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=0, digest='4F7BsTMVPKFshM1MwLf6y23cid6fL3xMpazVoF9krzUw')) # ToDo: it should be done in Zero-view stage. write_manager.on_catchup_finished() # Simulate node behavior self._internal_bus = bus self._internal_bus.subscribe(NodeNeedViewChange, self.process_node_need_view_change) self._internal_bus.subscribe(Ordered, self.emulate_ordered_processing) # ToDo: ugly way to understand node_reg changing self._previous_node_reg = self._write_manager.node_reg_handler.committed_node_reg