Esempio n. 1
0
def test_calc_checkpoints_empty(builder):
    vc = ViewChange(viewNo=2, stableCheckpoint=0,
                    prepared=[BatchID(1, 1, 1, "digest1")],
                    preprepared=[BatchID(1, 1, 1, "digest1")],
                    checkpoints=[])
    vcs = [vc, vc, vc, vc]
    assert builder.calc_checkpoint(vcs) is None
def test_view_change_data(view_change_service, data):
    data.view_no = 1
    data.checkpoints.clear()
    cp = Checkpoint(instId=0,
                    viewNo=1,
                    seqNoStart=0,
                    seqNoEnd=10,
                    digest=cp_digest(10))
    data.checkpoints.add(cp)
    data.stable_checkpoint = 10
    data.prepared = [BatchID(0, 0, 1, "digest1"), BatchID(0, 0, 2, "digest2")]
    data.preprepared = [
        BatchID(0, 0, 1, "digest1"),
        BatchID(0, 0, 2, "digest2"),
        BatchID(0, 0, 3, "digest3")
    ]

    view_change_service._bus.send(NeedViewChange())

    assert data.view_no == 2
    msg = get_view_change(view_change_service)
    assert msg.viewNo == 2
    assert msg.prepared == [(0, 0, 1, "digest1"), (0, 0, 2, "digest2")]
    assert msg.preprepared == [(0, 0, 1, "digest1"), (0, 0, 2, "digest2"),
                               (0, 0, 3, "digest3")]
    assert msg.stableCheckpoint == 10
    assert msg.checkpoints == [cp]
def test_view_change_data_multiple(view_change_service, data):
    # view 0 -> 1
    data.view_no = 0
    cp1 = Checkpoint(instId=0,
                     viewNo=0,
                     seqNoStart=0,
                     seqNoEnd=10,
                     digest=cp_digest(10))
    data.checkpoints.add(cp1)
    data.stable_checkpoint = 0
    data.prepared = [BatchID(0, 0, 1, "digest1"), BatchID(0, 0, 2, "digest2")]
    data.preprepared = [
        BatchID(0, 0, 1, "digest1"),
        BatchID(0, 0, 2, "digest2"),
        BatchID(0, 0, 3, "digest3")
    ]

    view_change_service._bus.send(NeedViewChange())
    assert data.view_no == 1

    msg = get_view_change(view_change_service)
    assert msg.viewNo == 1
    assert msg.prepared == [(0, 0, 1, "digest1"), (0, 0, 2, "digest2")]
    assert msg.preprepared == [(0, 0, 1, "digest1"), (0, 0, 2, "digest2"),
                               (0, 0, 3, "digest3")]
    assert msg.stableCheckpoint == 0
    assert msg.checkpoints == [data.initial_checkpoint, cp1]

    # view 1 -> 2
    data.view_no = 1
    cp2 = Checkpoint(instId=0,
                     viewNo=1,
                     seqNoStart=0,
                     seqNoEnd=20,
                     digest=cp_digest(20))
    data.checkpoints.add(cp2)
    data.stable_checkpoint = 0
    data.prepared = [
        BatchID(1, 1, 11, "digest11"),
        BatchID(1, 1, 12, "digest12")
    ]
    data.preprepared = [
        BatchID(1, 1, 11, "digest11"),
        BatchID(1, 1, 12, "digest12"),
        BatchID(1, 1, 13, "digest13")
    ]

    view_change_service._bus.send(NeedViewChange())
    assert data.view_no == 2

    msg = get_view_change(view_change_service)
    assert msg.viewNo == 2
    assert msg.prepared == [(0, 0, 1, "digest1"), (0, 0, 2, "digest2"),
                            (1, 1, 11, "digest11"), (1, 1, 12, "digest12")]
    assert msg.preprepared == [(0, 0, 1, "digest1"), (0, 0, 2, "digest2"),
                               (0, 0, 3, "digest3"), (1, 1, 11, "digest11"),
                               (1, 1, 12, "digest12"), (1, 1, 13, "digest13")]
    assert msg.stableCheckpoint == 0
    assert msg.checkpoints == [data.initial_checkpoint, cp1, cp2]
