示例#1
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)
示例#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)
示例#3
0
def test_deregister_then_register(smc_handler):  # noqa: F811
    w3 = smc_handler.web3

    notary_0 = NotaryAccount(0)

    # Register notary 0 and fast forward to next period
    smc_handler.register_notary(private_key=notary_0.private_key)
    fast_forward(smc_handler, 1)

    # Deregister notary 0 first
    # NOTE: Deregistration would also invoke update_notary_sample_size function
    smc_handler.deregister_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    # Check that current_period_notary_sample_size is updated
    current_period_notary_sample_size = smc_handler.current_period_notary_sample_size(
    )
    assert current_period_notary_sample_size == 1

    notary_1 = NotaryAccount(1)

    # Then register notary 1
    smc_handler.register_notary(private_key=notary_1.private_key)
    mine(w3, 1)

    _, notary_1_pool_index = smc_handler.get_notary_info(
        notary_1.checksum_address)
    assert notary_1_pool_index == 0
    # Check that next_period_notary_sample_size remains the same
    next_period_notary_sample_size = smc_handler.next_period_notary_sample_size(
    )
    assert (notary_1_pool_index + 1) == next_period_notary_sample_size
示例#4
0
def test_committee_change_with_deregister_then_register(
        smc_handler):  # noqa: F811
    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)

    # Update notary sample size
    update_notary_sample_size(smc_handler)

    notary_pool_list = get_notary_pool_list(smc_handler)
    # Choose the first sampled notary and deregister it
    notary = get_committee_list(smc_handler, 0)[0]
    notary_index = notary_pool_list.index(notary)
    smc_handler.deregister_notary(
        private_key=NotaryAccount(notary_index).private_key)
    mine(w3, 1)
    # Check that first slot in committee is now empty
    assert smc_handler.get_member_of_committee(0, 0) == b'\x00' * 20

    # Register notary 9
    smc_handler.register_notary(private_key=NotaryAccount(9).private_key)
    mine(w3, 1)
    # Check that first slot in committee is replaced by notary 9
    assert smc_handler.get_member_of_committee(
        0, 0) == NotaryAccount(9).canonical_address
def test_register_without_enough_ether(smc_handler):  # noqa: F811
    w3 = smc_handler.web3

    notary_0 = NotaryAccount(0)

    does_notary_exist = smc_handler.does_notary_exist(
        notary_0.checksum_address)
    assert not does_notary_exist

    # Register without enough ether
    smc_handler._send_transaction(
        func_name='register_notary',
        args=[],
        private_key=notary_0.private_key,
        value=smc_handler.config['NOTARY_DEPOSIT'] // 10000,
        gas=smc_handler._estimate_gas_dict['register_notary'],
    )
    mine(w3, 1)

    # Check that the registration failed
    does_notary_exist = smc_handler.does_notary_exist(
        notary_0.checksum_address)
    assert not does_notary_exist
    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 0
def test_normal_deregister(smc_handler):  # noqa: F811
    w3 = smc_handler.web3

    notary_0 = NotaryAccount(0)

    # Register notary 0
    smc_handler.register_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    does_notary_exist = smc_handler.does_notary_exist(
        notary_0.checksum_address)
    assert does_notary_exist
    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 1

    # Fast foward
    fast_forward(smc_handler, 1)

    # Deregister notary 0
    smc_handler.deregister_notary(private_key=notary_0.private_key)
    current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH']
    mine(w3, 1)
    does_notary_exist = smc_handler.does_notary_exist(
        notary_0.checksum_address)
    assert does_notary_exist
    notary_deregistered_period, notary_pool_index = smc_handler.get_notary_info(
        notary_0.checksum_address)
    assert notary_deregistered_period == current_period
    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 0
示例#7
0
def update_notary_sample_size(smc_handler):
    smc_handler._send_transaction(
        func_name='update_notary_sample_size',
        args=[],
        private_key=NotaryAccount(0).private_key,
        gas=smc_handler._estimate_gas_dict['update_notary_sample_size'],
    )
    mine(smc_handler.web3, 1)
