def test_get_msgs_from_rxMsgs_queue(create_node_and_not_start, looper): node = create_node_and_not_start node.view_changer = ViewChanger(node) node.view_changer.view_no = 0 """pre_view_change stage""" node.view_changer.startViewChange(1) assert node.view_changer.view_no == 0 prepare = Prepare( 0, 0, 1, get_utc_epoch(), 'f99937241d4c891c08e92a3cc25966607315ca66b51827b170d492962d58a9be', 'CZecK1m7VYjSNCC7pGHj938DSW2tfbqoJp1bMJEtFqvG', '7WrAMboPTcMaQCU1raoj28vnhu2bPMMd2Lr9tEcsXeCJ') inst_change = InstanceChange(1, 25) m = node.nodeInBox.popleft() assert isinstance(m[0], ViewChangeStartMessage) node.nodestack.addRemote('someNode', genHa(), b'1DYuELN<SHbv1?NJ=][4De%^Hge887B0I!s<YGdD', 'pubkey') node.nodestack.rxMsgs.append((json.dumps(prepare._asdict()), 'pubkey')) node.nodestack.rxMsgs.append((json.dumps(inst_change._asdict()), 'pubkey')) node.msgHasAcceptableViewNo = lambda *args, **kwargs: True """While processing ViewChangeStartMessage from nodeInBox queue, should be: - move msgs from rxMsgs queue to nodeInBox queue - process all 3PC msgs (for Prepare msg it should be moved to inBox queue of master_replica) - add ViewChangeContinue msg into master_replica's inBox queue - all not 3PC msgs will be stashed in strategy queue""" looper.run(node.process_one_node_message(m)) m = node.master_replica.inBox.popleft() assert isinstance(m[0], Prepare) m = node.master_replica.inBox.popleft() assert isinstance(m, ViewChangeContinueMessage) m = node.view_changer.pre_vc_strategy.stashedNodeInBox.popleft() assert isinstance(m[0], InstanceChange)
def test_get_msgs_from_rxMsgs_queue(create_node_and_not_start, looper): node = create_node_and_not_start node.view_changer = create_view_changer(node) node.view_changer.pre_vc_strategy = VCStartMsgStrategy(view_changer, node) node.view_changer.view_no = 0 """pre_view_change stage""" node.view_changer.start_view_change(1) assert node.view_changer.view_no == 0 prepare = Prepare( 0, 0, 1, get_utc_epoch(), 'f99937241d4c891c08e92a3cc25966607315ca66b51827b170d492962d58a9be', 'CZecK1m7VYjSNCC7pGHj938DSW2tfbqoJp1bMJEtFqvG', '7WrAMboPTcMaQCU1raoj28vnhu2bPMMd2Lr9tEcsXeCJ') inst_change = InstanceChange(1, 25) m = node.nodeInBox.popleft() assert isinstance(m[0], ViewChangeStartMessage) node.nodestack.addRemote('someNode', genHa(), b'1DYuELN<SHbv1?NJ=][4De%^Hge887B0I!s<YGdD', 'pubkey') node.nodestack.rxMsgs.append((json.dumps(prepare._asdict()), 'pubkey')) node.nodestack.rxMsgs.append((json.dumps(inst_change._asdict()), 'pubkey')) node.msgHasAcceptableViewNo = lambda *args, **kwargs: True """While processing ViewChangeStartMessage from nodeInBox queue, should be: - move msgs from rxMsgs queue to nodeInBox queue - process all 3PC msgs (for Prepare msg it should be moved to inBox queue of master_replica) - add ViewChangeContinue msg into master_replica's inBox queue - all not 3PC msgs will be stashed in strategy queue""" looper.run(node.process_one_node_message(m)) m = node.master_replica.inBox.popleft() assert isinstance(m[0], Prepare) m = node.master_replica.inBox.popleft() assert isinstance(m, ViewChangeContinueMessage) m = node.view_changer.pre_vc_strategy.stashedNodeInBox.popleft() assert isinstance(m[0], InstanceChange)
def test_node_request_preprepare(looper, txnPoolNodeSet, client1, wallet1, client1Connected, teardown): """ Node requests PRE-PREPARE only once after getting PREPAREs. """ slow_node, other_nodes, primary_node, \ other_primary_nodes = split_nodes(txnPoolNodeSet) # Drop PrePrepares and Prepares slow_node.nodeIbStasher.delay(ppDelay(300, 0)) slow_node.nodeIbStasher.delay(pDelay(300, 0)) send_reqs_batches_and_get_suff_replies(looper, wallet1, client1, 10, 5) slow_node.nodeIbStasher.drop_delayeds() slow_node.nodeIbStasher.resetDelays() old_count_req = count_requested_preprepare_req(slow_node) old_count_resp = count_requested_preprepare_resp(slow_node) def chk(increase=True): # Method is called assert count_requested_preprepare_req(slow_node) > old_count_req # Requesting Preprepare assert count_requested_preprepare_resp( slow_node) - old_count_resp == (1 if increase else 0) for pp in primary_node.master_replica.sentPrePrepares.values(): for rep in [n.master_replica for n in other_primary_nodes]: prepare = Prepare(rep.instId, pp.viewNo, pp.ppSeqNo, pp.ppTime, pp.digest, pp.stateRootHash, pp.txnRootHash ) rep.send(prepare) looper.run(eventually(chk, True, retryWait=1)) old_count_resp = count_requested_preprepare_resp(slow_node) prepare = Prepare(rep.instId, pp.viewNo, pp.ppSeqNo, pp.ppTime, pp.digest, pp.stateRootHash, pp.txnRootHash ) rep.send(prepare) looper.run(eventually(chk, False, retryWait=1)) old_count_req = count_requested_preprepare_req(slow_node) old_count_resp = count_requested_preprepare_resp(slow_node)
def test_accept_all_3PC_msgs(create_node_and_not_start, looper): node = create_node_and_not_start preprepare = PrePrepare( 0, 0, 1, get_utc_epoch(), ['f99937241d4c891c08e92a3cc25966607315ca66b51827b170d492962d58a9be'], '[]', 'f99937241d4c891c08e92a3cc25966607315ca66b51827b170d492962d58a9be', DOMAIN_LEDGER_ID, 'CZecK1m7VYjSNCC7pGHj938DSW2tfbqoJp1bMJEtFqvG', '7WrAMboPTcMaQCU1raoj28vnhu2bPMMd2Lr9tEcsXeCJ', 0, True ) prepare = Prepare( 0, 0, 1, get_utc_epoch(), 'f99937241d4c891c08e92a3cc25966607315ca66b51827b170d492962d58a9be', 'CZecK1m7VYjSNCC7pGHj938DSW2tfbqoJp1bMJEtFqvG', '7WrAMboPTcMaQCU1raoj28vnhu2bPMMd2Lr9tEcsXeCJ') commit = Commit( 0, 0, 1 ) node.view_changer = node.newViewChanger() node.master_replica._consensus_data.view_no = 0 node.master_replica.primaryName = 'Alpha' """Initiate view_change procedure""" node.master_replica.internal_bus.send(NodeNeedViewChange(1)) # We don't use a view_change_strategy anymore assert len(node.nodeInBox) == 0 """ Imitate that nodestack.service was called and those of next messages are put into nodeInBox queue """ node.nodeInBox.append((preprepare, 'some_node')) node.nodeInBox.append((prepare, 'some_node')) node.nodeInBox.append((commit, 'some_node')) assert len(node.master_replica.inBox) == 0 """Imitate looper's work""" looper.run(node.serviceReplicas(None)) """ Next looper's task must be processNodeInBox and all of 3PC messages must be moved to replica's inBox queue """ looper.run(node.processNodeInBox()) """3 3PC msgs""" assert len(node.master_replica.inBox) == 3 """Check the order of msgs""" m = node.master_replica.inBox.popleft() assert isinstance(m[0], PrePrepare) m = node.master_replica.inBox.popleft() assert isinstance(m[0], Prepare) m = node.master_replica.inBox.popleft() assert isinstance(m[0], Commit)
def create_prepare(req_key, state_root, inst_id=0): view_no, pp_seq_no = req_key params = create_prepare_params(view_no, pp_seq_no, state_root, inst_id=inst_id) return Prepare(*params)
def _create_prepare_and_preprepare(inst_id, pp_sq_no, view_no, timestamp, sdk_wallet_client): time = int(timestamp) req_idr = ["random request digest"] preprepare = PrePrepare(inst_id, pp_sq_no, view_no, time, req_idr, init_discarded(), "123", 1, None, None, 0, True) prepare = Prepare(inst_id, pp_sq_no, view_no, time, "321", None, None ) return preprepare, prepare
def create_prepare_from_pre_prepare(pre_prepare): params = [ pre_prepare.instId, pre_prepare.viewNo, pre_prepare.ppSeqNo, pre_prepare.ppTime, pre_prepare.digest, pre_prepare.stateRootHash, pre_prepare.txnRootHash, pre_prepare.auditTxnRootHash ] return Prepare(*params)
def create(self, msg: Dict, **kwargs) -> Optional[Prepare]: prepare = Prepare(**msg) if prepare.instId != kwargs['inst_id'] \ or prepare.viewNo != kwargs['view_no'] \ or prepare.ppSeqNo != kwargs['pp_seq_no']: raise MismatchedMessageReplyException return prepare
def create_prepare(pp): # Prepare has the following parameters prep_args = [ pp.instId, pp.viewNo, pp.ppSeqNo, pp.ppTime, pp.digest, pp.stateRootHash, pp.txnRootHash ] return Prepare(*prep_args)
def _create_prepare_and_preprepare(inst_id, pp_sq_no, view_no, timestamp, sdk_wallet_client): time = int(timestamp) req_idr = [[sdk_wallet_client[1], 1234]] preprepare = PrePrepare(inst_id, pp_sq_no, view_no, time, req_idr, 1, "123", 1, None, None) prepare = Prepare(inst_id, pp_sq_no, view_no, time, "321", None, None) return preprepare, prepare
def create(self, msg: Dict, **kwargs) -> Optional[Prepare]: prepare = Prepare(**msg) if prepare.instId != kwargs['inst_id'] or prepare.viewNo != kwargs['view_no']: logger.warning( '{}{} found PREPARE {} not satisfying query criteria' .format( THREE_PC_PREFIX, self, prepare)) return None return prepare
def evilSendPrepare(self, ppReq: PrePrepare): prepare = Prepare(self.instId, ppReq.viewNo, ppReq.ppSeqNo, ppReq.ppTime, ppReq.digest, ppReq.stateRootHash, ppReq.txnRootHash, ppReq.auditTxnRootHash) logger.debug( "EVIL: Creating prepare message for request {}: {}".format( ppReq, prepare)) self._ordering_service._add_to_prepares(prepare, self.name) sendDup(self, prepare, count)
def evilSendPrepare(self, ppReq: PrePrepare): prepare = Prepare(self.instId, ppReq.viewNo, ppReq.ppSeqNo, ppReq.ppTime, ppReq.digest, ppReq.stateRootHash, ppReq.txnRootHash) logger.debug( "EVIL: Creating prepare message for request {}: {}".format( ppReq, prepare)) self.addToPrepares(prepare, self.name) sendDup(self, prepare, TPCStat.PrepareSent, count)
def evilSendPrepare(self, ppReq): digest = "random" prepare = Prepare(self.instId, ppReq.viewNo, ppReq.ppSeqNo, ppReq.ppTime, digest, ppReq.stateRootHash, ppReq.txnRootHash) logger.debug( "EVIL: Creating prepare message for request {}: {}".format( ppReq, prepare)) self._ordering_service._add_to_prepares(prepare, self.name) self.send(prepare)
def send_prepare(view_no, pp_seq_no, nodes, state_root=None, txn_root=None): prepare = Prepare( 0, view_no, pp_seq_no, get_utc_epoch(), "random digest", state_root or '0' * 44, txn_root or '0' * 44 ) primary_node = getPrimaryReplica(nodes).node sendMessageToAll(nodes, primary_node, prepare)
def sendPrepareFromPrimary(instId): primary = getPrimaryReplica(nodeSet, instId) viewNo, ppSeqNo = next(iter(primary.sentPrePrepares.keys())) ppReq = primary.sentPrePrepares[viewNo, ppSeqNo] prepare = Prepare(instId, viewNo, ppSeqNo, ppReq.digest, ppReq.stateRootHash, ppReq.txnRootHash) primary.doPrepare(prepare) def chk(): for r in getNonPrimaryReplicas(nodeSet, instId): l = len([ param for param in getAllArgs(r, r.processPrepare) if param['sender'] == primary.name ]) assert l == 1 looper.run(eventually(chk))
discard_counts = {} pre_prepare_msg = PrePrepare( 0, 1, 3, get_utc_epoch(), [ '4AdS22kC7xzb4bcqg9JATuCfAMNcQYcZa1u5eWzs6cSJ', ], init_discarded(), 'f99937241d4c891c08e92a3cc25966607315ca66b51827b170d492962d58a9be', 1, 'CZecK1m7VYjSNCC7pGHj938DSW2tfbqoJp1bMJEtFqvG', '7WrAMboPTcMaQCU1raoj28vnhu2bPMMd2Lr9tEcsXeCJ', 0, True) prepare_msg = Prepare( 0, 1, 3, get_utc_epoch(), 'f99937241d4c891c08e92a3cc25966607315ca66b51827b170d492962d58a9be', 'CZecK1m7VYjSNCC7pGHj938DSW2tfbqoJp1bMJEtFqvG', '7WrAMboPTcMaQCU1raoj28vnhu2bPMMd2Lr9tEcsXeCJ', ) commit_msg = Commit( 0, 1, 3, ) propagate_msg = Propagate( **{ 'request': { 'identifier': '5rArie7XKukPCaEwq5XGQJnM9Fc5aZE3M9HAPVfMU2xC',