Esempio n. 4
0
def test_calc_checkpoints_equal_stable(builder):
    cp = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=10, digest=cp_digest(0))
    vc = ViewChange(viewNo=2, stableCheckpoint=10,
                    prepared=[BatchID(1, 1, 1, "digest1")],
                    preprepared=[BatchID(1, 1, 1, "digest1")],
                    checkpoints=[cp])
    vcs = [vc, vc, vc, vc]
    assert builder.calc_checkpoint(vcs) == cp
Esempio n. 5
0
def test_calc_batches_diff_pp_viewno_in_prepare_and_preprepare(builder):
    cp = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=0, digest=cp_digest(0))
    vc = ViewChange(viewNo=2, stableCheckpoint=0,
                    prepared=[BatchID(1, 0, 1, "digest1"), BatchID(1, 0, 2, "digest2")],
                    preprepared=[BatchID(1, 1, 1, "digest1"), BatchID(1, 1, 2, "digest2")],
                    checkpoints=[cp])

    vcs = [vc, vc, vc, vc]
    assert builder.calc_batches(cp, vcs) is None
Esempio n. 6
0
def test_calc_checkpoints_selects_max(builder):
    cp1 = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=0, digest=cp_digest(0))
    cp2 = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=10, digest=cp_digest(10))
    cp3 = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=20, digest=cp_digest(20))

    vc1 = ViewChange(viewNo=2, stableCheckpoint=0,
                     prepared=[BatchID(1, 1, 1, "digest1")],
                     preprepared=[BatchID(1, 1, 1, "digest1")],
                     checkpoints=[cp1])

    vc2_not_stable = ViewChange(viewNo=2, stableCheckpoint=0,
                                prepared=[BatchID(1, 1, 1, "digest1")],
                                preprepared=[BatchID(1, 1, 1, "digest1")],
                                checkpoints=[cp2])

    vc2_stable = ViewChange(viewNo=2, stableCheckpoint=10,
                            prepared=[BatchID(1, 1, 1, "digest1")],
                            preprepared=[BatchID(1, 1, 1, "digest1")],
                            checkpoints=[cp2])

    vc3_not_stable = ViewChange(viewNo=2, stableCheckpoint=10,
                                prepared=[BatchID(1, 1, 1, "digest1")],
                                preprepared=[BatchID(1, 1, 1, "digest1")],
                                checkpoints=[cp3])

    vc3_stable = ViewChange(viewNo=2, stableCheckpoint=10,
                            prepared=[BatchID(1, 1, 1, "digest1")],
                            preprepared=[BatchID(1, 1, 1, "digest1")],
                            checkpoints=[cp3])

    for vc3 in (vc3_not_stable, vc3_stable):
        for vc2 in (vc2_not_stable, vc2_stable):
            vcs = [vc1, vc2, vc3, vc3]
            assert builder.calc_checkpoint(vcs) == cp3

            vcs = [vc1, vc3, vc3, vc3]
            assert builder.calc_checkpoint(vcs) == cp3

            vcs = [vc2, vc3, vc3, vc3]
            assert builder.calc_checkpoint(vcs) == cp3

            vcs = [vc2, vc2, vc3, vc3]
            assert builder.calc_checkpoint(vcs) == cp3

            vcs = [vc1, vc1, vc3, vc3]
            assert builder.calc_checkpoint(vcs) == cp3

            vcs = [vc1, vc1, vc1, vc3]
            assert builder.calc_checkpoint(vcs) == cp1

            vcs = [vc1, vc1, vc2, vc2]
            assert builder.calc_checkpoint(vcs) == cp2

            vcs = [vc2, vc2, vc2, vc3]
            assert builder.calc_checkpoint(vcs) == cp2