示例#8
0
def update_notary_sample_size(smc_handler):
    smc_handler._send_transaction(
        func_name='update_notary_sample_size',
        args=[],
        private_key=NotaryAccount(0).private_key,
        gas=smc_handler.config['DEFAULT_GAS'],
    )
    mine(smc_handler.web3, 1)
示例#9
0
def fast_forward(smc_handler, num_of_periods):
    assert num_of_periods > 0
    period_length = smc_handler.config['PERIOD_LENGTH']
    block_number = smc_handler.web3.eth.blockNumber
    current_period = block_number // period_length
    blocks_to_the_period = (current_period + num_of_periods) * period_length \
        - block_number
    mine(smc_handler.web3, blocks_to_the_period)
示例#10
0
def contract():
    eth_tester = EthereumTester(
        backend=PyEVMBackend(),
        auto_mine_transactions=False,
    )
    provider = EthereumTesterProvider(eth_tester)
    w3 = Web3(provider)
    tx_hash = w3.eth.sendTransaction(assoc(default_tx_detail, 'data', bytecode))
    mine(w3, 1)
    receipt = w3.eth.getTransactionReceipt(tx_hash)
    contract_address = receipt['contractAddress']
    return w3.eth.contract(contract_address, abi=abi, bytecode=bytecode)
示例#11
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
示例#12
0
def test_submit_vote_by_notary_sampled_multiple_times(
        smc_handler):  # noqa: F811
    w3 = smc_handler.web3
    # We only vote in shard 0 for ease of testing
    shard_id = 0

    # Here we only register 5 notaries so it's guaranteed that at least
    # one notary is going to be sampled twice.
    # Register notary 0~4 and fast forward to next period
    batch_register(smc_handler, 0, 4)
    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)

    # Find the notary that's sampled more than one time
    for pool_index in range(5):
        sample_index_list = [
            sample_index
            for (_, _shard_id,
                 sample_index) in get_sample_result(smc_handler, pool_index)
            if _shard_id == shard_id
        ]
        if len(sample_index_list) > 1:
            vote_count = len(sample_index_list)
            for sample_index in sample_index_list:
                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 every vote is successfully casted even by the same notary
            assert smc_handler.get_vote_count(shard_id) == vote_count
            break
def test_normal_register(smc_handler):  # noqa: F811
    w3 = smc_handler.web3

    notary_0 = NotaryAccount(0)

    does_notary_exist = smc_handler.does_notary_exist(
        notary_0.checksum_address)
    assert not does_notary_exist
    # Register notary 0
    smc_handler.register_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    does_notary_exist = smc_handler.does_notary_exist(
        notary_0.checksum_address)
    assert does_notary_exist
    notary_deregistered_period, notary_pool_index = smc_handler.get_notary_info(
        notary_0.checksum_address)
    assert notary_deregistered_period == 0 and notary_pool_index == 0
    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 1

    notary_1 = NotaryAccount(1)

    notary_2 = NotaryAccount(2)

    # Register notary 1 and notary 2
    batch_register(smc_handler, 0, 2)

    does_notary_exist = smc_handler.does_notary_exist(
        notary_1.checksum_address)
    assert does_notary_exist
    notary_deregistered_period, notary_pool_index = smc_handler.get_notary_info(
        notary_1.checksum_address)
    assert notary_deregistered_period == 0 and notary_pool_index == 1

    does_notary_exist = smc_handler.does_notary_exist(
        notary_2.checksum_address)
    assert does_notary_exist
    notary_deregistered_period, notary_pool_index = smc_handler.get_notary_info(
        notary_2.checksum_address)
    assert notary_deregistered_period == 0 and notary_pool_index == 2

    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 3
def test_normal_release_notary(smc_handler):  # noqa: F811
    w3 = smc_handler.web3

    notary_0 = NotaryAccount(0)

    # Register notary 0
    smc_handler.register_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    does_notary_exist = smc_handler.does_notary_exist(
        notary_0.checksum_address)
    assert does_notary_exist
    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 1

    # Fast foward
    fast_forward(smc_handler, 1)

    # Deregister notary 0
    smc_handler.deregister_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 0

    # Fast foward to end of lock up
    fast_forward(smc_handler, smc_handler.config['NOTARY_LOCKUP_LENGTH'] + 1)

    # Release notary 0
    smc_handler.release_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    does_notary_exist = smc_handler.does_notary_exist(
        notary_0.checksum_address)
    assert not does_notary_exist
