def check_view_change_completes_under_normal_conditions(random: SimRandom):
    pool = SimPool(4, random)
    for node in pool.nodes:
        node._view_changer.start_view_change()

    for node in pool.nodes:
        pool.timer.wait_for(lambda: not node._data.waiting_for_new_view)
예제 #2
0
def check_view_change_completes_under_normal_conditions(random: SimRandom):
    pool_size = random.integer(4, 8)
    pool = SimPool(pool_size, random)

    view_nos = {node._data.view_no for node in pool.nodes}
    assert len(view_nos) == 1
    initial_view_no = view_nos.pop()

    # Schedule view change at different time on all nodes
    for node in pool.nodes:
        pool.timer.schedule(random.integer(0, 10000),
                            node._view_changer.start_view_change)

    # Make sure all nodes complete view change
    pool.timer.wait_for(lambda: all(not node._data.waiting_for_new_view and
                                    node._data.view_no > initial_view_no
                                    for node in pool.nodes))

    # Make sure all nodes end up in same state
    for node_a, node_b in zip(pool.nodes, pool.nodes[1:]):
        assert node_a._data.view_no == node_b._data.view_no
        assert node_a._data.primary_name == node_b._data.primary_name
        assert node_a._data.preprepared == node_b._data.preprepared
예제 #3
0
def create_pool(random):
    pool_size = random.integer(4, 8)
    pool = SimPool(pool_size, random)
    return pool
예제 #4
0
def some_pool(random: SimRandom) -> (SimPool, List):
    pool_size = random.integer(4, 8)
    pool = SimPool(pool_size, random)
    view_no = pool._initial_view_no
    log_size = pool.nodes[0].config.LOG_SIZE

    # Create simulated history
    # TODO: Move into helper?
    faulty = (pool_size - 1) // 3
    seq_no_per_cp = 10
    max_batches = 50
    batches = [
        BatchID(view_no, view_no, n, random.string(40))
        for n in range(1, max_batches)
    ]
    checkpoints = [
        some_checkpoint(random, view_no, n)
        for n in range(0, max_batches, seq_no_per_cp)
    ]

    # Preprepares
    pp_count = [random.integer(0, len(batches)) for _ in range(pool_size)]
    max_pp = sorted(pp_count)[faulty]
    # Prepares
    p_count = [random.integer(0, min(max_pp, pp)) for pp in pp_count]
    max_p = sorted(p_count)[faulty]
    # Checkpoints
    cp_count = [
        1 + random.integer(0, min(max_p, p)) // seq_no_per_cp for p in pp_count
    ]
    max_stable_cp_indx = sorted(cp_count)[faulty]
    stable_cp = [
        checkpoints[random.integer(0,
                                   min(max_stable_cp_indx, cp) - 1)].seqNoEnd
        for cp in cp_count
    ]

    # Initialize consensus data
    for i, node in enumerate(pool.nodes):
        high_watermark = stable_cp[i] + log_size
        node._data.preprepared = batches[:min(high_watermark, pp_count[i])]
        node._data.prepared = batches[:min(high_watermark, p_count[i])]
        node._data.checkpoints.clear()
        node._data.checkpoints.update(checkpoints[:cp_count[i]])
        node._data.stable_checkpoint = stable_cp[i]

    # Mock Ordering service to update preprepares for new view
    for node in pool.nodes:

        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

        node._orderer._subscription.subscribe(
            node._orderer._stasher, NewViewCheckpointsApplied,
            partial(update_shared_data, node))

    committed = []
    for i in range(1, max_batches):
        prepare_count = sum(1 for node in pool.nodes
                            if i <= len(node._data.prepared))
        has_prepared_cert = prepare_count >= pool_size - faulty
        if has_prepared_cert:
            batch_id = batches[i - 1]
            committed.append(
                BatchID(batch_id.view_no + 1, batch_id.pp_view_no,
                        batch_id.pp_seq_no, batch_id.pp_digest))

    return pool, committed