Esempio n. 7
0
def test_calc_batches_takes_quorum_of_prepared(builder):
    cp = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=0, digest=cp_digest(0))
    vc1 = ViewChange(viewNo=1, stableCheckpoint=0,
                     prepared=[BatchID(0, 0, 1, "digest2")],
                     preprepared=[BatchID(0, 0, 1, "digest2")],
                     checkpoints=[cp])
    vc2 = ViewChange(viewNo=1, stableCheckpoint=0,
                     prepared=[BatchID(0, 0, 1, "digest1")],
                     preprepared=[BatchID(0, 0, 1, "digest1")],
                     checkpoints=[cp])
    vc3 = ViewChange(viewNo=1, stableCheckpoint=0,
                     prepared=[],
                     preprepared=[BatchID(0, 0, 1, "digest1")],
                     checkpoints=[cp])

    vcs = [vc1, vc2, vc2, vc2]
    assert builder.calc_batches(cp, vcs) == [BatchID(0, 0, 1, "digest1")]

    vcs = [vc3, vc2, vc2, vc2]
    assert builder.calc_batches(cp, vcs) == [BatchID(0, 0, 1, "digest1")]

    vcs = [vc3, vc3, vc3, vc3]
    assert builder.calc_batches(cp, vcs) == []

    vcs = [vc1, vc1, vc2, vc2]
    assert builder.calc_batches(cp, vcs) is None

    # since we have enough pre-prepares
    vcs = [vc2, vc3, vc3, vc3]
    assert builder.calc_batches(cp, vcs) == [BatchID(0, 0, 1, "digest1")]
    vcs = [vc2, vc2, vc3, vc3]
    assert builder.calc_batches(cp, vcs) == [BatchID(0, 0, 1, "digest1")]
Esempio n. 8
0
def test_calc_batches_takes_max_view_same_pp_view(builder):
    cp = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=0, digest=cp_digest(0))
    vc = ViewChange(viewNo=2, stableCheckpoint=0,
                    prepared=[BatchID(0, 0, 1, "digest1"), BatchID(0, 0, 2, "digest2"),
                              BatchID(1, 1, 1, "digest1"), BatchID(1, 1, 2, "digest2")],
                    preprepared=[BatchID(0, 0, 1, "digest1"), BatchID(0, 0, 2, "digest2"), BatchID(1, 1, 1, "digest1"),
                                 BatchID(1, 1, 2, "digest2")],
                    checkpoints=[cp])

    vcs = [vc, vc, vc, vc]
    assert builder.calc_batches(cp, vcs) == [BatchID(1, 1, 1, "digest1"), BatchID(1, 1, 2, "digest2")]
Esempio n. 9
0
def test_calc_batches_quorum(builder):
    cp = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=0, digest=cp_digest(0))
    vc = ViewChange(viewNo=1, stableCheckpoint=0,
                    prepared=[BatchID(0, 0, 1, "digest1"), BatchID(0, 0, 2, "digest2")],
                    preprepared=[BatchID(0, 0, 1, "digest1"), BatchID(0, 0, 2, "digest2"), BatchID(0, 0, 3, "digest3")],
                    checkpoints=[cp])

    vcs = [vc]
    assert builder.calc_batches(cp, vcs) is None

    vcs.append(vc)
    assert builder.calc_batches(cp, vcs) is None

    vcs.append(vc)
    assert builder.calc_batches(cp, vcs)
Esempio n. 10
0
def calc_committed(view_changes, max_pp_seq_no, n, f) -> List[BatchID]:
    def check_prepared_in_vc(vc, batch_id):
        # check that batch_id is present in VC's prepared and preprepared
        for p_batch_id in vc.prepared:
            if batch_id != p_batch_id:
                continue
            for pp_batch_id in vc.preprepared:
                if batch_id == pp_batch_id:
                    return True

        return False

    def find_batch_id(pp_seq_no):
        for vc in view_changes:
            for batch_id in vc.prepared:
                if batch_id[2] != pp_seq_no:
                    continue
                prepared_count = sum(1 for vc in view_changes
                                     if check_prepared_in_vc(vc, batch_id))
                if prepared_count < n - f:
                    continue
                return batch_id
        return None

    committed = []
    for pp_seq_no in range(1, max_pp_seq_no):
        batch_id = find_batch_id(pp_seq_no)
        if batch_id is not None:
            committed.append(BatchID(*batch_id))

    return committed