def test_instant_release_notary(smc_handler):  # noqa: F811
    w3 = smc_handler.web3

    notary_0 = NotaryAccount(0)

    # Register notary 0
    smc_handler.register_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    does_notary_exist = smc_handler.does_notary_exist(
        notary_0.checksum_address)
    assert does_notary_exist
    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 1

    # Fast foward
    fast_forward(smc_handler, 1)

    # Deregister notary 0
    smc_handler.deregister_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 0

    # Instant release notary 0
    tx_hash = smc_handler.release_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    # Check registry remain the same and the transaction consume all gas
    # and no logs has been emitted
    does_notary_exist = smc_handler.does_notary_exist(
        notary_0.checksum_address)
    assert does_notary_exist
    assert len(w3.eth.getTransactionReceipt(tx_hash)['logs']) == 0
示例#16
0
def test_register_then_deregister(smc_handler):  # noqa: F811
    w3 = smc_handler.web3

    notary_0 = NotaryAccount(0)

    # Register notary 0 first
    smc_handler.register_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    _, notary_0_pool_index = smc_handler.get_notary_info(
        notary_0.checksum_address)
    assert notary_0_pool_index == 0
    next_period_notary_sample_size = smc_handler.next_period_notary_sample_size(
    )
    assert (notary_0_pool_index + 1) == next_period_notary_sample_size

    # Then deregister notary 0
    smc_handler.deregister_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    # Check that next_period_notary_sample_size remains the same
    next_period_notary_sample_size = smc_handler.next_period_notary_sample_size(
    )
    assert (notary_0_pool_index + 1) == next_period_notary_sample_size
def test_double_register(smc_handler):  # noqa: F811
    w3 = smc_handler.web3

    notary_0 = NotaryAccount(0)

    # Register notary 0
    smc_handler.register_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    does_notary_exist = smc_handler.does_notary_exist(
        notary_0.checksum_address)
    assert does_notary_exist
    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 1

    # Try register notary 0 again
    tx_hash = smc_handler.register_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    # Check pool remain the same and the transaction consume all gas
    # and no logs has been emitted
    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 1
    assert len(w3.eth.getTransactionReceipt(tx_hash)['logs']) == 0
示例#18
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)
示例#19
0
def test_normal_add_header(smc_handler):  # noqa: F811
    w3 = smc_handler.web3

    # Register notary 0~2 and fast forward to next period
    batch_register(smc_handler, 0, 2)
    fast_forward(smc_handler, 1)
    current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH']
    assert current_period == 1
    # Check that collation records of shard 0 and shard 1 have not been updated before
    assert smc_handler.records_updated_period(0) == 0
    assert smc_handler.records_updated_period(1) == 0

    CHUNK_ROOT_1_0 = b'\x10' * 32
    smc_handler.add_header(
        shard_id=0,
        period=1,
        chunk_root=CHUNK_ROOT_1_0,
        private_key=NotaryAccount(index=0).private_key,
    )
    mine(w3=w3, num_blocks=1)
    # Check that collation record of shard 0 has been updated
    assert smc_handler.records_updated_period(0) == 1
    assert smc_handler.get_collation_chunk_root(shard_id=0,
                                                period=1) == CHUNK_ROOT_1_0

    fast_forward(smc_handler, 1)
    current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH']
    assert current_period == 2

    CHUNK_ROOT_2_0 = b'\x20' * 32
    smc_handler.add_header(
        shard_id=0,
        period=2,
        chunk_root=CHUNK_ROOT_2_0,
        private_key=NotaryAccount(index=0).private_key,
    )
    mine(w3=w3, num_blocks=1)
    # Check that collation record of shard 0 has been updated
    assert smc_handler.records_updated_period(0) == 2
    assert smc_handler.get_collation_chunk_root(shard_id=0,
                                                period=2) == CHUNK_ROOT_2_0
    # Check that collation record of shard 1 has never been updated
    assert smc_handler.records_updated_period(1) == 0

    CHUNK_ROOT_2_1 = b'\x21' * 32
    smc_handler.add_header(
        shard_id=1,
        period=2,
        chunk_root=CHUNK_ROOT_2_1,
        private_key=NotaryAccount(index=0).private_key,
    )
    mine(w3=w3, num_blocks=1)
    # Check that collation record of shard 1 has been updated
    assert smc_handler.records_updated_period(1) == 2
    assert smc_handler.get_collation_chunk_root(shard_id=1,
                                                period=2) == CHUNK_ROOT_2_1
