def test_updates_shared_data_on_need_view_change(internal_bus,
                                                 view_change_service,
                                                 initial_view_no, is_master):
    old_primary = view_change_service._data.primary_name
    old_primaries = view_change_service._data.primaries
    old_data = copy_shared_data(view_change_service._data)
    internal_bus.send(NeedViewChange())

    assert view_change_service._data.view_no == initial_view_no + 1
    assert view_change_service._data.waiting_for_new_view
    assert view_change_service._data.primary_name != old_primary
    assert view_change_service._data.primaries != old_primaries
    new_data = copy_shared_data(view_change_service._data)
    check_service_changed_only_owned_fields_in_shared_data(
        ViewChangeService, old_data, new_data)

    old_primary = view_change_service._data.primary_name
    old_primaries = view_change_service._data.primaries
    old_data = copy_shared_data(view_change_service._data)
    internal_bus.send(NeedViewChange(view_no=initial_view_no + 3))

    assert view_change_service._data.view_no == initial_view_no + 3
    assert view_change_service._data.waiting_for_new_view
    assert view_change_service._data.primary_name != old_primary
    assert view_change_service._data.primaries != old_primaries
    new_data = copy_shared_data(view_change_service._data)
    check_service_changed_only_owned_fields_in_shared_data(
        ViewChangeService, old_data, new_data)
def test_update_shared_data_on_new_view_accepted_no_batches(
        internal_bus, view_change_service, is_master):
    # TODO: Need to decide on how we handle this case
    if not is_master:
        return

    view_change_service._data.waiting_for_new_view = False
    view_change_service._data.view_no = 1
    view_change_service._data.primary_name = "Alpha"
    view_change_service._data.primaries = ["Alpha", "Beta"]
    view_change_service._data.prev_view_prepare_cert = 1
    old_data = copy_shared_data(view_change_service._data)

    new_view = create_new_view(initial_view_no=3, stable_cp=200, batches=[])
    internal_bus.send(
        NewViewAccepted(view_no=4,
                        view_changes=new_view.viewChanges,
                        checkpoint=new_view.checkpoint,
                        batches=new_view.batches))

    new_data = copy_shared_data(view_change_service._data)
    # For now prev_view_prepare_cert is set on finish_view_change stage
    assert view_change_service._data.prev_view_prepare_cert == 1
    check_service_changed_only_owned_fields_in_shared_data(
        ViewChangeService, old_data, new_data)
예제 #3
0
def test_update_shared_data_on_new_view_accepted(internal_bus,
                                                 checkpoint_service,
                                                 checkpoints,
                                                 stable_checkpoint,
                                                 checkpoints_result):
    old_data = copy_shared_data(checkpoint_service._data)
    checkpoint_service._data.checkpoints.update(checkpoints)
    checkpoint_service._data.stable_checkpoint = stable_checkpoint
    checkpoint_service._data.low_watermark = stable_checkpoint
    checkpoint_service._data.high_watermark = checkpoint_service._data.low_watermark + 300

    initial_view_no = 3
    new_view = create_new_view(initial_view_no=initial_view_no, stable_cp=200)
    internal_bus.send(
        NewViewAccepted(view_no=initial_view_no + 1,
                        view_changes=new_view.viewChanges,
                        checkpoint=new_view.checkpoint,
                        batches=new_view.batches))

    new_data = copy_shared_data(checkpoint_service._data)
    check_service_changed_only_owned_fields_in_shared_data(
        CheckpointService, old_data, new_data)

    assert list(checkpoint_service._data.checkpoints) == checkpoints_result
    assert checkpoint_service._data.stable_checkpoint == 200
    assert checkpoint_service._data.low_watermark == 200
    assert checkpoint_service._data.high_watermark == checkpoint_service._data.low_watermark + 300