Esempio n. 11
0
 def update_shared_data(node, msg: NewViewCheckpointsApplied):
     x = [
         BatchID(view_no=msg.view_no,
                 pp_view_no=batch_id.pp_view_no,
                 pp_seq_no=batch_id.pp_seq_no,
                 pp_digest=batch_id.pp_digest)
         for batch_id in msg.batches
     ]
     node._orderer._data.preprepared = x
Esempio n. 12
0
        def check(vc: ViewChange):
            if pp_seq_no <= vc.stableCheckpoint:
                return False

            for _some_bid in vc.prepared:
                some_bid = BatchID(*_some_bid)
                if some_bid.pp_seq_no == pp_seq_no:
                    return False
            return True
Esempio n. 13
0
def test_calc_batches_respects_checkpoint(builder):
    cp = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=10, digest=cp_digest(10))
    vc = ViewChange(viewNo=1, stableCheckpoint=0,
                    prepared=[BatchID(0, 0, 1, "digest1"), BatchID(0, 0, 2, "digest2")],
                    preprepared=[BatchID(0, 0, 1, "digest1"), BatchID(0, 0, 2, "digest2")],
                    checkpoints=[cp])

    vcs = [vc, vc, vc, vc]
    assert builder.calc_batches(cp, vcs) == []

    cp = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=10, digest=cp_digest(10))
    vc = ViewChange(viewNo=2, stableCheckpoint=0,
                    prepared=[BatchID(0, 0, 10, "digest10"), BatchID(0, 0, 11, "digest11"), BatchID(1, 0, 12, "digest12")],
                    preprepared=[BatchID(0, 0, 10, "digest10"), BatchID(0, 0, 11, "digest11"), BatchID(1, 0, 12, "digest12")],
                    checkpoints=[cp])

    vcs = [vc, vc, vc, vc]
    assert builder.calc_batches(cp, vcs) == [BatchID(0, 0, 11, "digest11"), BatchID(1, 0, 12, "digest12")]
Esempio n. 14
0
def test_calc_batches_takes_prepared_only(builder):
    cp = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=0, digest=cp_digest(0))
    vc = ViewChange(viewNo=1, stableCheckpoint=0,
                    prepared=[],
                    preprepared=[BatchID(0, 0, 1, "digest1"), BatchID(0, 0, 2, "digest2"), BatchID(0, 0, 3, "digest3"),
                                 BatchID(0, 0, 4, "digest4")],
                    checkpoints=[cp])

    vcs = [vc, vc, vc, vc]
    assert builder.calc_batches(cp, vcs) == []

    cp = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=0, digest=cp_digest(0))
    vc = ViewChange(viewNo=1, stableCheckpoint=0,
                    prepared=[BatchID(0, 0, 1, "digest1"), BatchID(0, 0, 2, "digest2")],
                    preprepared=[BatchID(0, 0, 1, "digest1"), BatchID(0, 0, 2, "digest2"), BatchID(0, 0, 3, "digest3"),
                                 BatchID(0, 0, 4, "digest4")],
                    checkpoints=[cp])

    vcs = [vc, vc, vc, vc]
    assert builder.calc_batches(cp, vcs) == [BatchID(0, 0, 1, "digest1"), BatchID(0, 0, 2, "digest2")]