def test_deregister_and_new_notary_register(smc_handler):  # noqa: F811
    w3 = smc_handler.web3

    notary_0 = NotaryAccount(0)

    # Register notary 0
    smc_handler.register_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 1

    notary_2 = NotaryAccount(2)

    # Register notary 1~3
    batch_register(smc_handler, 1, 3)

    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 4
    # Check that empty_slots_stack is empty
    empty_slots_stack_top = smc_handler.empty_slots_stack_top()
    assert empty_slots_stack_top == 0

    # Fast foward
    fast_forward(smc_handler, 1)

    # Deregister notary 2
    smc_handler.deregister_notary(private_key=notary_2.private_key)
    mine(w3, 1)
    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 3

    # Check that empty_slots_stack is not empty
    empty_slots_stack_top = smc_handler.empty_slots_stack_top()
    assert empty_slots_stack_top == 1
    _, notary_2_pool_index = smc_handler.get_notary_info(
        notary_2.checksum_address)
    empty_slots = smc_handler.empty_slots_stack(0)
    # Check that the top empty_slots entry point to notary 2
    assert empty_slots == notary_2_pool_index

    notary_4 = NotaryAccount(4)

    # Register notary 4
    smc_handler.register_notary(private_key=notary_4.private_key)
    mine(w3, 1)

    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 4
    # Check that empty_slots_stack is empty
    empty_slots_stack_top = smc_handler.empty_slots_stack_top()
    assert empty_slots_stack_top == 0
    _, notary_4_pool_index = smc_handler.get_notary_info(
        notary_4.checksum_address)
    # Check that notary fill in notary 2's spot
    assert notary_4_pool_index == notary_2_pool_index
示例#21
0
def test_add_header_wrong_shard(smc_handler):  # noqa: F811
    w3 = smc_handler.web3
    shard_count = smc_handler.config['SHARD_COUNT']

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

    BLANK_CHUNK_ROOT = b'\x00' * 32
    CHUNK_ROOT_1_0 = b'\x10' * 32
    # Attempt to add collation record with illegal shard_id specified
    tx_hash = smc_handler.add_header(
        shard_id=shard_count + 1,
        period=1,
        chunk_root=CHUNK_ROOT_1_0,
        private_key=NotaryAccount(index=0).private_key,
    )
    mine(w3, 1)
    # Check that collation record of shard 0 has not been updated and transaction consume all gas
    # and no logs has been emitted
    assert smc_handler.records_updated_period(0) == 0
    assert smc_handler.get_collation_chunk_root(shard_id=0,
                                                period=1) == BLANK_CHUNK_ROOT
    assert len(w3.eth.getTransactionReceipt(tx_hash)['logs']) == 0

    # Second attempt to add collation record with illegal shard_id specified
    tx_hash = smc_handler.add_header(
        shard_id=-1,
        period=1,
        chunk_root=CHUNK_ROOT_1_0,
        private_key=NotaryAccount(index=0).private_key,
    )
    mine(w3, 1)
    # Check that collation record of shard 0 has not been updated and transaction consume all gas
    # and no logs has been emitted
    assert smc_handler.records_updated_period(0) == 0
    assert smc_handler.get_collation_chunk_root(shard_id=0,
                                                period=1) == BLANK_CHUNK_ROOT
    assert len(w3.eth.getTransactionReceipt(tx_hash)['logs']) == 0

    # Add correct collation record
    smc_handler.add_header(
        shard_id=0,
        period=1,
        chunk_root=CHUNK_ROOT_1_0,
        private_key=NotaryAccount(index=0).private_key,
    )
    mine(w3=w3, num_blocks=1)
    # Check that collation record of shard 0 has been updated
    assert smc_handler.records_updated_period(0) == 1
    assert smc_handler.get_collation_chunk_root(shard_id=0,
                                                period=1) == CHUNK_ROOT_1_0
