def test_calc_batches_takes_prepared_if_preprepared_in_next_view(builder):
    cp = Checkpoint(instId=0,
                    viewNo=0,
                    seqNoStart=0,
                    seqNoEnd=0,
                    digest='empty')
    vc1 = ViewChange(viewNo=0,
                     stableCheckpoint=0,
                     prepared=[(1, 1, "digest2")],
                     preprepared=[(0, 1, "digest1"), (2, 1, "digest2")],
                     checkpoints=[cp])
    vc2 = ViewChange(viewNo=0,
                     stableCheckpoint=0,
                     prepared=[(0, 1, "digest1")],
                     preprepared=[(0, 1, "digest1"), (2, 1, "digest2")],
                     checkpoints=[cp])
    vc3 = ViewChange(viewNo=0,
                     stableCheckpoint=0,
                     prepared=[(0, 1, "digest1")],
                     preprepared=[(0, 1, "digest1")],
                     checkpoints=[cp])
    vc4 = ViewChange(viewNo=0,
                     stableCheckpoint=0,
                     prepared=[(0, 1, "digest1")],
                     preprepared=[(0, 1, "digest1")],
                     checkpoints=[cp])

    vcs = [vc1, vc2, vc3, vc4]
    assert builder.calc_batches(cp, vcs) == [BatchID(1, 1, "digest2")]