def test_process_preprepare_on_old_view_pre_prepares_reply(
        external_bus, internal_bus, orderer, is_primary, initial_view_no,
        pre_prepares):
    # !!!SETUP!!!
    orderer._data.view_no = initial_view_no + 1
    new_view = create_new_view(
        initial_view_no=initial_view_no,
        stable_cp=200,
        batches=create_batches_from_preprepares(pre_prepares))
    orderer._data.new_view_votes.add_new_view(new_view,
                                              orderer._data.primary_name)
    orderer._data.prev_view_prepare_cert = new_view.batches[-1].pp_seq_no

    # !!!EXECUTE!!!
    rep = OldViewPrePrepareReply(0, [pp._asdict() for pp in pre_prepares])
    orderer._network.process_incoming(
        rep, generateName("node1", orderer._data.inst_id))

    # !!!CHECK!!!
    if not orderer.is_master:
        # no re-ordering is expected on non-master
        assert orderer._data.preprepared == []
        assert orderer._data.prepared == []
        return

    # check that PPs were added
    assert orderer._data.preprepared == [
        BatchID(view_no=initial_view_no + 1,
                pp_view_no=pp.viewNo,
                pp_seq_no=pp.ppSeqNo,
                pp_digest=pp.digest) for pp in pre_prepares
    ]

    # check that sent_preprepares is updated in case of Primary and prePrepares in case of non-primary
    updated_prepares_collection = orderer.prePrepares if not is_primary else orderer.sent_preprepares
    non_updated_prepares_collection = orderer.sent_preprepares if not is_primary else orderer.prePrepares
    for pp in pre_prepares:
        new_pp = updateNamedTuple(pp,
                                  viewNo=initial_view_no + 1,
                                  originalViewNo=pp.viewNo)
        assert (initial_view_no + 1,
                new_pp.ppSeqNo) in updated_prepares_collection
        assert updated_prepares_collection[(initial_view_no + 1,
                                            new_pp.ppSeqNo)] == new_pp
    assert not non_updated_prepares_collection

    # check that Prepare is sent in case of non primary
    if not is_primary:
        check_prepares_sent(external_bus, pre_prepares, initial_view_no + 1)
    else:
        assert len(external_bus.sent_messages) == 0

    # we don't have a quorum of Prepares yet
    assert orderer._data.prepared == []
Esempio n. 16
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     if isinstance(self.checkpoint, dict):
         self.checkpoint = Checkpoint(**self.checkpoint)
     # The field `batches` can to be a list of BatchIDs or of dicts.
     # If it's not a list of dicts then we don't need to deserialize it.
     if not self.batches or not isinstance(self.batches[0], dict):
         return
     self.batches = [
         BatchID(**bid) for bid in self.batches if isinstance(bid, dict)
     ]
Esempio n. 17
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        checkpoints = []
        for chk in self.checkpoints:
            if isinstance(chk, dict):
                checkpoints.append(Checkpoint(**chk))
        if checkpoints:
            self.checkpoints = checkpoints

        # The field `prepared` can to be a list of BatchIDs or of dicts.
        # If its a list of dicts then we need to deserialize it.
        if self.prepared and isinstance(self.prepared[0], dict):
            self.prepared = [BatchID(**bid)
                             for bid in self.prepared
                             if isinstance(bid, dict)]
        # The field `preprepared` can to be a list of BatchIDs or of dicts.
        # If its a list of dicts then we need to deserialize it.
        if self.preprepared and isinstance(self.preprepared[0], dict):
            self.preprepared = [BatchID(**bid)
                                for bid in self.preprepared
                                if isinstance(bid, dict)]
Esempio n. 18
0
    def _specific_validation(self, val):
        if len(val) != 4:
            return 'should have size of 4'
        if isinstance(val, dict):
            if any(key not in BatchID._fields for key in val.keys()):
                return 'incorrect list of fields'
            bid = BatchID(**val)
        else:
            bid = BatchID(*val)

        for validate, value in ((self._validate_non_negative_number_field,
                                 bid.view_no),
                                (self._validate_non_negative_number_field,
                                 bid.pp_view_no),
                                (self._validate_non_negative_number_field,
                                 bid.pp_seq_no),
                                (self._validate_non_empty_string_field,
                                 bid.pp_digest)):
            err = validate(value)
            if err:
                return err
