def __init__( self, data: ConsensusSharedData, bus: InternalBus, network: ExternalBus, stasher: StashingRouter, db_manager: DatabaseManager, metrics: MetricsCollector = NullMetricsCollector(), ): self._data = data self._bus = bus self._network = network self._stasher = stasher self._subscription = Subscription() self._validator = CheckpointMsgValidator(self._data) self._db_manager = db_manager self.metrics = metrics # Received checkpoints, mapping CheckpointKey -> List(node_alias) self._received_checkpoints = defaultdict( set) # type: Dict[CheckpointService.CheckpointKey, Set[str]] self._config = getConfig() self._logger = getlogger() self._subscription.subscribe(stasher, Checkpoint, self.process_checkpoint) self._subscription.subscribe(bus, Ordered, self.process_ordered) self._subscription.subscribe(bus, BackupSetupLastOrdered, self.process_backup_setup_last_ordered) self._subscription.subscribe(bus, NewViewAccepted, self.process_new_view_accepted)
def __init__(self, data: ConsensusSharedData, timer: TimerService, bus: InternalBus, network: ExternalBus, db_manager: DatabaseManager, stasher: StashingRouter, is_master_degraded: Callable[[], bool], metrics: MetricsCollector = NullMetricsCollector()): self._data = data self._timer = timer self._bus = bus self._network = network self._stasher = stasher self._is_master_degraded = is_master_degraded self.metrics = metrics self._config = getConfig() self._instance_changes = \ InstanceChangeProvider(outdated_ic_interval=self._config.OUTDATED_INSTANCE_CHANGES_CHECK_INTERVAL, node_status_db=db_manager.get_store(NODE_STATUS_DB_LABEL), time_provider=timer.get_current_time) self._subscription = Subscription() self._subscription.subscribe(bus, VoteForViewChange, self.process_vote_for_view_change) self._subscription.subscribe(bus, NewViewAccepted, self.process_new_view_accepted) self._subscription.subscribe(stasher, InstanceChange, self.process_instance_change)
def __init__(self, data: ConsensusSharedData, bus: InternalBus, network: ExternalBus, metrics=NullMetricsCollector()): self._logger = getlogger() self._data = data self._bus = bus self._subscription = Subscription() self._subscription.subscribe(bus, MissingMessage, self.process_missing_message) self._subscription.subscribe(bus, Ordered, self.process_ordered) self._subscription.subscribe(bus, ViewChangeStarted, self.process_view_change_started) self._subscription.subscribe(bus, CheckpointStabilized, self.process_checkpoint_stabilized) self._network = network self._subscription.subscribe(network, MessageReq, self.process_message_req) self._subscription.subscribe(network, MessageRep, self.process_message_rep) self.metrics = metrics self.handlers = { PREPREPARE: PreprepareHandler(self._data), PREPARE: PrepareHandler(self._data), COMMIT: CommitHandler(self._data), VIEW_CHANGE: ViewChangeHandler(self._data) } self.three_pc_handlers = {PREPREPARE, PREPARE, COMMIT}
def __init__(self, data: ConsensusSharedData, timer: TimerService, bus: InternalBus, network: ExternalBus, stasher: StashingRouter): self._config = getConfig() self._logger = getlogger() self._data = data self._new_view_builder = NewViewBuilder(self._data) self._timer = timer self._bus = bus self._network = network self._router = stasher self._new_view = None # type: Optional[NewView] self._resend_inst_change_timer = RepeatingTimer(self._timer, self._config.NEW_VIEW_TIMEOUT, partial(self._propose_view_change, Suspicions.INSTANCE_CHANGE_TIMEOUT.code), active=False) self._router.subscribe(ViewChange, self.process_view_change_message) self._router.subscribe(ViewChangeAck, self.process_view_change_ack_message) self._router.subscribe(NewView, self.process_new_view_message) self._old_prepared = {} # type: Dict[int, BatchID] self._old_preprepared = {} # type: Dict[int, List[BatchID]] self._primaries_selector = RoundRobinPrimariesSelector() self._subscription = Subscription() self._subscription.subscribe(self._bus, NeedViewChange, self.process_need_view_change)
def __init__(self, data: ConsensusSharedData, timer: TimerService, bus: InternalBus, network: ExternalBus, stasher: StashingRouter): self._config = getConfig() self._logger = getlogger() self._data = data self._new_view_builder = NewViewBuilder(self._data) self._timer = timer self._bus = bus self._network = network self._router = stasher self._votes = ViewChangeVotesForView(self._data.quorums) self._new_view = None # type: Optional[NewView] self._router.subscribe(ViewChange, self.process_view_change_message) self._router.subscribe(ViewChangeAck, self.process_view_change_ack_message) self._router.subscribe(NewView, self.process_new_view_message) self._old_prepared = {} # type: Dict[int, BatchID] self._old_preprepared = {} # type: Dict[int, List[BatchID]] self._primaries_selector = RoundRobinPrimariesSelector() self._subscription = Subscription() self._subscription.subscribe(self._bus, NeedViewChange, self.process_need_view_change)
def __init__(self, data: ConsensusSharedData, timer: TimerService, bus: InternalBus, network: ExternalBus, metrics: MetricsCollector = NullMetricsCollector()): self._data = data self._timer = timer self._bus = bus self._network = network self.metrics = metrics self._config = getConfig() self._primary_disconnection_time = timer.get_current_time() # type: Optional[float] self._propose_view_change_timer = RepeatingTimer(timer=timer, interval=self._config.NEW_VIEW_TIMEOUT, callback=self._propose_view_change_if_needed, active=False) self._subscription = Subscription() self._subscription.subscribe(network, ExternalBus.Connected, self.process_connected) self._subscription.subscribe(network, ExternalBus.Disconnected, self.process_disconnected) self._subscription.subscribe(bus, PrimarySelected, self.process_primary_selected) self._subscription.subscribe(bus, NodeStatusUpdated, self.process_node_status_updated) if self._data.is_master: self._schedule_primary_connection_check(delay=self._config.INITIAL_PROPOSE_VIEW_CHANGE_TIMEOUT)
def __init__(self, data: ConsensusSharedData, timer: TimerService, bus: InternalBus, network: ExternalBus, stasher: StashingRouter, primaries_selector: PrimariesSelector): self._config = getConfig() self._data = data self._new_view_builder = NewViewBuilder(self._data) self._timer = timer self._bus = bus self._network = network self._router = stasher # Last successful viewNo. # In some cases view_change process can be uncompleted in time. # In that case we want to know, which viewNo was successful (last completed view_change) self.last_completed_view_no = self._data.view_no self._resend_inst_change_timer = RepeatingTimer(self._timer, self._config.NEW_VIEW_TIMEOUT, self._propose_view_change_not_complete_in_time, active=False) self._old_prepared = {} # type: Dict[int, BatchID] self._old_preprepared = {} # type: Dict[int, List[BatchID]] self._stashed_vc_msgs = {} # type: Dict[int, int] self._primaries_selector = primaries_selector self._subscription = Subscription() self._subscription.subscribe(self._router, ViewChange, self.process_view_change_message) self._subscription.subscribe(self._router, ViewChangeAck, self.process_view_change_ack_message) self._subscription.subscribe(self._router, NewView, self.process_new_view_message) self._subscription.subscribe(self._bus, NeedViewChange, self.process_need_view_change)
def __init__(self, limit: int, buses: List[Router], unstash_handler: Callable = None): super().__init__() self._limit = limit self._logger = getlogger() self._queues = {} # type: Dict[int, StashingQueue] # TODO: This call has been added to saving the old message order in the list. # This is a replica's method that moves the message to the inBox, rather than # calling the handler immediately, as the default router does. self._unstash_handler = unstash_handler self._subscriptions = Subscription() self._buses = buses
def __init__( self, data: ConsensusSharedData, bus: InternalBus, network: ExternalBus, stasher: StashingRouter, db_manager: DatabaseManager, metrics: MetricsCollector = NullMetricsCollector(), ): self._data = data self._bus = bus self._network = network self._checkpoint_state = SortedDict(lambda k: k[1]) self._stasher = stasher self._subscription = Subscription() self._validator = CheckpointMsgValidator(self._data) self._db_manager = db_manager self.metrics = metrics # Stashed checkpoints for each view. The key of the outermost # dictionary is the view_no, value being a dictionary with key as the # range of the checkpoint and its value again being a mapping between # senders and their sent checkpoint # Dict[view_no, Dict[(seqNoStart, seqNoEnd), Dict[sender, Checkpoint]]] self._stashed_recvd_checkpoints = {} self._config = getConfig() self._logger = getlogger() self._subscription.subscribe(stasher, Checkpoint, self.process_checkpoint) self._subscription.subscribe(bus, Ordered, self.process_ordered) self._subscription.subscribe(bus, BackupSetupLastOrdered, self.process_backup_setup_last_ordered) self._subscription.subscribe(bus, NewViewAccepted, self.process_new_view_accepted)
def __init__(self, node: 'plenum.server.node.Node', instId: int, config=None, isMaster: bool = False, bls_bft_replica: BlsBftReplica = None, metrics: MetricsCollector = NullMetricsCollector(), get_current_time=None, get_time_for_3pc_batch=None): """ Create a new replica. :param node: Node on which this replica is located :param instId: the id of the protocol instance the replica belongs to :param isMaster: is this a replica of the master protocol instance """ HasActionQueue.__init__(self) self.get_current_time = get_current_time or time.perf_counter self.get_time_for_3pc_batch = get_time_for_3pc_batch or node.utc_epoch # self.stats = Stats(TPCStat) self.config = config or getConfig() self.metrics = metrics self.node = node self.instId = instId self.name = self.generateName(node.name, self.instId) self.logger = getlogger(self.name) self.validator = ReplicaValidator(self) self.outBox = deque() """ This queue is used by the replica to send messages to its node. Replica puts messages that are consumed by its node """ self.inBox = deque() """ This queue is used by the replica to receive messages from its node. Node puts messages that are consumed by the replica """ self.inBoxStash = deque() """ If messages need to go back on the queue, they go here temporarily and are put back on the queue on a state change """ self._is_master = isMaster # Dictionary to keep track of the which replica was primary during each # view. Key is the view no and value is the name of the primary # replica during that view self.primaryNames = OrderedDict() # type: OrderedDict[int, str] # Flag being used for preterm exit from the loop in the method # `processStashedMsgsForNewWaterMarks`. See that method for details. self.consumedAllStashedMsgs = True self._freshness_checker = FreshnessChecker( freshness_timeout=self.config.STATE_FRESHNESS_UPDATE_INTERVAL) self._bls_bft_replica = bls_bft_replica self._state_root_serializer = state_roots_serializer # Did we log a message about getting request while absence of primary self.warned_no_primary = False self._consensus_data = ConsensusSharedData( self.name, self.node.poolManager.node_names_ordered_by_rank(), self.instId, self.isMaster) self._internal_bus = InternalBus() self._external_bus = ExternalBus(send_handler=self.send) self.stasher = self._init_replica_stasher() self._subscription = Subscription() self._bootstrap_consensus_data() self._subscribe_to_external_msgs() self._subscribe_to_internal_msgs() self._checkpointer = self._init_checkpoint_service() self._ordering_service = self._init_ordering_service() self._message_req_service = self._init_message_req_service() self._view_change_service = self._init_view_change_service() for ledger_id in self.ledger_ids: self.register_ledger(ledger_id)