def test_update_shared_data_on_new_view_accepted(internal_bus, checkpoint_service,
                                                 checkpoints, stable_checkpoint,
                                                 checkpoints_result, stable_cp_result, is_master):
    # TODO: Need to decide on how we handle this case
    if not is_master:
        return

    old_data = copy_shared_data(checkpoint_service._data)
    checkpoint_service._data.checkpoints.clear()
    checkpoint_service._data.checkpoints.update(checkpoints)
    checkpoint_service._data.stable_checkpoint = stable_checkpoint
    checkpoint_service._data.low_watermark = stable_checkpoint
    checkpoint_service._data.high_watermark = checkpoint_service._data.low_watermark + 300

    initial_view_no = 3
    new_view = create_new_view(initial_view_no=initial_view_no, stable_cp=200)
    internal_bus.send(NewViewAccepted(view_no=initial_view_no + 1,
                                      view_changes=new_view.viewChanges,
                                      checkpoint=new_view.checkpoint,
                                      batches=new_view.batches))

    new_data = copy_shared_data(checkpoint_service._data)
    check_service_changed_only_owned_fields_in_shared_data(CheckpointService, old_data, new_data)

    assert list(checkpoint_service._data.checkpoints) == checkpoints_result
    assert checkpoint_service._data.stable_checkpoint == stable_cp_result
    assert checkpoint_service._data.low_watermark == stable_cp_result
    assert checkpoint_service._data.high_watermark == checkpoint_service._data.low_watermark + 300
예제 #5
0
def test_update_shared_data_on_mew_view_checkpoint_applied(internal_bus, orderer):
    orderer._data.preprepared = []
    orderer._data.prepared = []
    old_data = copy_shared_data(orderer._data)

    initial_view_no = 3
    new_view = create_new_view(initial_view_no=initial_view_no, stable_cp=200)
    internal_bus.send(NewViewCheckpointsApplied(view_no=initial_view_no + 1,
                                                view_changes=new_view.viewChanges,
                                                checkpoint=new_view.checkpoint,
                                                batches=new_view.batches))

    new_data = copy_shared_data(orderer._data)
    check_service_changed_only_owned_fields_in_shared_data(OrderingService, old_data, new_data)

    # preprepared are created for new view
    if orderer.is_master:
        assert orderer._data.preprepared
        assert orderer._data.preprepared == [BatchID(view_no=initial_view_no + 1, pp_seq_no=batch_id.pp_seq_no,
                                                     pp_digest=batch_id.pp_digest)
                                             for batch_id in new_view.batches]
        assert orderer._data.prepared == []
    else:
        assert orderer._data.preprepared == []
        assert orderer._data.prepared == []
def test_updates_shared_data_on_need_view_change(internal_bus, view_change_service, initial_view_no, is_master):
    old_primary = view_change_service._data.primary_name
    old_data = copy_shared_data(view_change_service._data)
    internal_bus.send(NeedViewChange())

    assert view_change_service._data.view_no == initial_view_no + 1
    assert view_change_service._data.waiting_for_new_view
    if not is_master:
        assert view_change_service._data.master_reordered_after_vc == False
        assert view_change_service._data.primary_name is None
    else:
        assert view_change_service._data.primary_name != old_primary
    new_data = copy_shared_data(view_change_service._data)
    check_service_changed_only_owned_fields_in_shared_data(ViewChangeService, old_data, new_data)

    old_primary = view_change_service._data.primary_name
    old_data = copy_shared_data(view_change_service._data)
    internal_bus.send(NeedViewChange(view_no=initial_view_no + 3))

    assert view_change_service._data.view_no == initial_view_no + 3
    assert view_change_service._data.waiting_for_new_view
    if not is_master:
        assert view_change_service._data.master_reordered_after_vc == False
        assert view_change_service._data.primary_name is None
    else:
        assert view_change_service._data.primary_name != old_primary
    new_data = copy_shared_data(view_change_service._data)
    check_service_changed_only_owned_fields_in_shared_data(ViewChangeService, old_data, new_data)