示例#2
0
def test_calc_batches_respects_checkpoint(builder):
    cp = Checkpoint(instId=0,
                    viewNo=0,
                    seqNoStart=0,
                    seqNoEnd=10,
                    digest=cp_digest(0, 0))
    vc = ViewChange(viewNo=0,
                    stableCheckpoint=0,
                    prepared=[(0, 1, "digest1"), (0, 2, "digest2")],
                    preprepared=[(0, 1, "digest1"), (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(0, 0))
    vc = ViewChange(viewNo=0,
                    stableCheckpoint=0,
                    prepared=[(0, 10, "digest10"), (0, 11, "digest11"),
                              (1, 12, "digest12")],
                    preprepared=[(0, 10, "digest10"), (0, 11, "digest11"),
                                 (1, 12, "digest12")],
                    checkpoints=[cp])

    vcs = [vc, vc, vc, vc]
    assert builder.calc_batches(
        cp, vcs) == [BatchID(0, 11, "digest11"),
                     BatchID(1, 12, "digest12")]
示例#3
0
def test_calc_batches_must_be_in_pre_prepare(builder):
    cp = Checkpoint(instId=0,
                    viewNo=0,
                    seqNoStart=0,
                    seqNoEnd=0,
                    digest=cp_digest(0, 0))
    vc = ViewChange(viewNo=0,
                    stableCheckpoint=0,
                    prepared=[(0, 1, "digest1"), (0, 2, "digest2")],
                    preprepared=[(0, 1, "digest1")],
                    checkpoints=[cp])

    vcs = [vc, vc, vc, vc]
    # all nodes are malicious here since all added (0, 2) into prepared without adding to pre-prepared
    # so, None here means we can not calculate NewView reliably
    assert builder.calc_batches(cp, vcs) is None

    vc1 = ViewChange(viewNo=0,
                     stableCheckpoint=0,
                     prepared=[(0, 1, "digest1"), (0, 2, "digest2")],
                     preprepared=[(0, 1, "digest1")],
                     checkpoints=[cp])
    vc2 = ViewChange(viewNo=0,
                     stableCheckpoint=0,
                     prepared=[(0, 1, "digest1")],
                     preprepared=[(0, 1, "digest1")],
                     checkpoints=[cp])

    vcs = [vc1, vc2, vc2, vc2]
    assert builder.calc_batches(cp, vcs) == [BatchID(0, 1, "digest1")]
def test_start_vc_by_quorum_of_vc_msgs(view_change_service_builder,
                                       internal_bus, external_bus, validators,
                                       is_master):
    svc_queue = []

    def svc_handler(msg: StartViewChange):
        svc_queue.append(msg)

    internal_bus.subscribe(StartViewChange, svc_handler)
    # Quorum for ViewChange message is N-f
    service = view_change_service_builder(validators[0])
    proposed_view_no = 10
    f = getMaxFailures(len(validators))
    # Append N-f-1 ViewChange msgs to view_change_votes
    for validator in validators[1:-f]:
        msg = ViewChange(proposed_view_no, 0, [], [], [])
        service.process_view_change_message(msg, validator)
    # N-f-1 msgs is not enough for triggering view_change
    assert not svc_queue
    # Process the other one message
    service.process_view_change_message(
        ViewChange(proposed_view_no, 0, [], [], []), validators[-1])
    if is_master:
        assert svc_queue
        assert isinstance(svc_queue[0], StartViewChange)
        assert svc_queue[0].view_no == proposed_view_no
    else:
        # ViewChange message isn't processed on backups
        assert not svc_queue
示例#5
0
def test_calc_batches_takes_prepared_only(builder):
    cp = Checkpoint(instId=0,
                    viewNo=0,
                    seqNoStart=0,
                    seqNoEnd=0,
                    digest=cp_digest(0, 0))
    vc = ViewChange(viewNo=0,
                    stableCheckpoint=0,
                    prepared=[],
                    preprepared=[(0, 1, "digest1"), (0, 2, "digest2"),
                                 (0, 3, "digest3"), (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, 0))
    vc = ViewChange(viewNo=0,
                    stableCheckpoint=0,
                    prepared=[(0, 1, "digest1"), (0, 2, "digest2")],
                    preprepared=[(0, 1, "digest1"), (0, 2, "digest2"),
                                 (0, 3, "digest3"), (0, 4, "digest4")],
                    checkpoints=[cp])

    vcs = [vc, vc, vc, vc]
    assert builder.calc_batches(
        cp, vcs) == [BatchID(0, 1, "digest1"),
                     BatchID(0, 2, "digest2")]
示例#6
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, 0))
    vc1 = ViewChange(viewNo=0,
                     stableCheckpoint=0,
                     prepared=[(1, 1, "digest1")],
                     preprepared=[(1, 1, "digest1")],
                     checkpoints=[cp])
    vc2 = ViewChange(viewNo=0,
                     stableCheckpoint=0,
                     prepared=[(1, 1, "digest1")],
                     preprepared=[(1, 1, "digest1")],
                     checkpoints=[cp])
    vc3 = ViewChange(viewNo=0,
                     stableCheckpoint=0,
                     prepared=[(1, 1, "digest2")],
                     preprepared=[(1, 1, "digest2")],
                     checkpoints=[cp])
    vc4 = ViewChange(viewNo=0,
                     stableCheckpoint=0,
                     prepared=[],
                     preprepared=[(1, 1, "digest1")],
                     checkpoints=[cp])

    vcs = [vc1, vc2, vc3, vc4]
    assert builder.calc_batches(cp, vcs) == [BatchID(1, 1, "digest1")]
示例#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")]
示例#8
0
def test_calc_batches_empty(builder):
    cp = Checkpoint(instId=0,
                    viewNo=0,
                    seqNoStart=0,
                    seqNoEnd=0,
                    digest=cp_digest(0, 0))
    vcs = [
        ViewChange(viewNo=0,
                   stableCheckpoint=0,
                   prepared=[],
                   preprepared=[],
                   checkpoints=[cp]),
        ViewChange(viewNo=0,
                   stableCheckpoint=0,
                   prepared=[],
                   preprepared=[],
                   checkpoints=[cp]),
        ViewChange(viewNo=0,
                   stableCheckpoint=0,
                   prepared=[],
                   preprepared=[],
                   checkpoints=[cp]),
        ViewChange(viewNo=0,
                   stableCheckpoint=0,
                   prepared=[],
                   preprepared=[],
                   checkpoints=[cp]),
    ]
    assert [] == builder.calc_batches(cp, vcs)
示例#9
0
def test_calc_batches_takes_next_view_one_prepared_if_weak_quorum_of_preprepared(
        builder):
    cp = Checkpoint(instId=0,
                    viewNo=0,
                    seqNoStart=0,
                    seqNoEnd=0,
                    digest=cp_digest(0, 0))
    vc1 = ViewChange(viewNo=0,
                     stableCheckpoint=0,
                     prepared=[(0, 1, "digest1"), (1, 2, "digest2")],
                     preprepared=[(0, 1, "digest1"), (1, 2, "digest2")],
                     checkpoints=[cp])
    vc2 = ViewChange(viewNo=0,
                     stableCheckpoint=0,
                     prepared=[(0, 1, "digest1")],
                     preprepared=[(0, 1, "digest1"), (1, 2, "digest2")],
                     checkpoints=[cp])
    vc3 = ViewChange(viewNo=0,
                     stableCheckpoint=0,
                     prepared=[(0, 1, "digest1")],
                     preprepared=[(0, 1, "digest1")],
                     checkpoints=[cp])
    vc4 = ViewChange(viewNo=0,
                     stableCheckpoint=0,
                     prepared=[(0, 1, "digest1")],
                     preprepared=[(0, 1, "digest1")],
                     checkpoints=[cp])

    vcs = [vc1, vc2, vc3, vc4]
    assert builder.calc_batches(
        cp, vcs) == [BatchID(0, 1, "digest1"), (1, 2, "digest2")]
def test_calc_checkpoints_quorum(builder):
    cp1 = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=0, digest='d1')
    cp2 = Checkpoint(instId=0,
                     viewNo=0,
                     seqNoStart=0,
                     seqNoEnd=10,
                     digest='d2')

    vc1 = ViewChange(viewNo=0,
                     stableCheckpoint=0,
                     prepared=[(1, 1, "digest1")],
                     preprepared=[(1, 1, "digest1")],
                     checkpoints=[cp1])
    vc2 = ViewChange(viewNo=0,
                     stableCheckpoint=0,
                     prepared=[(1, 1, "digest1")],
                     preprepared=[(1, 1, "digest1")],
                     checkpoints=[cp2])
    vc2_stable = ViewChange(viewNo=0,
                            stableCheckpoint=10,
                            prepared=[(1, 1, "digest1")],
                            preprepared=[(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
示例#11
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
示例#12
0
def test_calc_batches_diff_pp_viewno(builder):
    cp = Checkpoint(instId=0, viewNo=0, seqNoStart=0, seqNoEnd=0, digest=cp_digest(0))
    vc1 = ViewChange(viewNo=2, stableCheckpoint=0,
                     prepared=[BatchID(1, 0, 1, "digest1"), BatchID(1, 0, 2, "digest2")],
                     preprepared=[BatchID(1, 0, 1, "digest1"), BatchID(1, 0, 2, "digest2")],
                     checkpoints=[cp])
    vc2 = ViewChange(viewNo=2, stableCheckpoint=0,
                     prepared=[BatchID(1, 1, 1, "digest1"), BatchID(1, 1, 2, "digest2")],
                     preprepared=[BatchID(1, 1, 1, "digest1"), BatchID(1, 1, 2, "digest2")],
                     checkpoints=[cp])

    vcs = [vc1, vc1, vc2, vc2]
    assert builder.calc_batches(cp, vcs) is None
示例#13
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=0,
                        stableCheckpoint=0,
                        prepared=[(1, 1, "digest1")],
                        preprepared=[(1, 1, "digest1")],
                        checkpoints=[cp1_d1])
    vc2_d2 = ViewChange(viewNo=0,
                        stableCheckpoint=0,
                        prepared=[(1, 1, "digest1")],
                        preprepared=[(1, 1, "digest1")],
                        checkpoints=[cp2_d2])
    vc2_d1 = ViewChange(viewNo=0,
                        stableCheckpoint=0,
                        prepared=[(1, 1, "digest1")],
                        preprepared=[(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
示例#14
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
示例#15
0
 def _view_change(view_no: int):
     vc = ViewChange(viewNo=view_no,
                     stableCheckpoint=4,
                     prepared=[],
                     preprepared=[],
                     checkpoints=[])
     return vc
示例#16
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
示例#17
0
def test_calc_batches_combinations(builder, random):
    MAX_PP_SEQ_NO = 4
    MAX_VIEW_NO = 2
    MAX_DIGEST_ID = 4
    cp = Checkpoint(instId=0, viewNo=1, seqNoStart=0, seqNoEnd=0, digest=cp_digest(0))

    for i in range(200):
        for vc_count in range(N - F, N + 1):
            view_changes = []

            # 1. INIT
            for i in range(vc_count):
                # PRE-PREPARED
                num_preprepares = random.integer(0, MAX_PP_SEQ_NO)
                pre_prepares = []
                for i in range(1, num_preprepares + 1):
                    view_no = random.integer(0, MAX_VIEW_NO)
                    batch_id = (view_no, random.integer(0, view_no),
                                i, "digest{}".format(random.integer(1, MAX_DIGEST_ID)))
                    pre_prepares.append(batch_id)

                # PREPARED
                prepares_mode = random.sample(['all-preprepared', 'half-preprepared', 'random-preprepared', 'random'],
                                              1)
                if prepares_mode == ['all-preprepared']:
                    prepares = pre_prepares
                elif prepares_mode == ['half-preprepared']:
                    prepares = pre_prepares[:(num_preprepares // 2)]
                elif prepares_mode == ['random-preprepared']:
                    prepares = random.sample(pre_prepares, len(pre_prepares))
                elif prepares_mode == ['random']:
                    num_prepares = random.integer(0, MAX_PP_SEQ_NO)
                    prepares = []
                    for i in range(1, num_prepares + 1):
                        view_no = random.integer(0, MAX_VIEW_NO)
                        batch_id = (view_no, random.integer(0, view_no),
                                    i, "digest{}".format(random.integer(1, MAX_DIGEST_ID)))
                        prepares.append(batch_id)
                else:
                    assert False, str(prepares_mode)

                # CHECKPOINTS
                view_changes.append(ViewChange(
                    viewNo=MAX_VIEW_NO,
                    stableCheckpoint=0,
                    prepared=prepares,
                    preprepared=pre_prepares,
                    checkpoints=[cp]
                ))

            # 2. EXECUTE
            batches = builder.calc_batches(cp, view_changes)

            # 3. VALIDATE
            committed = calc_committed(view_changes, MAX_PP_SEQ_NO, N, F)
            if committed and batches is not None:
                assert set(committed) <= set(batches)
示例#18
0
def test_calc_batches_same_data_prev_pp_viewno(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, 0, 1, "digest1"), BatchID(1, 0, 2, "digest2")],
                    checkpoints=[cp])

    vcs = [vc, vc, vc, vc]
    assert builder.calc_batches(cp, vcs) == [BatchID(1, 0, 1, "digest1"), BatchID(1, 0, 2, "digest2")]
示例#19
0
 def _view_change(view_no: int):
     vc = ViewChange(
         viewNo=view_no,
         stableCheckpoint=4,
         prepared=[],
         preprepared=[],
         checkpoints=[Checkpoint(instId=0, viewNo=view_no, seqNoStart=0, seqNoEnd=4, digest=cp_digest(4))]
     )
     return vc
示例#20
0
def create_view_change(initial_view_no, stable_cp=10, batches=None):
    if batches is None:
        batches = create_batches(initial_view_no)
    digest = cp_digest(stable_cp)
    cp = Checkpoint(instId=0, viewNo=initial_view_no, seqNoStart=0, seqNoEnd=stable_cp, digest=digest)
    return ViewChange(viewNo=initial_view_no + 1,
                      stableCheckpoint=stable_cp,
                      prepared=batches,
                      preprepared=batches,
                      checkpoints=[cp])
def test_calc_checkpoints_equal_initial(builder):
    cp = Checkpoint(instId=0,
                    viewNo=0,
                    seqNoStart=0,
                    seqNoEnd=0,
                    digest='empty')
    vc = ViewChange(viewNo=0,
                    stableCheckpoint=0,
                    prepared=[(1, 1, "digest1")],
                    preprepared=[(1, 1, "digest1")],
                    checkpoints=[cp])
    vcs = [vc, vc, vc, vc]
    assert builder.calc_checkpoint(vcs) == cp
    def start_view_change(self):
        # TODO: Calculate
        prepared = []
        preprepared = []

        self._data.view_no += 1
        self._data.waiting_for_new_view = True

        vc = ViewChange(viewNo=self._data.view_no,
                        stableCheckpoint=self._data.stable_checkpoint,
                        prepared=prepared,
                        preprepared=preprepared,
                        checkpoints=self._data.checkpoints)
        self._network.send(vc)
示例#23
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)
def test_calc_batches_same_data(builder):
    cp = Checkpoint(instId=0,
                    viewNo=0,
                    seqNoStart=0,
                    seqNoEnd=0,
                    digest='empty')
    vc = ViewChange(viewNo=0,
                    stableCheckpoint=0,
                    prepared=[(0, 1, "digest1"), (0, 2, "digest2")],
                    preprepared=[(0, 1, "digest1"), (0, 2, "digest2")],
                    checkpoints=[cp])

    vcs = [vc, vc, vc, vc]
    assert builder.calc_batches(
        cp, vcs) == [BatchID(0, 1, "digest1"),
                     BatchID(0, 2, "digest2")]
示例#25
0
    def start_view_change(self):
        # TODO: Calculate
        prepared = []
        preprepared = []

        self._data.view_no += 1
        self._data.waiting_for_new_view = True
        self._data.primary_name = self._find_primary(self._data.validators,
                                                     self._data.view_no)

        vc = ViewChange(viewNo=self._data.view_no,
                        stableCheckpoint=self._data.stable_checkpoint,
                        prepared=prepared,
                        preprepared=preprepared,
                        checkpoints=self._data.checkpoints)
        self._network.send(vc)
def test_process_message_req_view_change(message_req_service: MessageReqService,
                                         external_bus, data: ConsensusSharedData,
                                         view_change_message: ViewChange):
    frm = "frm"
    digest = view_change_digest(view_change_message)
    message_req = MessageReq(**{
        f.MSG_TYPE.nm: VIEW_CHANGE,
        f.PARAMS.nm: {f.INST_ID.nm: data.inst_id,
                      f.DIGEST.nm: digest,
                      f.NAME.nm: frm},
    })
    data.view_change_votes.add_view_change(view_change_message, frm)
    external_bus.process_incoming(message_req, frm)
    assert len(external_bus.sent_messages) == 1

    assert external_bus.sent_messages[0] == (MessageRep(message_req.msg_type,
                                                        message_req.params,
                                                        view_change_message._asdict()),
                                             [frm])
示例#27
0
    def start_view_change(self, view_no: Optional[int] = None):
        if view_no is None:
            view_no = self._data.view_no + 1

        self._clear_old_batches(self._old_prepared)
        self._clear_old_batches(self._old_preprepared)

        for pp in self._data.prepared:
            self._old_prepared[pp.ppSeqNo] = self._batch_id(pp)
        prepared = sorted([tuple(bid) for bid in self._old_prepared.values()])

        for pp in self._data.preprepared:
            new_bid = self._batch_id(pp)
            pretenders = self._old_preprepared.get(pp.ppSeqNo, [])
            pretenders = [
                bid for bid in pretenders if bid.pp_digest != new_bid.pp_digest
            ]
            pretenders.append(new_bid)
            self._old_preprepared[pp.ppSeqNo] = pretenders
        preprepared = sorted([
            tuple(bid) for bids in self._old_preprepared.values()
            for bid in bids
        ])

        self._data.view_no = view_no
        self._data.waiting_for_new_view = True
        self._data.primary_name = self._find_primary(self._data.validators,
                                                     self._data.view_no)
        self._data.preprepared.clear()
        self._data.prepared.clear()
        self._votes.clear()
        self._new_view = None

        vc = ViewChange(viewNo=self._data.view_no,
                        stableCheckpoint=self._data.stable_checkpoint,
                        prepared=prepared,
                        preprepared=preprepared,
                        checkpoints=list(self._data.checkpoints))
        self._network.send(vc)
        self._votes.add_view_change(vc, self._data.name)

        self._router.process_all_stashed()
示例#28
0
    def _build_view_change_msg(self):
        for batch_id in self._data.prepared:
            self._old_prepared[batch_id.pp_seq_no] = batch_id
        prepared = sorted(list(self._old_prepared.values()))

        for new_bid in self._data.preprepared:
            pretenders = self._old_preprepared.get(new_bid.pp_seq_no, [])
            pretenders = [
                bid for bid in pretenders if bid.pp_digest != new_bid.pp_digest
            ]
            pretenders.append(new_bid)
            self._old_preprepared[new_bid.pp_seq_no] = pretenders
        preprepared = sorted(
            [bid for bids in self._old_preprepared.values() for bid in bids])

        return ViewChange(viewNo=self._data.view_no,
                          stableCheckpoint=self._data.stable_checkpoint,
                          prepared=prepared,
                          preprepared=preprepared,
                          checkpoints=list(self._data.checkpoints))
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 start_view_change(self, view_no: Optional[int] = None):
        if view_no is None:
            view_no = self._data.view_no + 1

        self._clear_old_batches(self._old_prepared)
        self._clear_old_batches(self._old_preprepared)

        for batch_id in self._data.prepared:
            self._old_prepared[batch_id.pp_seq_no] = batch_id
        prepared = sorted([tuple(bid) for bid in self._old_prepared.values()])

        for new_bid in self._data.preprepared:
            pretenders = self._old_preprepared.get(new_bid.pp_seq_no, [])
            pretenders = [bid for bid in pretenders
                          if bid.pp_digest != new_bid.pp_digest]
            pretenders.append(new_bid)
            self._old_preprepared[new_bid.pp_seq_no] = pretenders
        preprepared = sorted([tuple(bid) for bids in self._old_preprepared.values() for bid in bids])

        self._data.view_no = view_no
        self._data.waiting_for_new_view = True
        self._data.primary_name = self._primaries_selector.select_primaries(view_no=self._data.view_no,
                                                                            instance_count=self._data.quorums.f + 1,
                                                                            validators=self._data.validators)[0]
        self._data.preprepared.clear()
        self._data.prepared.clear()
        self._votes.clear()
        self._new_view = None

        vc = ViewChange(
            viewNo=self._data.view_no,
            stableCheckpoint=self._data.stable_checkpoint,
            prepared=prepared,
            preprepared=preprepared,
            checkpoints=list(self._data.checkpoints)
        )
        self._network.send(vc)
        self._votes.add_view_change(vc, self._data.name)

        self._router.process_all_stashed()