示例#22
0
def test_series_of_deregister_starting_from_bottom_of_the_stack(
        smc_handler):  # noqa: F811
    w3 = smc_handler.web3

    notary_0 = NotaryAccount(0)
    notary_1 = NotaryAccount(1)
    notary_2 = NotaryAccount(2)

    # Register notary 0~2
    batch_register(smc_handler, 0, 2)

    # Fast forward to next period
    fast_forward(smc_handler, 1)

    # Deregister from notary 0 to notary 2
    # Deregister notary 0
    smc_handler.deregister_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    _, notary_0_pool_index = smc_handler.get_notary_info(
        notary_0.checksum_address)
    next_period_notary_sample_size = smc_handler.next_period_notary_sample_size(
    )
    # Check that next_period_notary_sample_size remains the same
    assert next_period_notary_sample_size == 3
    # Deregister notary 1
    smc_handler.deregister_notary(private_key=notary_1.private_key)
    mine(w3, 1)
    _, notary_1_pool_index = smc_handler.get_notary_info(
        notary_1.checksum_address)
    next_period_notary_sample_size = smc_handler.next_period_notary_sample_size(
    )
    # Check that next_period_notary_sample_size remains the same
    assert next_period_notary_sample_size == 3
    # Deregister notary 2
    smc_handler.deregister_notary(private_key=notary_2.private_key)
    mine(w3, 1)
    # Check that current_period_notary_sample_size is updated
    current_period_notary_sample_size = smc_handler.current_period_notary_sample_size(
    )
    assert current_period_notary_sample_size == 3
    _, notary_2_pool_index = smc_handler.get_notary_info(
        notary_2.checksum_address)
    next_period_notary_sample_size = smc_handler.next_period_notary_sample_size(
    )
    assert next_period_notary_sample_size == 3

    # Fast forward to next period
    fast_forward(smc_handler, 1)

    # Update notary sample size
    update_notary_sample_size(smc_handler)
    current_period_notary_sample_size = smc_handler.current_period_notary_sample_size(
    )
    assert current_period_notary_sample_size == next_period_notary_sample_size
示例#23
0
def test_series_of_deregister_starting_from_top_of_the_stack(
        smc_handler):  # noqa: F811
    w3 = smc_handler.web3

    notary_0 = NotaryAccount(0)
    notary_1 = NotaryAccount(1)
    notary_2 = NotaryAccount(2)

    # Register notary 0~2
    batch_register(smc_handler, 0, 2)
    next_period_notary_sample_size = smc_handler.next_period_notary_sample_size(
    )
    assert next_period_notary_sample_size == 3

    # Fast forward to next period
    fast_forward(smc_handler, 1)

    # Deregister from notary 2 to notary 0
    # Deregister notary 2
    smc_handler.deregister_notary(private_key=notary_2.private_key)
    mine(w3, 1)
    # Check that current_period_notary_sample_size is updated
    current_period_notary_sample_size = smc_handler.current_period_notary_sample_size(
    )
    assert current_period_notary_sample_size == 3
    # Check that next_period_notary_sample_size remains the samev
    next_period_notary_sample_size = smc_handler.next_period_notary_sample_size(
    )
    assert next_period_notary_sample_size == 3
    # Deregister notary 1
    smc_handler.deregister_notary(private_key=notary_1.private_key)
    mine(w3, 1)
    # Check that next_period_notary_sample_size remains the same
    next_period_notary_sample_size = smc_handler.next_period_notary_sample_size(
    )
    assert next_period_notary_sample_size == 3
    # Deregister notary 0
    smc_handler.deregister_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    # Check that next_period_notary_sample_size remains the same
    next_period_notary_sample_size = smc_handler.next_period_notary_sample_size(
    )
    assert next_period_notary_sample_size == 3

    # Fast forward to next period
    fast_forward(smc_handler, 1)

    # Update notary sample size
    update_notary_sample_size(smc_handler)
    current_period_notary_sample_size = smc_handler.current_period_notary_sample_size(
    )
    assert current_period_notary_sample_size == next_period_notary_sample_size
