def test_cleanup_after_checkpoint_stabilize(orderer): pre_prepares = [create_pre_prepare_no_bls(generate_state_root(), view_no=0, pp_seq_no=1), create_pre_prepare_no_bls(generate_state_root(), view_no=1, pp_seq_no=2), create_pre_prepare_no_bls(generate_state_root(), view_no=1, pp_seq_no=3)] dicts_to_cleaning = [orderer.pre_prepare_tss, orderer.sent_preprepares, orderer.prePrepares, orderer.prepares, orderer.commits, orderer.batches, orderer.pre_prepares_stashed_for_incorrect_time] lists_to_cleaning = [orderer._data.prepared, orderer._data.preprepared] for pp in pre_prepares: for dict_to_cleaning in dicts_to_cleaning: dict_to_cleaning[(pp.viewNo, pp.ppSeqNo)] = pp for list_to_cleaning in lists_to_cleaning: list_to_cleaning.append(preprepare_to_batch_id(pp)) orderer._bus.send(CheckpointStabilized(last_stable_3pc=(1, 2))) for pp in pre_prepares[:2]: for dict_to_cleaning in dicts_to_cleaning: assert (pp.viewNo, pp.ppSeqNo) not in dict_to_cleaning for list_to_cleaning in lists_to_cleaning: assert preprepare_to_batch_id(pp) not in list_to_cleaning for dict_to_cleaning in dicts_to_cleaning: assert (pre_prepares[2].viewNo, pre_prepares[2].ppSeqNo) in dict_to_cleaning for list_to_cleaning in lists_to_cleaning: assert preprepare_to_batch_id(pre_prepares[2]) in list_to_cleaning
def test_commits_gc(bls_bft_replicas): key1 = (0, 0) pre_prepare1 = create_pre_prepare_no_bls(generate_state_root()) process_commits_for_key(key1, pre_prepare1, bls_bft_replicas) key2 = (0, 1) pre_prepare2 = create_pre_prepare_no_bls(generate_state_root()) process_commits_for_key(key2, pre_prepare2, bls_bft_replicas) key3 = (1, 2) pre_prepare3 = create_pre_prepare_no_bls(generate_state_root()) process_commits_for_key(key3, pre_prepare3, bls_bft_replicas) for bls_bft in bls_bft_replicas: assert len(bls_bft._signatures) == 3 assert key1 in bls_bft._signatures assert key2 in bls_bft._signatures assert key3 in bls_bft._signatures for bls_bft in bls_bft_replicas: bls_bft.gc((0, 1)) for bls_bft in bls_bft_replicas: assert len(bls_bft._signatures) == 1 assert not key1 in bls_bft._signatures assert not key2 in bls_bft._signatures assert len(bls_bft._signatures[key3]) == len(bls_bft_replicas)
def fake_msg_batch_committed(): reqs = [ req.as_dict for req in sdk_random_request_objects( 10, identifier="1" * 16, protocol_version=CURRENT_PROTOCOL_VERSION) ] return BatchCommitted(reqs, DOMAIN_LEDGER_ID, get_utc_epoch(), generate_state_root(), generate_state_root(), 1, 10)
def create_valid_batch_committed(): reqs = [ req.as_dict for req in sdk_random_request_objects( 10, identifier="1" * 16, protocol_version=CURRENT_PROTOCOL_VERSION) ] return BatchCommitted(reqs, DOMAIN_LEDGER_ID, 0, 1, 1, get_utc_epoch(), generate_state_root(), generate_state_root(), 1, 2, generate_state_root(), ['Alpha', 'Beta'], 0, 'digest')
def create_3pc_msgs(view_no, pp_seq_no, inst_id): pre_prepare = create_pre_prepare_no_bls(generate_state_root(), view_no=view_no, pp_seq_no=pp_seq_no, inst_id=inst_id) prepare = create_prepare(req_key=(view_no, pp_seq_no), state_root=generate_state_root(), inst_id=inst_id) commit = create_commit_no_bls_sig(req_key=(view_no, pp_seq_no), inst_id=inst_id) return [pre_prepare, prepare, commit]
def create_three_pc_msgs(replica, pp_seq_no): pre_prepare = create_pre_prepare_no_bls(generate_state_root(), view_no=replica.viewNo, pp_seq_no=pp_seq_no, inst_id=replica.instId) prepare = create_prepare(req_key=(replica.viewNo, pp_seq_no), state_root=generate_state_root(), inst_id=replica.instId) commit = create_commit_no_bls_sig(req_key=(replica.viewNo, pp_seq_no), inst_id=replica.instId) return [pre_prepare, prepare, commit]
def create_observed_data(seq_no_start=1, seq_no_end=5): req_num = seq_no_end - seq_no_start + 1 reqs = [ req.as_dict for req in sdk_random_request_objects( req_num, identifier="1" * 16, protocol_version=CURRENT_PROTOCOL_VERSION) ] msg = BatchCommitted(reqs, DOMAIN_LEDGER_ID, 0, 0, 1, get_utc_epoch(), generate_state_root(), generate_state_root(), seq_no_start, seq_no_end, generate_state_root()) return ObservedData(BATCH, msg)
def test_check_previous_view_view_change_prep_cert_non_commit(validator, pp_seq_no): validator.replica.node.view_change_in_progress = True validator.replica.last_prepared_before_view_change = (validator.view_no - 1, 10) pre_prepare = create_pre_prepare_no_bls(generate_state_root(), view_no=validator.view_no - 1, pp_seq_no=pp_seq_no, inst_id=validator.inst_id) prepare = create_prepare(req_key=(validator.view_no - 1, pp_seq_no), state_root=generate_state_root(), inst_id=validator.inst_id) assert validator.validate_3pc_msg(pre_prepare) == (DISCARD, OLD_VIEW) assert validator.validate_3pc_msg(prepare) == (DISCARD, OLD_VIEW)
def create_pre_prepares(view_no): return [ create_pre_prepare_no_bls(generate_state_root(), view_no=view_no, pp_seq_no=11), create_pre_prepare_no_bls(generate_state_root(), view_no=view_no, pp_seq_no=12), create_pre_prepare_no_bls(generate_state_root(), view_no=view_no, pp_seq_no=13) ]
def pre_prepare_incorrect(state_root, request): if request.param == 'state_root': params = create_pre_prepare_params(state_root=generate_state_root()) elif request.param == 'ledger_id': params = create_pre_prepare_params(state_root=state_root, ledger_id=DOMAIN_LEDGER_ID) elif request.param == 'timestamp': params = create_pre_prepare_params(state_root=state_root, timestamp=get_utc_epoch() + 1000) elif request.param == 'txn_root': params = create_pre_prepare_params(state_root=state_root, txn_root=generate_state_root()) return PrePrepare(*params)
def test_clear_old_view_pre_prepares_till_3pc_multiple_digests(orderer): pp1 = create_pre_prepare_no_bls(generate_state_root(), view_no=0, pp_seq_no=1) orderer.old_view_preprepares[(0, 1, 'd1')] = pp1 orderer.old_view_preprepares[(0, 1, 'd2')] = pp1 pp2 = create_pre_prepare_no_bls(generate_state_root(), view_no=1, pp_seq_no=2) orderer.old_view_preprepares[(1, 2, 'd1')] = pp2 orderer.old_view_preprepares[(1, 2, 'd2')] = pp2 orderer.gc(till3PCKey=(1, 1)) assert len(orderer.old_view_preprepares) == 2 assert (1, 2, 'd1') in orderer.old_view_preprepares assert (1, 2, 'd2') in orderer.old_view_preprepares
def create_invalid_batch_committed(): return BatchCommitted(["aaaa", "bbbb"], DOMAIN_LEDGER_ID, 0, 1, 1, get_utc_epoch(), generate_state_root(), generate_state_root(), 1, 2, generate_state_root(), ['Alpha', 'Beta'], 0)
def test_node_reg_in_ordered_from_audit_for_tree_txns(test_node): node_regs = {} replica = test_node.master_replica node_reg = ["Alpha", "Beta", "Gamma", "Delta", "Eta"] for i in range(3): pp = create_pre_prepare_no_bls(state_root=generate_state_root(), pp_seq_no=i) key = (pp.viewNo, pp.ppSeqNo) replica._ordering_service.prePrepares[key] = pp replica._consensus_data.preprepared.append(preprepare_to_batch_id(pp)) three_pc_batch = ThreePcBatch.from_pre_prepare( pre_prepare=pp, state_root=pp.stateRootHash, txn_root=pp.txnRootHash, valid_digests=pp.reqIdr) three_pc_batch.node_reg = node_reg + ["Node{}".format(i + 10)] three_pc_batch.primaries = ["Alpha", "Beta"] test_node.write_manager.audit_b_handler.post_batch_applied( three_pc_batch) node_regs[key] = three_pc_batch.node_reg for key in reversed(list(node_regs.keys())): pp = replica._ordering_service.get_preprepare(*key) assert replica._ordering_service._get_node_reg_for_ordered( pp) == node_regs[key]
def test_primaries_in_ordered_from_audit_for_tree_txns(test_node): node_regs = {} replica = test_node.master_replica test_node.primaries = ["Alpha", "Beta"] node_reg = ["Alpha", "Beta", "Gamma", "Delta", "Eta"] for i in range(3): pp = create_pre_prepare_no_bls(state_root=generate_state_root(), pp_seq_no=i) key = (pp.viewNo, pp.ppSeqNo) replica._ordering_service.prePrepares[key] = pp replica._consensus_data.preprepared.append(preprepare_to_batch_id(pp)) three_pc_batch = ThreePcBatch.from_pre_prepare(pre_prepare=pp, state_root=pp.stateRootHash, txn_root=pp.txnRootHash, primaries=["Node{}".format(num) for num in range(i + 1)], valid_digests=pp.reqIdr) three_pc_batch.node_reg = node_reg + ["Node{}".format(i + 10)] test_node.write_manager.audit_b_handler.post_batch_applied(three_pc_batch) node_regs[key] = three_pc_batch.node_reg for key in reversed(list(node_regs.keys())): replica._ordering_service._order_3pc_key(key) for ordered in replica.outBox: if not isinstance(ordered, Ordered): continue assert ordered.nodeReg == node_regs[(ordered.viewNo, ordered.ppSeqNo)]
def test_node_reg_in_ordered_from_audit_no_node_reg(test_node): replica = test_node.master_replica # run multiple times to have a situation when we write node reg to non-empty audit ledger for i in range(1, 4): uncommitted_node_reg = ['Alpha', 'Beta', 'Gamma', 'Node{}'.format(i)] test_node.write_manager.node_reg_handler.uncommitted_node_reg = uncommitted_node_reg pre_prepare = create_pre_prepare_no_bls( state_root=generate_state_root(), pp_seq_no=i) key = (pre_prepare.viewNo, pre_prepare.ppSeqNo) replica._ordering_service.prePrepares[key] = pre_prepare replica._consensus_data.preprepared.append( preprepare_to_batch_id(pre_prepare)) test_node.primaries = ["Alpha", "Beta"] three_pc_batch = ThreePcBatch.from_pre_prepare( pre_prepare=pre_prepare, state_root=pre_prepare.stateRootHash, txn_root=pre_prepare.txnRootHash, primaries=["Alpha", "Beta", "Gamma"], valid_digests=pre_prepare.reqIdr) three_pc_batch.node_reg = None test_node.write_manager.audit_b_handler.post_batch_applied( three_pc_batch) replica._ordering_service._order_3pc_key(key) ordered = replica.outBox.pop() # we expect it equal to the current uncommitted node reg assert ordered.nodeReg == uncommitted_node_reg
def test_validate_prepare_wrong_audit_root(r, pre_prepare, prepare): r.processPrePrepare(pre_prepare, PRIMARY_NAME) prepare = updateNamedTuple(prepare, auditTxnRootHash=generate_state_root()) with pytest.raises(SuspiciousNode, match=str( Suspicions.PR_AUDIT_TXN_ROOT_HASH_WRONG.code)): r.validatePrepare(prepare, NON_PRIMARY_NAME)
def test_primaries_in_ordered_from_audit_for_tree_txns(test_node): primaries = {} replica = test_node.master_replica test_node.primaries = ["Alpha", "Beta"] for i in range(3): pp = create_pre_prepare_no_bls(state_root=generate_state_root(), pp_seq_no=i) key = (pp.viewNo, pp.ppSeqNo) replica.prePrepares[key] = pp three_pc_batch = ThreePcBatch.from_pre_prepare( pre_prepare=pp, state_root=pp.stateRootHash, txn_root=pp.txnRootHash, primaries=["Node{}".format(num) for num in range(i + 1)], valid_digests=pp.reqIdr) test_node.audit_handler.post_batch_applied(three_pc_batch) primaries[key] = three_pc_batch.primaries for key in reversed(list(primaries.keys())): replica.order_3pc_key(key) for ordered in replica.outBox: if not isinstance(ordered, Ordered): continue assert ordered.primaries != test_node.primaries assert ordered.primaries == primaries[(ordered.viewNo, ordered.ppSeqNo)]
def test_ts_is_not_set_for_non_pp(primary_orderer, ts_now, sender, pp, sender_orderer): primary_orderer.process_prepare( create_prepare(req_key=(0, 1), state_root=generate_state_root()), sender_orderer) primary_orderer.process_commit(create_commit_no_bls_sig(req_key=(0, 1)), sender_orderer) assert len(primary_orderer.pre_prepare_tss) == 0
def test_clear_old_view_pre_prepares_till_3pc(orderer): orderer.old_view_preprepares[(0, 1, 'd1')] = create_pre_prepare_no_bls(generate_state_root(), view_no=0, pp_seq_no=1) orderer.old_view_preprepares[(0, 2, 'd2')] = create_pre_prepare_no_bls(generate_state_root(), view_no=0, pp_seq_no=2) orderer.old_view_preprepares[(1, 3, 'd3')] = create_pre_prepare_no_bls(generate_state_root(), view_no=1, pp_seq_no=3) orderer.old_view_preprepares[(1, 4, 'd4')] = create_pre_prepare_no_bls(generate_state_root(), view_no=1, pp_seq_no=4) orderer.old_view_preprepares[(2, 5, 'd5')] = create_pre_prepare_no_bls(generate_state_root(), view_no=1, pp_seq_no=5) orderer.gc(till3PCKey=(1, 3)) assert len(orderer.old_view_preprepares) == 2 assert (1, 4, 'd4') in orderer.old_view_preprepares assert (2, 5, 'd5') in orderer.old_view_preprepares
def pp(primary_replica, ts_now): params = create_pre_prepare_params( generate_state_root(), inst_id=primary_replica.instId, view_no=primary_replica.viewNo, pp_seq_no=(primary_replica.last_ordered_3pc[1] + 1), timestamp=ts_now) return PrePrepare(*params)
def test_discard_process_three_phase_msg(test_node, looper): sender = "NodeSender" inst_id = 0 replica = test_node.replicas[inst_id] view_no = test_node.viewNo pp_seq_no = 0 # should start with 1 msg = create_prepare((view_no, pp_seq_no), generate_state_root(), inst_id) replica._external_bus.process_incoming(msg, sender) checkDiscardMsg([replica.stasher, ], msg, INCORRECT_PP_SEQ_NO)
def test_discard_process_three_phase_msg_for_old_view(test_node, looper): sender = "NodeSender" inst_id = 0 replica = test_node.replicas[inst_id] view_no = test_node.viewNo - 1 pp_seq_no = replica.last_ordered_3pc[1] + 1 msg = create_prepare((view_no, pp_seq_no), generate_state_root(), inst_id) replica._external_bus.process_incoming(msg, sender) checkDiscardMsg([replica.stasher, ], msg, OLD_VIEW)
def test_process_three_phase_msg_and_stashed_future_view(test_node, looper): sender = "NodeSender" inst_id = 0 replica = test_node.replicas[inst_id] old_stashed_future_view_msgs = replica.stasher.num_stashed_future_view view_no = test_node.viewNo + 1 pp_seq_no = replica.last_ordered_3pc[1] + 1 msg = create_prepare((view_no, pp_seq_no), generate_state_root(), inst_id) replica.process_three_phase_msg(msg, sender) assert old_stashed_future_view_msgs + 1 == replica.stasher.num_stashed_future_view
def test_process_three_phase_msg_and_stashed_future_view(test_node, looper): sender = "NodeSender" inst_id = 0 replica = test_node.replicas[inst_id] old_stashed_future_view_msgs = replica.stasher.stash_size(STASH_VIEW_3PC) view_no = test_node.viewNo + 1 pp_seq_no = replica.last_ordered_3pc[1] + 1 msg = create_prepare((view_no, pp_seq_no), generate_state_root(), inst_id) replica._external_bus.process_incoming(msg, sender) assert old_stashed_future_view_msgs + 1 == replica.stasher.stash_size(STASH_VIEW_3PC)
def test_process_three_phase_msg_and_stashed_for_next_checkpoint(test_node, looper): sender = "NodeSender" inst_id = 0 replica = test_node.replicas[inst_id] old_stashed_watermarks_msgs = replica.stasher.stash_size(STASH_WATERMARKS) view_no = test_node.viewNo pp_seq_no = replica.H + 1 msg = create_prepare((view_no, pp_seq_no), generate_state_root(), inst_id) replica._external_bus.process_incoming(msg, sender) assert old_stashed_watermarks_msgs + 1 == replica.stasher.stash_size(STASH_WATERMARKS)
def test_validate_prepare_wrong_state_root(o, pre_prepare, prepare): handler = Mock() o._bus.subscribe(RaisedSuspicion, handler) o.process_preprepare(pre_prepare, PRIMARY_NAME) prepare = updateNamedTuple(prepare, stateRootHash=generate_state_root()) o._validate_prepare(prepare, NON_PRIMARY_NAME) check_suspicious( handler, RaisedSuspicion(inst_id=o._data.inst_id, ex=SuspiciousNode(NON_PRIMARY_NAME, Suspicions.PR_STATE_WRONG, prepare)))
def test_process_three_phase_msg_and_stashed_for_next_checkpoint( test_node, looper): sender = "NodeSender" inst_id = 0 replica = test_node.replicas[inst_id] old_stashed_watermarks_msgs = replica.stasher.num_stashed_watermarks view_no = test_node.viewNo pp_seq_no = replica.H + 1 msg = create_prepare((view_no, pp_seq_no), generate_state_root(), inst_id) replica.process_three_phase_msg(msg, sender) assert old_stashed_watermarks_msgs + 1 == replica.stasher.num_stashed_watermarks
def test_process_three_phase_msg_with_catchup_stash(test_node, looper): sender = "NodeSender" inst_id = 0 replica = test_node.replicas[inst_id] old_catchup_stashed_msgs = replica.stasher.num_stashed_catchup test_node.mode = Mode.syncing # catchup in process view_no = test_node.viewNo pp_seq_no = replica.last_ordered_3pc[1] + 1 msg = create_prepare((view_no, pp_seq_no), generate_state_root(), inst_id) replica.process_three_phase_msg(msg, sender) assert old_catchup_stashed_msgs + 1 == replica.stasher.num_stashed_catchup
def test_discard_process_three_phase_already_ordered_msg(test_node, looper): sender = "NodeSender" inst_id = 0 replica = test_node.replicas[inst_id] replica.last_ordered_3pc = (test_node.viewNo, 100) replica._checkpointer.update_watermark_from_3pc() view_no = test_node.viewNo pp_seq_no = replica.h msg = create_prepare((view_no, pp_seq_no), generate_state_root(), inst_id) replica._external_bus.process_incoming(msg, sender) checkDiscardMsg([replica.stasher, ], msg, ALREADY_ORDERED)
def test_primaries_in_ordered_from_node(test_node): pre_prepare = create_pre_prepare_no_bls(state_root=generate_state_root(), pp_seq_no=1) key = (pre_prepare.viewNo, pre_prepare.ppSeqNo) test_node.primaries = ["Alpha", "Beta"] replica = test_node.master_replica replica.prePrepares[key] = pre_prepare replica.order_3pc_key(key) ordered = replica.outBox.pop() assert ordered.primaries == test_node.primaries