Example #1
0
def test_submit_vote_then_deregister(smc_handler):  # noqa: F811
    w3 = smc_handler.web3
    # We only vote in shard 0 for ease of testing
    shard_id = 0

    # Register notary 0~8 and fast forward to next period
    batch_register(smc_handler, 0, 8)
    fast_forward(smc_handler, 1)
    current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH']
    assert current_period == 1

    # Add collation record
    CHUNK_ROOT_1_0 = b'\x10' * 32
    smc_handler.add_header(
        shard_id=shard_id,
        period=current_period,
        chunk_root=CHUNK_ROOT_1_0,
        private_key=NotaryAccount(index=0).private_key,
    )
    mine(w3, 1)

    sample_index = 0
    pool_index = sampling(smc_handler, shard_id)[sample_index]
    smc_handler.submit_vote(
        shard_id=shard_id,
        period=current_period,
        chunk_root=CHUNK_ROOT_1_0,
        index=sample_index,
        private_key=NotaryAccount(index=pool_index).private_key,
    )
    mine(w3, 1)

    # Check that vote has been casted successfully
    assert smc_handler.get_vote_count(shard_id) == 1
    assert smc_handler.has_notary_voted(shard_id, sample_index)

    # The notary deregisters
    smc_handler.deregister_notary(
        private_key=NotaryAccount(pool_index).private_key)
    mine(w3, 1)
    # Check that vote was not effected by deregistration
    assert smc_handler.get_vote_count(shard_id) == 1
    assert smc_handler.has_notary_voted(shard_id, sample_index)

    # Notary 9 registers and takes retired notary's place in pool
    smc_handler.register_notary(private_key=NotaryAccount(9).private_key)
    # Attempt to vote
    tx_hash = smc_handler.submit_vote(
        shard_id=shard_id,
        period=current_period,
        chunk_root=CHUNK_ROOT_1_0,
        index=sample_index,
        private_key=NotaryAccount(index=9).private_key,
    )
    mine(w3, 1)

    # Check that transaction failed and vote count remains the same
    # and no logs has been emitted
    assert len(w3.eth.getTransactionReceipt(tx_hash)['logs']) == 0
    assert smc_handler.get_vote_count(shard_id) == 1
Example #2
0
def test_submit_vote_with_invalid_args(smc_handler, period, shard_id,
                                       chunk_root, sample_index):
    w3 = smc_handler.web3

    # Register notary 0~8 and fast forward to next period
    batch_register(smc_handler, 0, 8)
    fast_forward(smc_handler, 1)
    current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH']
    assert current_period == 1

    # Add correct collation record
    smc_handler.add_header(
        shard_id=0,
        period=current_period,
        chunk_root=b'\x10' * 32,
        private_key=NotaryAccount(index=0).private_key,
    )
    mine(w3, 1)

    pool_index = sampling(smc_handler, 0)[0]
    # Vote with provided incorrect arguments
    tx_hash = smc_handler.submit_vote(
        shard_id=shard_id,
        period=period,
        chunk_root=chunk_root,
        index=sample_index,
        private_key=NotaryAccount(index=pool_index).private_key,
    )
    mine(w3, 1)
    # Check that transaction failed and vote count remains the same
    # and no logs has been emitted
    assert len(w3.eth.getTransactionReceipt(tx_hash)['logs']) == 0
    assert smc_handler.get_vote_count(shard_id) == 0
    assert not smc_handler.has_notary_voted(shard_id, sample_index)
Example #3
0
def test_submit_vote_without_add_header_first(smc_handler):  # noqa: F811
    w3 = smc_handler.web3
    # We only vote in shard 0 for ease of testing
    shard_id = 0

    # Register notary 0~8 and fast forward to next period
    batch_register(smc_handler, 0, 8)
    fast_forward(smc_handler, 1)
    current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH']
    assert current_period == 1

    CHUNK_ROOT_1_0 = b'\x10' * 32
    # Get the first notary in the sample list in this period and vote
    sample_index = 0
    pool_index = sampling(smc_handler, shard_id)[sample_index]
    tx_hash = smc_handler.submit_vote(
        shard_id=shard_id,
        period=current_period,
        chunk_root=CHUNK_ROOT_1_0,
        index=sample_index,
        private_key=NotaryAccount(index=pool_index).private_key,
    )
    mine(w3, 1)
    # Check that transaction failed and vote count remains the same
    # and no logs has been emitted
    assert len(w3.eth.getTransactionReceipt(tx_hash)['logs']) == 0
    assert smc_handler.get_vote_count(shard_id) == 0
    assert not smc_handler.has_notary_voted(shard_id, sample_index)