示例#24
0
def test_double_add_header(smc_handler):  # noqa: F811
    w3 = smc_handler.web3

    # Register notary 0~2 and fast forward to next period
    batch_register(smc_handler, 0, 2)
    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
    smc_handler.add_header(
        shard_id=0,
        period=1,
        chunk_root=CHUNK_ROOT_1_0,
        private_key=NotaryAccount(index=0).private_key,
    )
    mine(w3=w3, num_blocks=1)
    # Check that collation record of shard 0 has been updated
    assert smc_handler.records_updated_period(0) == 1
    assert smc_handler.get_collation_chunk_root(shard_id=0,
                                                period=1) == CHUNK_ROOT_1_0

    # Attempt to add collation record again with same collation record
    tx_hash = smc_handler.add_header(
        shard_id=0,
        period=1,
        chunk_root=CHUNK_ROOT_1_0,
        private_key=NotaryAccount(index=0).private_key,
    )
    mine(w3, 1)
    # Check that transaction consume all gas and no logs has been emitted
    assert len(w3.eth.getTransactionReceipt(tx_hash)['logs']) == 0

    # Attempt to add collation record again with different chunk root
    tx_hash = smc_handler.add_header(
        shard_id=0,
        period=1,
        chunk_root=b'\x56' * 32,
        private_key=NotaryAccount(index=0).private_key,
    )
    mine(w3, 1)
    # Check that collation record of shard 0 remains the same and transaction consume all gas
    # and no logs has been emitted
    assert smc_handler.records_updated_period(0) == 1
    assert smc_handler.get_collation_chunk_root(shard_id=0,
                                                period=1) == CHUNK_ROOT_1_0
    assert len(w3.eth.getTransactionReceipt(tx_hash)['logs']) == 0
示例#25
0
def test_get_logs_with_forks(contract, smc_testing_config):
    w3 = contract.web3
    log_handler = LogHandler(w3, smc_testing_config['PERIOD_LENGTH'])
    counter = itertools.count()
    snapshot_id = take_snapshot(w3)
    current_block_number = w3.eth.blockNumber

    contract.functions.emit_log(next(counter)).transact(default_tx_detail)
    mine(w3, 1)
    revert_to_snapshot(w3, snapshot_id)
    assert w3.eth.blockNumber == current_block_number
    contract.functions.emit_log(next(counter)).transact(default_tx_detail)
    mine(w3, 1)
    contract.functions.emit_log(next(counter)).transact(default_tx_detail)
    mine(w3, 1)
    logs = log_handler.get_logs()
    # assert len(logs) == 2
    assert int(logs[0]['data'], 16) == 1
    assert int(logs[1]['data'], 16) == 2
def test_deregister_then_register(smc_handler):  # noqa: F811
    w3 = smc_handler.web3

    notary_0 = NotaryAccount(0)

    # Register notary 0
    smc_handler.register_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    does_notary_exist = smc_handler.does_notary_exist(
        notary_0.checksum_address)
    assert does_notary_exist
    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 1

    # Fast foward
    fast_forward(smc_handler, 1)

    # Deregister notary 0
    smc_handler.deregister_notary(private_key=notary_0.private_key)
    current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH']
    mine(w3, 1)
    does_notary_exist = smc_handler.does_notary_exist(
        notary_0.checksum_address)
    assert does_notary_exist
    notary_deregistered_period, notary_pool_index = smc_handler.get_notary_info(
        notary_0.checksum_address)
    assert notary_deregistered_period == current_period
    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 0

    # Register again right away
    tx_hash = smc_handler.register_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    # Check pool remain the same and the transaction consume all gas
    # and no logs has been emitted
    notary_pool_length = smc_handler.notary_pool_len()
    assert notary_pool_length == 0
    assert len(w3.eth.getTransactionReceipt(tx_hash)['logs']) == 0
