def test_retrieve_multiple_blocks_by_proposer_and_step(empty_db):
    proposer_privkey = random_private_key()
    proposer = proposer_privkey.public_key.to_canonical_address()
    step = random_step()

    block_one = make_block(proposer_privkey=proposer_privkey, step=step)
    empty_db.insert(block_one)

    block_two = make_block(proposer_privkey=proposer_privkey, step=step)
    empty_db.insert(block_two)

    retrieved_blocks = empty_db.get_blocks_by_proposer_and_step(proposer, step)

    assert len(retrieved_blocks) == 2

    retrieved_block_one, retrieved_block_two = retrieved_blocks

    assert retrieved_block_one.hash == block_one.hash
    assert retrieved_block_two.hash == block_two.hash

    assert retrieved_block_one.proposer == proposer
    assert retrieved_block_two.proposer == proposer

    assert retrieved_block_one.step == step
    assert retrieved_block_two.step == step
def test_report_equivocation(
    number_of_blocks,
    block_proposer_one_privkey,
    report_callback,
    equivocation_reporter_with_callback,
    empty_db,
):
    step = 1
    proposed_block_hashes = []

    for _ in range(0, number_of_blocks):
        block = make_block(proposer_privkey=block_proposer_one_privkey, step=step)
        empty_db.insert(block)
        equivocation_reporter_with_callback(block)
        proposed_block_hashes.append(bytes(block.hash))

    assert number_of_blocks - 1 == report_callback.call_count

    for call in report_callback.call_args_list:
        args, _ = call  # Only the *args are of interest.
        retrieved_block_hashes = args[
            0
        ]  # The first and only argument is the list of block hashes.

        for block_hash in retrieved_block_hashes:
            assert block_hash in proposed_block_hashes
def test_report_no_equivocation_for_two_different_validators(
    block_proposer_one_privkey,
    block_proposer_two_privkey,
    report_callback,
    equivocation_reporter_with_callback,
    empty_db,
):
    step = 1

    block_one = make_block(proposer_privkey=block_proposer_one_privkey, step=step)
    block_two = make_block(proposer_privkey=block_proposer_two_privkey, step=step)

    empty_db.insert(block_one)
    empty_db.insert(block_two)

    equivocation_reporter_with_callback(block_one)
    equivocation_reporter_with_callback(block_two)

    report_callback.assert_not_called()
def test_report_no_equivocation_for_a_single_branch(
    branch_length,
    block_proposer_one_privkey,
    report_callback,
    equivocation_reporter_with_callback,
    empty_db,
):
    for step in range(1, branch_length):
        block = make_block(proposer_privkey=block_proposer_one_privkey, step=step)
        empty_db.insert(block)
        equivocation_reporter_with_callback(block)

    report_callback.assert_not_called()
def test_does_not_contain_not_inserted_block(populated_db):
    for block in [make_block() for _ in range(3)]:
        assert not populated_db.contains(block.hash)
def test_insert_block(populated_db):
    block = make_block()
    populated_db.insert(block)
    assert populated_db.contains(block.hash)
def inserted_blocks():
    return [make_block() for _ in range(3)]