def test_get_member_of_committee_without_updating_sample_size( smc_handler): # noqa: F811 w3 = smc_handler.web3 # Register notary 0~5 and fast forward to next period batch_register(smc_handler, 0, 5) fast_forward(smc_handler, 1) # Register notary 6~8 batch_register(smc_handler, 6, 8) # Check that sample-size-related values match current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH'] notary_sample_size_updated_period = smc_handler.notary_sample_size_updated_period( ) assert notary_sample_size_updated_period == current_period current_period_notary_sample_size = smc_handler.current_period_notary_sample_size( ) assert current_period_notary_sample_size == 6 next_period_notary_sample_size = smc_handler.next_period_notary_sample_size( ) assert next_period_notary_sample_size == 9 # Fast forward to next period fast_forward(smc_handler, 1) current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH'] notary_sample_size_updated_period = smc_handler.notary_sample_size_updated_period( ) assert notary_sample_size_updated_period == current_period - 1 shard_0_committee_list = get_committee_list(smc_handler, 0) # Check that get_committee_list did generate committee list assert len(shard_0_committee_list) > 0 for (i, notary) in enumerate(shard_0_committee_list): assert smc_handler.get_member_of_committee(0, i) == notary
def test_get_member_of_committee_with_updated_sample_size( 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) # Check that sample-size-related values match current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH'] notary_sample_size_updated_period = smc_handler.notary_sample_size_updated_period( ) assert notary_sample_size_updated_period == current_period current_period_notary_sample_size = smc_handler.current_period_notary_sample_size( ) assert current_period_notary_sample_size == 9 next_period_notary_sample_size = smc_handler.next_period_notary_sample_size( ) assert next_period_notary_sample_size == 9 shard_0_committee_list = get_committee_list(smc_handler, 0) for (i, notary) in enumerate(shard_0_committee_list): assert smc_handler.get_member_of_committee(0, i) == notary
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
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)
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)
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_get_sample_result(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 current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH'] update_notary_sample_size(smc_handler) # Get all committee of current period committee_group = [] for shard_id in range(smc_handler.config['SHARD_COUNT']): committee_group.append(get_committee_list(smc_handler, shard_id)) # Get sampling result for notary 0 notary_0 = NotaryAccount(0) _, notary_0_pool_index = smc_handler.get_notary_info( notary_0.checksum_address) notary_0_sampling_result = get_sample_result(smc_handler, notary_0_pool_index) for (period, shard_id, sampling_index) in notary_0_sampling_result: assert period == current_period # Check that notary is correctly sampled in get_committee_list assert committee_group[shard_id][ sampling_index] == notary_0.canonical_address # Check that notary is correctly sampled in SMC assert smc_handler.get_member_of_committee(shard_id, sampling_index) \ == notary_0.canonical_address
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
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
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
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
def test_get_member_of_committee_with_non_member(smc_handler): # noqa: F811 # 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) shard_0_committee_list = get_committee_list(smc_handler, 0) for (i, notary) in enumerate(shard_0_committee_list): notary_index = notary_pool_list.index(notary) next_notary_index = notary_index + 1 \ if notary_index < len(notary_pool_list) - 1 else 0 next_notary = notary_pool_list[next_notary_index] assert not (smc_handler.get_member_of_committee(0, i) == next_notary)
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
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_committee_lists_generated_are_different(smc_handler): # noqa: F811 # 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) shard_0_committee_list = get_committee_list(smc_handler, 0) shard_1_committee_list = get_committee_list(smc_handler, 1) assert shard_0_committee_list != shard_1_committee_list # Fast forward to next period fast_forward(smc_handler, 1) # Update notary sample size update_notary_sample_size(smc_handler) new_shard_0_committee_list = get_committee_list(smc_handler, 0) assert new_shard_0_committee_list != shard_0_committee_list
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)
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)
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)