def test_view_change_finished_is_sent_by_non_primary_once_view_change_certificate_is_reached_and_new_view_from_primary(
        internal_bus, external_bus, validators, primary,
        view_change_service_builder, initial_view_no, some_item, is_master):
    # TODO: Need to decide on how we handle this case
    if not is_master:
        return

    handler = Mock()
    internal_bus.subscribe(NewViewAccepted, handler)

    next_view_no = initial_view_no + 1
    primary_name = primary(next_view_no)
    non_primary_name = some_item(validators, exclude=[primary_name])
    service = view_change_service_builder(non_primary_name)
    vc = create_view_change(initial_view_no)
    service._data.preprepared = vc.preprepared
    service._data.prepared = vc.prepared
    service._data.stable_checkpoint = vc.stableCheckpoint
    service._data.checkpoints = vc.checkpoints
    old_data = copy_shared_data(service._data)

    # start view change
    internal_bus.send(NeedViewChange())
    external_bus.sent_messages.clear()

    # receive quorum of ViewChanges and ViewChangeAcks
    non_primaries = [item for item in validators if item != primary_name]
    non_primaries = random.sample(non_primaries,
                                  service._data.quorums.view_change.value)
    new_view = create_new_view_from_vc(vc, non_primaries)
    for vc_frm in non_primaries:
        external_bus.process_incoming(
            vc, generateName(vc_frm, service._data.inst_id))
        for ack, ack_frm in create_view_change_acks(vc, vc_frm, non_primaries):
            external_bus.process_incoming(
                ack, generateName(ack_frm, service._data.inst_id))

        # check that NewViewAccepted hasn't been sent if NewView is from non-primary
        external_bus.process_incoming(
            new_view, generateName(non_primary_name, service._data.inst_id))
    handler.assert_not_called()
    assert service._data.view_no == initial_view_no + 1
    assert service._data.waiting_for_new_view

    # check that NewViewAccepted has been sent if NewView is from primary
    external_bus.process_incoming(
        new_view, generateName(primary_name, service._data.inst_id))
    expected_finish_vc = NewViewAccepted(view_no=initial_view_no + 1,
                                         view_changes=new_view.viewChanges,
                                         checkpoint=new_view.checkpoint,
                                         batches=new_view.batches)
    handler.assert_called_with(expected_finish_vc)

    # check that shared data is updated
    new_data = copy_shared_data(service._data)
    check_service_changed_only_owned_fields_in_shared_data(
        ViewChangeService, old_data, new_data)
    assert service._data.view_no == initial_view_no + 1
    assert not service._data.waiting_for_new_view
def test_do_nothing_on_view_change_started(internal_bus, view_change_service):
    view_change_service._data.waiting_for_new_view = False
    view_change_service._data.view_no = 1
    view_change_service._data.primary_name = "Alpha"
    view_change_service._data.primaries = ["Alpha", "Beta"]
    old_data = copy_shared_data(view_change_service._data)

    internal_bus.send(ViewChangeStarted(view_no=4))

    new_data = copy_shared_data(view_change_service._data)
    assert old_data == new_data
예제 #9
0
def test_do_nothing_on_view_change_started(internal_bus, checkpoint_service):
    checkpoint_service._data.checkpoints.update(create_checkpoints(view_no=0))
    checkpoint_service._data.stable_checkpoint = 200
    checkpoint_service._data.low_watermark = 200
    checkpoint_service._data.high_watermark = checkpoint_service._data.low_watermark + 300
    old_data = copy_shared_data(checkpoint_service._data)

    internal_bus.send(ViewChangeStarted(view_no=4))

    new_data = copy_shared_data(checkpoint_service._data)
    assert old_data == new_data
예제 #10
0
def test_update_shared_data_on_view_change_started(internal_bus, orderer):
    orderer._data.preprepared = create_batches(view_no=3)
    orderer._data.prepared = create_batches(view_no=3)
    old_data = copy_shared_data(orderer._data)

    internal_bus.send(ViewChangeStarted(view_no=4))

    new_data = copy_shared_data(orderer._data)
    check_service_changed_only_owned_fields_in_shared_data(OrderingService, old_data, new_data)
    assert orderer._data.preprepared == []
    assert orderer._data.prepared == []
예제 #11
0
def test_do_nothing_on_new_view_accepted(internal_bus, orderer):
    orderer._data.preprepared = create_batches(view_no=0)
    orderer._data.prepared = create_batches(view_no=0)
    old_data = copy_shared_data(orderer._data)

    initial_view_no = 3
    new_view = create_new_view(initial_view_no=initial_view_no, stable_cp=200)
    internal_bus.send(NewViewAccepted(view_no=initial_view_no + 1,
                                      view_changes=new_view.viewChanges,
                                      checkpoint=new_view.checkpoint,
                                      batches=new_view.batches))

    new_data = copy_shared_data(orderer._data)
    assert old_data == new_data