Esempio n. 19
0
    def _specific_validation(self, val):
        if len(val) != 4:
            return 'should have size of 4'
        if isinstance(val, dict):
            if any(key not in BatchID._fields for key in val.keys()):
                return 'incorrect list of fields'
            bid = BatchID(**val)
        else:
            bid = BatchID(*val)

        for validator, value in ((NonNegativeNumberField().validate,
                                  bid.view_no),
                                 (NonNegativeNumberField().validate,
                                  bid.pp_view_no),
                                 (NonNegativeNumberField().validate,
                                  bid.pp_seq_no),
                                 (NonEmptyStringField().validate,
                                  bid.pp_digest)):
            err = validator(value)
            if err:
                return err
def test_view_change_replaces_prepare(view_change_service, data):
    data.view_no = 0
    data.prepared = [BatchID(0, 0, 1, "digest1"), BatchID(0, 0, 2, "digest2")]

    # view no 0->1
    view_change_service._bus.send(NeedViewChange())
    assert data.view_no == 1

    msg = get_view_change(view_change_service)
    assert msg.viewNo == 1
    assert msg.prepared == [(0, 0, 1, "digest1"), (0, 0, 2, "digest2")]

    # view no 1->2
    # replace by different viewNo and digest
    data.prepared = [
        BatchID(1, 1, 1, "digest11"),
        BatchID(1, 1, 2, "digest22")
    ]
    view_change_service._bus.send(NeedViewChange())
    assert data.view_no == 2

    msg = get_view_change(view_change_service)
    assert msg.viewNo == 2
    assert msg.prepared == [(1, 1, 1, "digest11"), (1, 1, 2, "digest22")]

    # view no 2->3
    # replace by different viewNo only
    data.prepared = [BatchID(2, 2, 2, "digest22"), BatchID(2, 2, 3, "digest3")]
    view_change_service._bus.send(NeedViewChange())
    assert data.view_no == 3

    msg = get_view_change(view_change_service)
    assert msg.viewNo == 3
    assert msg.prepared == [(1, 1, 1, "digest11"), (2, 2, 2, "digest22"),
                            (2, 2, 3, "digest3")]
Esempio n. 21
0
        def check(vc: ViewChange):
            for _some_bid in vc.preprepared:
                some_bid = BatchID(*_some_bid)
                if some_bid.pp_seq_no != bid.pp_seq_no:
                    continue
                if some_bid.pp_view_no != bid.pp_view_no:
                    continue
                if some_bid.pp_digest != bid.pp_digest:
                    continue
                if some_bid.view_no >= bid.view_no:
                    return True

            return False
Esempio n. 22
0
    def _try_find_batch_for_pp_seq_no(self, vcs, pp_seq_no):
        for vc in vcs:
            for _bid in vc.prepared:
                bid = BatchID(*_bid)
                if bid.pp_seq_no != pp_seq_no:
                    continue
                if not self._is_batch_prepared(bid, vcs):
                    continue
                if not self._is_batch_preprepared(bid, vcs):
                    continue
                return bid

        return None
Esempio n. 23
0
        def check(vc: ViewChange):
            if bid.pp_seq_no <= vc.stableCheckpoint:
                return False

            for _some_bid in vc.prepared:
                some_bid = BatchID(*_some_bid)
                if some_bid.pp_seq_no != bid.pp_seq_no:
                    continue

                # not ( (v' < v) OR (v'==v and d'==d and pp_view_no'==pp_view_no) )
                if some_bid.view_no > bid.view_no:
                    return False
                if some_bid.view_no >= bid.view_no and some_bid.pp_digest != bid.pp_digest:
                    return False
                if some_bid.view_no >= bid.view_no and some_bid.pp_view_no != bid.pp_view_no:
                    return False

            return True
Esempio n. 24
0
def calc_committed(view_changes):
    committed = []
    for pp_seq_no in range(1, 50):
        batch_id = None
        for vc in view_changes:
            # pp_seq_no must be present in all PrePrepares
            for pp in vc.preprepared:
                if pp[2] == pp_seq_no:
                    if batch_id is None:
                        batch_id = pp
                    assert batch_id == pp
                    break

            # pp_seq_no must be present in all Prepares
            if batch_id not in vc.prepared:
                return committed
        committed.append(BatchID(*batch_id))
    return committed