Example #4
0
def test_submit_vote_by_non_eligible_notary(smc_handler):  # noqa: F811
    w3 = smc_handler.web3
    # We only vote in shard 0 for ease of testing
    shard_id = 0

    # Register notary 0~8 and fast forward to next period
    batch_register(smc_handler, 0, 8)
    fast_forward(smc_handler, 1)
    current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH']
    assert current_period == 1

    # Add collation record
    CHUNK_ROOT_1_0 = b'\x10' * 32
    smc_handler.add_header(
        shard_id=shard_id,
        period=current_period,
        chunk_root=CHUNK_ROOT_1_0,
        private_key=NotaryAccount(index=0).private_key,
    )
    mine(w3, 1)

    sample_index = 0
    pool_index = sampling(smc_handler, shard_id)[sample_index]
    wrong_pool_index = 0 if pool_index != 0 else 1
    tx_hash = smc_handler.submit_vote(
        shard_id=shard_id,
        period=current_period,
        chunk_root=CHUNK_ROOT_1_0,
        index=sample_index,
        # Vote by non-eligible notary
        private_key=NotaryAccount(wrong_pool_index).private_key,
    )
    mine(w3, 1)
    # Check that transaction failed and vote count remains the same
    # and no logs has been emitted
    assert len(w3.eth.getTransactionReceipt(tx_hash)['logs']) == 0
    assert smc_handler.get_vote_count(shard_id) == 0
    assert not smc_handler.has_notary_voted(shard_id, sample_index)
Example #5
0
def test_status_checking_functions(smc_handler,
                                   smc_testing_config):  # noqa: F811
    w3 = smc_handler.web3
    config = smc_testing_config
    shard_tracker = ShardTracker(
        w3=w3,
        config=config,
        shard_id=0,
        smc_handler_address=smc_handler.address,
    )

    # Register nine notaries
    batch_register(smc_handler, 0, 8)
    # Check that registration log was/was not emitted accordingly
    assert shard_tracker.is_notary_registered(
        notary=NotaryAccount(0).checksum_address)
    assert shard_tracker.is_notary_registered(
        notary=NotaryAccount(5).checksum_address)
    assert not shard_tracker.is_notary_registered(
        notary=NotaryAccount(9).checksum_address)
    fast_forward(smc_handler, 1)

    # Check that add header log has not been emitted yet
    current_period = w3.eth.blockNumber // config['PERIOD_LENGTH']
    assert not shard_tracker.is_new_header_added(period=current_period)
    # Add header in multiple shards
    CHUNK_ROOT_1_0 = b'\x10' * 32
    smc_handler.add_header(
        shard_id=0,
        period=current_period,
        chunk_root=CHUNK_ROOT_1_0,
        private_key=NotaryAccount(0).private_key,
    )
    CHUNK_ROOT_1_7 = b'\x17' * 32
    smc_handler.add_header(
        shard_id=7,
        period=current_period,
        chunk_root=CHUNK_ROOT_1_7,
        private_key=NotaryAccount(7).private_key,
    )
    CHUNK_ROOT_1_3 = b'\x13' * 32
    smc_handler.add_header(
        shard_id=3,
        period=current_period,
        chunk_root=CHUNK_ROOT_1_3,
        private_key=NotaryAccount(3).private_key,
    )
    mine(w3, 1)
    # Check that add header log was successfully emitted
    assert shard_tracker.is_new_header_added(period=current_period)

    # Check that there has not been enough votes yet in shard 0
    assert not shard_tracker.has_enough_vote(period=current_period)
    # Submit three votes in shard 0 and one vote in shard 7
    for sample_index in range(3):
        pool_index = sampling(smc_handler, 0)[sample_index]
        smc_handler.submit_vote(
            shard_id=0,
            period=current_period,
            chunk_root=CHUNK_ROOT_1_0,
            index=sample_index,
            private_key=NotaryAccount(pool_index).private_key,
        )
        mine(w3, 1)
    sample_index = 0
    pool_index = sampling(smc_handler, 7)[sample_index]
    smc_handler.submit_vote(
        shard_id=7,
        period=current_period,
        chunk_root=CHUNK_ROOT_1_7,
        index=sample_index,
        private_key=NotaryAccount(pool_index).private_key,
    )
    mine(w3, 1)
    # Check that there has not been enough votes yet in shard 0
    # Only three votes in shard 0 while four is required
    assert not shard_tracker.has_enough_vote(period=current_period)
    # Cast the fourth vote
    sample_index = 3
    pool_index = sampling(smc_handler, 0)[sample_index]
    smc_handler.submit_vote(
        shard_id=0,
        period=current_period,
        chunk_root=CHUNK_ROOT_1_0,
        index=sample_index,
        private_key=NotaryAccount(pool_index).private_key,
    )
    mine(w3, 1)
    # Check that there are enough votes now in shard 0
    assert shard_tracker.has_enough_vote(period=current_period)
    # Proceed to next period
    fast_forward(smc_handler, 1)

    # Go back and check the status of header and vote counts in last period
    current_period = w3.eth.blockNumber // config['PERIOD_LENGTH']
    assert shard_tracker.is_new_header_added(period=(current_period - 1))
    assert shard_tracker.has_enough_vote(period=(current_period - 1))

    # Deregister
    smc_handler.deregister_notary(private_key=NotaryAccount(0).private_key)
    mine(w3, 1)
    # Check that deregistration log was/was not emitted accordingly
    assert shard_tracker.is_notary_deregistered(
        NotaryAccount(0).checksum_address)
    assert not shard_tracker.is_notary_deregistered(
        NotaryAccount(5).checksum_address)

    # Fast foward to end of lock up
    fast_forward(smc_handler, smc_handler.config['NOTARY_LOCKUP_LENGTH'] + 1)
    # Release
    smc_handler.release_notary(private_key=NotaryAccount(0).private_key)
    mine(w3, 1)
    # Check that log was successfully emitted
    assert shard_tracker.is_notary_released(NotaryAccount(0).checksum_address)