예제 #12
0
def test_do_nothing_on_new_view_checkpoint_applied(internal_bus, view_change_service):
    view_change_service._data.waiting_for_new_view = False
    view_change_service._data.view_no = 1
    view_change_service._data.primary_name = "Alpha"
    view_change_service._data.primaries = ["Alpha", "Beta"]
    old_data = copy_shared_data(view_change_service._data)

    new_view = create_new_view(initial_view_no=3, stable_cp=200)
    internal_bus.send(NewViewCheckpointsApplied(view_no=4,
                                                view_changes=new_view.viewChanges,
                                                checkpoint=new_view.checkpoint,
                                                batches=new_view.batches))

    new_data = copy_shared_data(view_change_service._data)
    assert old_data == new_data
def test_do_nothing_on_new_view_checkpoint_applied(internal_bus, checkpoint_service):
    checkpoint_service._data.checkpoints.clear()
    checkpoint_service._data.checkpoints.update(create_checkpoints(view_no=0))
    checkpoint_service._data.stable_checkpoint = 100
    checkpoint_service._data.low_watermark = 100
    checkpoint_service._data.high_watermark = checkpoint_service._data.low_watermark + 300
    old_data = copy_shared_data(checkpoint_service._data)

    initial_view_no = 3
    new_view = create_new_view(initial_view_no=initial_view_no, stable_cp=200)
    internal_bus.send(NewViewCheckpointsApplied(view_no=initial_view_no + 1,
                                                view_changes=new_view.viewChanges,
                                                checkpoint=new_view.checkpoint,
                                                batches=new_view.batches))

    new_data = copy_shared_data(checkpoint_service._data)
    assert old_data == new_data
def test_view_change_finished_is_sent_by_primary_once_view_change_certificate_is_reached(
        internal_bus, validators, primary, view_change_service_builder,
        initial_view_no):
    handler = Mock()
    internal_bus.subscribe(NewViewAccepted, handler)

    primary_name = primary(initial_view_no + 1)
    service = view_change_service_builder(primary_name)

    # start view change
    internal_bus.send(NeedViewChange())
    service._network.sent_messages.clear()
    old_data = copy_shared_data(service._data)

    # receive quorum of ViewChanges and ViewChangeAcks
    non_primaries = [item for item in validators if item != primary_name]
    non_primaries = random.sample(non_primaries,
                                  service._data.quorums.view_change.value)
    vc = create_view_change(initial_view_no)
    new_view = create_new_view_from_vc(vc, non_primaries)
    for vc_frm in non_primaries:
        service._network.process_incoming(vc, vc_frm)
        for ack, ack_frm in create_view_change_acks(vc, vc_frm, non_primaries):
            service._network.process_incoming(ack, ack_frm)

    # check that NewViewAccepted has been sent
    expected_finish_vc = NewViewAccepted(view_no=initial_view_no + 1,
                                         view_changes=new_view.viewChanges,
                                         checkpoint=new_view.checkpoint,
                                         batches=new_view.batches)
    handler.assert_called_with(expected_finish_vc)

    # check that shared data is updated
    new_data = copy_shared_data(service._data)
    check_service_changed_only_owned_fields_in_shared_data(
        ViewChangeService, old_data, new_data)
    assert service._data.view_no == initial_view_no + 1
    assert not service._data.waiting_for_new_view
def test_update_shared_data_on_new_view_checkpoint_applied(
        internal_bus, orderer):
    initial_view_no = 3
    orderer._data.preprepared = []
    orderer._data.prepared = []
    orderer._data.view_no = initial_view_no + 1
    old_data = copy_shared_data(orderer._data)

    new_view = create_new_view(initial_view_no=initial_view_no, stable_cp=200)
    internal_bus.send(
        NewViewCheckpointsApplied(view_no=initial_view_no + 1,
                                  view_changes=new_view.viewChanges,
                                  checkpoint=new_view.checkpoint,
                                  batches=new_view.batches))

    new_data = copy_shared_data(orderer._data)
    check_service_changed_only_owned_fields_in_shared_data(
        OrderingService, old_data, new_data)

    # Since we didn't order the PrePrepare from Batches, it should not be added into shared data
    # (we will request the PrePrepares instead, see next tests)
    assert orderer._data.preprepared == []
    assert orderer._data.prepared == []