Esempio n. 25
0
def test_calc_checkpoints_quorum(builder):
    cp1 = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=0, digest=cp_digest(0))
    cp2 = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=10, digest=cp_digest(10))

    vc1 = ViewChange(viewNo=2, stableCheckpoint=0,
                     prepared=[BatchID(1, 1, 1, "digest1")],
                     preprepared=[BatchID(1, 1, 1, "digest1")],
                     checkpoints=[cp1])
    vc2 = ViewChange(viewNo=2, stableCheckpoint=0,
                     prepared=[BatchID(1, 1, 1, "digest1")],
                     preprepared=[BatchID(1, 1, 1, "digest1")],
                     checkpoints=[cp2])
    vc2_stable = ViewChange(viewNo=2, stableCheckpoint=10,
                            prepared=[BatchID(1, 1, 1, "digest1")],
                            preprepared=[BatchID(1, 1, 1, "digest1")],
                            checkpoints=[cp2])

    vcs = [vc1, vc1, vc1, vc1]
    assert builder.calc_checkpoint(vcs) == cp1

    vcs = [vc2, vc2, vc2, vc2]
    assert builder.calc_checkpoint(vcs) == cp2

    vcs = [vc2_stable, vc2_stable, vc2_stable, vc2_stable]
    assert builder.calc_checkpoint(vcs) == cp2

    vcs = [vc2, vc1, vc1, vc1]
    assert builder.calc_checkpoint(vcs) == cp1

    vcs = [vc2, vc2, vc1, vc1]
    assert builder.calc_checkpoint(vcs) == cp2

    vcs = [vc2, vc2, vc2, vc1]
    assert builder.calc_checkpoint(vcs) == cp2

    vcs = [vc2_stable, vc1, vc1, vc1]
    assert builder.calc_checkpoint(vcs) == cp1

    vcs = [vc2_stable, vc2_stable, vc1, vc1]
    assert builder.calc_checkpoint(vcs) == cp2

    vcs = [vc2_stable, vc2_stable, vc2_stable, vc1]
    assert builder.calc_checkpoint(vcs) == cp2

    vcs = [vc2_stable, vc2, vc2, vc2]
    assert builder.calc_checkpoint(vcs) == cp2

    vcs = [vc2_stable, vc2_stable, vc2, vc2]
    assert builder.calc_checkpoint(vcs) == cp2

    vcs = [vc2_stable, vc2_stable, vc2_stable, vc2]
    assert builder.calc_checkpoint(vcs) == cp2
Esempio n. 26
0
def test_calc_batches_takes_next_view_prepared_if_old_view_prepared(builder):
    cp = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=0, digest=cp_digest(0))
    vc1 = ViewChange(viewNo=2, stableCheckpoint=0,
                     prepared=[(1, 1, 1, "digest2")],
                     preprepared=[(0, 0, 1, "digest1"), (1, 1, 1, "digest2")],
                     checkpoints=[cp])
    vc2 = ViewChange(viewNo=0, stableCheckpoint=0,
                     prepared=[BatchID(0, 0, 1, "digest1")],
                     preprepared=[BatchID(0, 0, 1, "digest1"), BatchID(1, 1, 1, "digest2")],
                     checkpoints=[cp])
    vc3 = ViewChange(viewNo=2, stableCheckpoint=0,
                     prepared=[BatchID(0, 0, 1, "digest1")],
                     preprepared=[BatchID(0, 0, 1, "digest1")],
                     checkpoints=[cp])
    vc4 = ViewChange(viewNo=2, stableCheckpoint=0,
                     prepared=[BatchID(0, 0, 1, "digest1")],
                     preprepared=[BatchID(0, 0, 1, "digest1")],
                     checkpoints=[cp])

    vcs = [vc1, vc2, vc3, vc4]
    assert builder.calc_batches(cp, vcs) == [BatchID(1, 1, 1, "digest2")]