Example #6
0
def test_log_emission(smc_handler):  # noqa: F811
    w3 = smc_handler.web3
    log_handler = LogHandler(w3, smc_handler.config['PERIOD_LENGTH'])
    shard_tracker = ShardTracker(
        config=smc_handler.config,
        shard_id=0,
        log_handler=log_handler,
        smc_handler_address=smc_handler.address,
    )
    notary = NotaryAccount(0)

    # Register
    smc_handler.register_notary(private_key=notary.private_key)
    mine(w3, 1)
    # Check that log was successfully emitted
    log = shard_tracker.get_register_notary_logs()[0]
    assert getattr(log, 'index_in_notary_pool') == 0 and \
        getattr(log, 'notary') == notary.checksum_address
    fast_forward(smc_handler, 1)

    # Add header
    CHUNK_ROOT_1_0 = b'\x10' * 32
    smc_handler.add_header(
        shard_id=0,
        period=1,
        chunk_root=CHUNK_ROOT_1_0,
        private_key=notary.private_key,
    )
    mine(w3, 1)
    # Check that log was successfully emitted
    log = shard_tracker.get_add_header_logs()[0]
    assert getattr(log, 'period') == 1 and getattr(log, 'shard_id') == 0 and \
        getattr(log, 'chunk_root') == CHUNK_ROOT_1_0

    # Submit vote
    sample_index = 0
    pool_index = sampling(smc_handler, 0)[sample_index]
    smc_handler.submit_vote(
        shard_id=0,
        period=1,
        chunk_root=CHUNK_ROOT_1_0,
        index=sample_index,
        private_key=NotaryAccount(pool_index).private_key,
    )
    mine(w3, 1)
    # Check that log was successfully emitted
    log = shard_tracker.get_submit_vote_logs()[0]
    assert getattr(log, 'period') == 1 and getattr(log, 'shard_id') == 0 and \
        getattr(log, 'chunk_root') == CHUNK_ROOT_1_0 and \
        getattr(log, 'notary') == NotaryAccount(pool_index).checksum_address
    fast_forward(smc_handler, 1)

    # Deregister
    smc_handler.deregister_notary(private_key=notary.private_key)
    mine(w3, 1)
    # Check that log was successfully emitted
    log = shard_tracker.get_deregister_notary_logs()[0]
    assert getattr(log, 'index_in_notary_pool') == 0 and \
        getattr(log, 'notary') == notary.checksum_address and \
        getattr(log, 'deregistered_period') == 2
    # Fast foward to end of lock up
    fast_forward(smc_handler, smc_handler.config['NOTARY_LOCKUP_LENGTH'] + 1)

    # Release
    smc_handler.release_notary(private_key=notary.private_key)
    mine(w3, 1)
    # Check that log was successfully emitted
    log = shard_tracker.get_release_notary_logs()[0]
    assert getattr(log, 'index_in_notary_pool') == 0 and \
        getattr(log, 'notary') == notary.checksum_address

    # Test fetching logs in past period
    assert shard_tracker.get_register_notary_logs(from_period=0, to_period=0)
    assert shard_tracker.get_add_header_logs(from_period=1, to_period=1)
    assert shard_tracker.get_submit_vote_logs(from_period=1, to_period=1)
    assert shard_tracker.get_deregister_notary_logs(from_period=2, to_period=2)
    assert shard_tracker.get_release_notary_logs(
        from_period=(3 + smc_handler.config['NOTARY_LOCKUP_LENGTH']),
        to_period=(3 + smc_handler.config['NOTARY_LOCKUP_LENGTH'])
    )