示例#27
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)
示例#28
0
def test_get_logs_without_forks(contract, smc_testing_config):
    period_length = smc_testing_config['PERIOD_LENGTH']
    w3 = contract.web3
    log_handler = LogHandler(w3, period_length)
    counter = itertools.count()

    contract.functions.emit_log(next(counter)).transact(default_tx_detail)
    mine(w3, 1)
    logs_block2 = log_handler.get_logs(address=contract.address)
    assert len(logs_block2) == 1
    assert int(logs_block2[0]['data'], 16) == 0
    mine(w3, period_length - 1)

    contract.functions.emit_log(next(counter)).transact(default_tx_detail)
    mine(w3, 1)
    logs_block3 = log_handler.get_logs(address=contract.address)
    assert len(logs_block3) == 1
    assert int(logs_block3[0]['data'], 16) == 1
    mine(w3, period_length - 1)

    contract.functions.emit_log(next(counter)).transact(default_tx_detail)
    mine(w3, 1)
    contract.functions.emit_log(next(counter)).transact(default_tx_detail)
    mine(w3, 1)
    logs_block4_5 = log_handler.get_logs(address=contract.address)
    assert len(logs_block4_5) == 2
    assert int(logs_block4_5[0]['data'], 16) == 2
    assert int(logs_block4_5[1]['data'], 16) == 3
示例#29
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'])
    )
示例#30
0
def test_normal_update_notary_sample_size(smc_handler):  # noqa: F811
    w3 = smc_handler.web3

    notary_0 = NotaryAccount(0)

    # Register notary 0
    smc_handler.register_notary(private_key=notary_0.private_key)
    mine(w3, 1)
    _, notary_0_pool_index = smc_handler.get_notary_info(
        notary_0.checksum_address)
    assert notary_0_pool_index == 0
    next_period_notary_sample_size = smc_handler.next_period_notary_sample_size(
    )
    assert (notary_0_pool_index + 1) == next_period_notary_sample_size

    notary_1 = NotaryAccount(1)

    # Register notary 1
    smc_handler.register_notary(private_key=notary_1.private_key)
    mine(w3, 1)

    _, notary_1_pool_index = smc_handler.get_notary_info(
        notary_1.checksum_address)
    assert notary_1_pool_index == 1
    next_period_notary_sample_size = smc_handler.next_period_notary_sample_size(
    )
    assert (notary_1_pool_index + 1) == next_period_notary_sample_size

    # Check that it's not yet the time to update notary sample size,
    # i.e., current period is the same as latest period the notary sample size was updated.
    current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH']
    notary_sample_size_updated_period = smc_handler.notary_sample_size_updated_period(
    )
    assert current_period == notary_sample_size_updated_period

    # Check that current_period_notary_sample_size has not been updated before
    current_period_notary_sample_size = smc_handler.current_period_notary_sample_size(
    )
    assert 0 == current_period_notary_sample_size

    # Try updating notary sample size
    update_notary_sample_size(smc_handler)
    # Check that current_period_notary_sample_size is not updated,
    # i.e., updating notary sample size failed.
    assert 0 == current_period_notary_sample_size

    # fast forward to next period
    fast_forward(smc_handler, 1)

    # Register notary 2
    # NOTE: Registration would also invoke update_notary_sample_size function
    notary_2 = NotaryAccount(2)
    smc_handler.register_notary(private_key=notary_2.private_key)
    mine(w3, 1)

    # Check that current_period_notary_sample_size is updated,
    # i.e., it is assigned the value of next_period_notary_sample_size.
    current_period_notary_sample_size = smc_handler.current_period_notary_sample_size(
    )
    assert next_period_notary_sample_size == current_period_notary_sample_size

    # Check that notary sample size is updated in this period
    current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH']
    notary_sample_size_updated_period = smc_handler.notary_sample_size_updated_period(
    )
    assert current_period == notary_sample_size_updated_period