Esempio n. 27
0
def test_calc_batches_takes_prepared_with_same_batchid_only(builder):
    cp = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=0, digest=cp_digest(0))
    vc1 = ViewChange(viewNo=2, stableCheckpoint=0,
                     prepared=[BatchID(1, 1, 1, "digest1")],
                     preprepared=[BatchID(1, 1, 1, "digest1")],
                     checkpoints=[cp])
    vc2 = ViewChange(viewNo=2, stableCheckpoint=0,
                     prepared=[BatchID(1, 1, 1, "digest1")],
                     preprepared=[BatchID(1, 1, 1, "digest1")],
                     checkpoints=[cp])
    vc3 = ViewChange(viewNo=2, stableCheckpoint=0,
                     prepared=[BatchID(1, 1, 1, "digest2")],
                     preprepared=[BatchID(1, 1, 1, "digest2")],
                     checkpoints=[cp])
    vc4 = ViewChange(viewNo=2, stableCheckpoint=0,
                     prepared=[],
                     preprepared=[BatchID(1, 1, 1, "digest1")],
                     checkpoints=[cp])

    vcs = [vc1, vc2, vc3, vc4]
    assert builder.calc_batches(cp, vcs) == [BatchID(1, 1, 1, "digest1")]
Esempio n. 28
0
def test_calc_checkpoints_digest(builder):
    d1 = cp_digest(0)
    d2 = cp_digest(10)

    cp1_d1 = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=0, digest=d1)
    cp2_d2 = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=10, digest=d2)
    cp2_d1 = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=10, digest=d1)

    vc1_d1 = ViewChange(viewNo=2, stableCheckpoint=0,
                        prepared=[BatchID(1, 1, 1, "digest1")],
                        preprepared=[BatchID(1, 1, 1, "digest1")],
                        checkpoints=[cp1_d1])
    vc2_d2 = ViewChange(viewNo=2, stableCheckpoint=0,
                        prepared=[BatchID(1, 1, 1, "digest1")],
                        preprepared=[BatchID(1, 1, 1, "digest1")],
                        checkpoints=[cp2_d2])
    vc2_d1 = ViewChange(viewNo=2, stableCheckpoint=0,
                        prepared=[BatchID(1, 1, 1, "digest1")],
                        preprepared=[BatchID(1, 1, 1, "digest1")],
                        checkpoints=[cp2_d1])

    vcs = [vc1_d1, vc1_d1, vc2_d1, vc2_d2]
    assert builder.calc_checkpoint(vcs) == cp1_d1

    vcs = [vc1_d1, vc2_d1, vc2_d2, vc2_d2]
    assert builder.calc_checkpoint(vcs) == cp2_d2

    vcs = [vc1_d1, vc2_d2, vc2_d1, vc2_d1]
    assert builder.calc_checkpoint(vcs) == cp2_d1

    # Here we have 2 nodes malicious (f=1), but calc_checkpoint returns a value depending on the order
    # Is it OK, or calc_checkpoint should return None (indicating that there is no valid quorum)?
    vcs = [vc2_d1, vc2_d1, vc2_d2, vc2_d2]
    assert builder.calc_checkpoint(vcs) == cp2_d1
    vcs = [vc2_d2, vc2_d2, vc2_d1, vc2_d1]
    assert builder.calc_checkpoint(vcs) == cp2_d2
Esempio n. 29
0
def create_batches(view_no):
    return [
        BatchID(view_no, view_no, 11, "d1"),
        BatchID(view_no, view_no, 12, "d2"),
        BatchID(view_no, view_no, 13, "d3")
    ]
Esempio n. 30
0
def preprepare_to_batch_id(pre_prepare: PrePrepare) -> BatchID:
    pp_view_no = get_original_viewno(pre_prepare)
    return BatchID(pre_prepare.viewNo, pp_view_no, pre_prepare.ppSeqNo,
                   pre_prepare.digest)