Example #7
0
def test_normal_submit_vote(smc_handler):  # noqa: F811
    w3 = smc_handler.web3
    # We only vote in shard 0 for ease of testing
    shard_id = 0

    # Register notary 0~8 and fast forward to next period
    batch_register(smc_handler, 0, 8)
    fast_forward(smc_handler, 1)
    current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH']
    assert current_period == 1

    # Add collation record
    CHUNK_ROOT_1_0 = b'\x10' * 32
    smc_handler.add_header(
        shard_id=shard_id,
        period=current_period,
        chunk_root=CHUNK_ROOT_1_0,
        private_key=NotaryAccount(index=0).private_key,
    )
    mine(w3, 1)

    # Get the first notary in the sample list in this period
    sample_index = 0
    pool_index = sampling(smc_handler, shard_id)[sample_index]
    # Check that voting record does not exist prior to voting
    assert smc_handler.get_vote_count(shard_id) == 0
    assert not smc_handler.has_notary_voted(shard_id, sample_index)
    # First notary vote
    smc_handler.submit_vote(
        shard_id=shard_id,
        period=current_period,
        chunk_root=CHUNK_ROOT_1_0,
        index=sample_index,
        private_key=NotaryAccount(index=pool_index).private_key,
    )
    mine(w3, 1)
    # Check that vote has been casted successfully
    assert smc_handler.get_vote_count(shard_id) == 1
    assert smc_handler.has_notary_voted(shard_id, sample_index)

    # Check that collation is not elected and forward to next period
    assert not smc_handler.get_collation_is_elected(shard_id=shard_id,
                                                    period=current_period)
    fast_forward(smc_handler, 1)
    current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH']
    assert current_period == 2

    # Add collation record
    CHUNK_ROOT_2_0 = b'\x20' * 32
    smc_handler.add_header(
        shard_id=shard_id,
        period=current_period,
        chunk_root=CHUNK_ROOT_2_0,
        private_key=NotaryAccount(index=0).private_key,
    )
    mine(w3, 1)

    # Check that vote count is zero
    assert smc_handler.get_vote_count(shard_id) == 0
    # Keep voting until the collation is elected.
    for (sample_index,
         pool_index) in enumerate(sampling(smc_handler, shard_id)):
        if smc_handler.get_collation_is_elected(shard_id=shard_id,
                                                period=current_period):
            assert smc_handler.get_vote_count(
                shard_id) == smc_handler.config['QUORUM_SIZE']
            break
        # Check that voting record does not exist prior to voting
        assert not smc_handler.has_notary_voted(shard_id, sample_index)
        # Vote
        smc_handler.submit_vote(
            shard_id=shard_id,
            period=current_period,
            chunk_root=CHUNK_ROOT_2_0,
            index=sample_index,
            private_key=NotaryAccount(index=pool_index).private_key,
        )
        mine(w3, 1)
        # Check that vote has been casted successfully
        assert smc_handler.has_notary_voted(shard_id, sample_index)
    # Check that the collation is indeed elected.
    assert smc_handler.get_collation_is_elected(shard_id=shard_id,
                                                period=current_period)