From 8a7814deab346ea4519b09d89e15c453d270549d Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Mon, 4 Mar 2019 17:25:27 +0800 Subject: [PATCH] Use little endian (#361) * Use little endian * Use little endian bit order in bitfield * fix `test_get_attestation_participants` and `test_custody_bit_indices` * PR feedback --- eth2/_utils/bitfield.py | 6 +++-- eth2/beacon/_utils/random.py | 4 +-- eth2/beacon/on_genesis.py | 2 +- .../forks/serenity/block_validation.py | 2 +- .../forks/serenity/epoch_processing.py | 2 +- tests/eth2/beacon/_utils/test_random.py | 18 +------------ tests/eth2/beacon/conftest.py | 2 +- .../forks/test_serenity_block_processing.py | 4 +-- .../forks/test_serenity_block_validation.py | 2 +- .../forks/test_serenity_epoch_processing.py | 23 ++++++++-------- .../test_serenity_operation_processing.py | 19 +++++++++++--- tests/eth2/beacon/test_committee_helpers.py | 4 +-- .../beacon/test_epoch_processing_helpers.py | 10 ++----- .../beacon/test_validator_status_helpers.py | 2 +- .../types/test_slashable_attestation.py | 4 +-- tests/eth2/bitfield-utils/test_bitfields.py | 26 ++++++++++++------- 16 files changed, 64 insertions(+), 66 deletions(-) diff --git a/eth2/_utils/bitfield.py b/eth2/_utils/bitfield.py index f9b3012783..8dc28dda0b 100644 --- a/eth2/_utils/bitfield.py +++ b/eth2/_utils/bitfield.py @@ -15,14 +15,16 @@ @curry def has_voted(bitfield: Bitfield, index: int) -> bool: - return bool(bitfield[index // 8] & (128 >> (index % 8))) + byte_index = index // 8 + bit_index = index % 8 + return bool((bitfield[byte_index] >> bit_index) % 2) @curry def set_voted(bitfield: Bitfield, index: int) -> Bitfield: byte_index = index // 8 bit_index = index % 8 - new_byte_value = bitfield[byte_index] | (128 >> bit_index) + new_byte_value = bitfield[byte_index] | (1 << bit_index) new_bitfield = bitfield[:byte_index] + bytes([new_byte_value]) + bitfield[byte_index + 1:] return Bitfield(new_bitfield) diff --git a/eth2/beacon/_utils/random.py b/eth2/beacon/_utils/random.py index 6e4cb9c130..364ebdb644 100644 --- a/eth2/beacon/_utils/random.py +++ b/eth2/beacon/_utils/random.py @@ -59,9 +59,9 @@ def shuffle(values: Sequence[TItem], if remaining == 1: break - # Read 3-bytes of `source` as a 24-bit big-endian integer. + # Read 3-bytes of `source` as a 24-bit little-endian integer. sample_from_source = int.from_bytes( - source[position:position + RAND_BYTES], 'big' + source[position:position + RAND_BYTES], 'little' ) # Sample values greater than or equal to `sample_max` will cause diff --git a/eth2/beacon/on_genesis.py b/eth2/beacon/on_genesis.py index 0479e644d8..15ba2bb5f8 100644 --- a/eth2/beacon/on_genesis.py +++ b/eth2/beacon/on_genesis.py @@ -159,7 +159,7 @@ def get_genesis_beacon_state(*, genesis_active_index_root = hash_eth2( b''.join( [ - index.to_bytes(32, 'big') + index.to_bytes(32, 'little') for index in active_validator_indices ] ) diff --git a/eth2/beacon/state_machines/forks/serenity/block_validation.py b/eth2/beacon/state_machines/forks/serenity/block_validation.py index e8e1220170..2995fc60f3 100644 --- a/eth2/beacon/state_machines/forks/serenity/block_validation.py +++ b/eth2/beacon/state_machines/forks/serenity/block_validation.py @@ -608,7 +608,7 @@ def validate_randao_reveal(randao_reveal: BLSSignature, proposer_pubkey: BLSPubkey, epoch: Epoch, fork: Fork) -> None: - message_hash = Hash32(epoch.to_bytes(32, byteorder="big")) + message_hash = Hash32(epoch.to_bytes(32, byteorder="little")) domain = get_domain(fork, epoch, SignatureDomain.DOMAIN_RANDAO) is_randao_reveal_valid = bls.verify( diff --git a/eth2/beacon/state_machines/forks/serenity/epoch_processing.py b/eth2/beacon/state_machines/forks/serenity/epoch_processing.py index ccdc02362b..f2efad5429 100644 --- a/eth2/beacon/state_machines/forks/serenity/epoch_processing.py +++ b/eth2/beacon/state_machines/forks/serenity/epoch_processing.py @@ -1000,7 +1000,7 @@ def _update_latest_active_index_roots(state: BeaconState, index_root = hash_eth2( b''.join( [ - index.to_bytes(32, 'big') + index.to_bytes(32, 'little') for index in active_validator_indices ] ) diff --git a/tests/eth2/beacon/_utils/test_random.py b/tests/eth2/beacon/_utils/test_random.py index 629a5dca9b..64050037b2 100644 --- a/tests/eth2/beacon/_utils/test_random.py +++ b/tests/eth2/beacon/_utils/test_random.py @@ -10,26 +10,10 @@ 'values,seed,expect' ), [ - ( - tuple(range(100)), - b'\x32' * 32, - ( - 92, 18, 80, 86, 39, 56, 81, 74, 68, 64, - 52, 82, 26, 25, 45, 2, 66, 38, 35, 15, - 46, 9, 65, 55, 85, 51, 53, 95, 57, 88, - 43, 70, 22, 5, 31, 63, 90, 61, 89, 24, - 6, 94, 12, 29, 84, 72, 42, 73, 40, 48, - 16, 77, 69, 4, 14, 75, 21, 17, 54, 37, - 98, 3, 60, 36, 76, 1, 97, 0, 44, 19, - 83, 28, 41, 47, 13, 91, 93, 7, 71, 58, - 11, 20, 50, 30, 34, 49, 33, 59, 79, 62, - 67, 96, 78, 8, 10, 99, 87, 27, 32, 23, - ), - ), ( tuple(range(12)), b'\x23' * 32, - (11, 4, 9, 5, 7, 10, 2, 8, 0, 6, 3, 1), + (8, 3, 9, 0, 1, 11, 2, 4, 6, 7, 10, 5), ), ], ) diff --git a/tests/eth2/beacon/conftest.py b/tests/eth2/beacon/conftest.py index 9f05679d59..8eb1646c64 100644 --- a/tests/eth2/beacon/conftest.py +++ b/tests/eth2/beacon/conftest.py @@ -363,7 +363,7 @@ def n_validators_state(filled_beacon_state, max_deposit_amount, n): return filled_beacon_state.copy( validator_registry=tuple( mock_validator_record( - pubkey=index.to_bytes(48, "big"), + pubkey=index.to_bytes(48, "little"), is_active=True, ) for index in range(validator_count) diff --git a/tests/eth2/beacon/state_machines/forks/test_serenity_block_processing.py b/tests/eth2/beacon/state_machines/forks/test_serenity_block_processing.py index 519bb86e64..29b88fe119 100644 --- a/tests/eth2/beacon/state_machines/forks/test_serenity_block_processing.py +++ b/tests/eth2/beacon/state_machines/forks/test_serenity_block_processing.py @@ -63,7 +63,7 @@ def test_randao_processing(sample_beacon_block_params, epoch = state.current_epoch(config.SLOTS_PER_EPOCH) slot = epoch * config.SLOTS_PER_EPOCH - message_hash = epoch.to_bytes(32, byteorder="big") + message_hash = epoch.to_bytes(32, byteorder="little") fork = Fork(**sample_fork_params) domain = get_domain(fork, slot, SignatureDomain.DOMAIN_RANDAO) randao_reveal = bls.sign(message_hash, proposer_privkey, domain) @@ -105,7 +105,7 @@ def test_randao_processing_validates_randao_reveal(sample_beacon_block_params, epoch = state.current_epoch(config.SLOTS_PER_EPOCH) slot = epoch * config.SLOTS_PER_EPOCH - message_hash = (epoch + 1).to_bytes(32, byteorder="big") + message_hash = (epoch + 1).to_bytes(32, byteorder="little") fork = Fork(**sample_fork_params) domain = get_domain(fork, slot, SignatureDomain.DOMAIN_RANDAO) randao_reveal = bls.sign(message_hash, proposer_privkey, domain) diff --git a/tests/eth2/beacon/state_machines/forks/test_serenity_block_validation.py b/tests/eth2/beacon/state_machines/forks/test_serenity_block_validation.py index 542b15339a..7f34e0e0c3 100644 --- a/tests/eth2/beacon/state_machines/forks/test_serenity_block_validation.py +++ b/tests/eth2/beacon/state_machines/forks/test_serenity_block_validation.py @@ -162,7 +162,7 @@ def test_randao_reveal_validation(is_valid, pubkeys, sample_fork_params, config): - message_hash = epoch.to_bytes(32, byteorder="big") + message_hash = epoch.to_bytes(32, byteorder="little") slot = epoch * config.SLOTS_PER_EPOCH fork = Fork(**sample_fork_params) domain = get_domain(fork, slot, SignatureDomain.DOMAIN_RANDAO) diff --git a/tests/eth2/beacon/state_machines/forks/test_serenity_epoch_processing.py b/tests/eth2/beacon/state_machines/forks/test_serenity_epoch_processing.py index 64f9b4bf16..26cd54db99 100644 --- a/tests/eth2/beacon/state_machines/forks/test_serenity_epoch_processing.py +++ b/tests/eth2/beacon/state_machines/forks/test_serenity_epoch_processing.py @@ -7,7 +7,6 @@ ) from eth._utils.numeric import ( - int_to_bytes32, integer_squareroot ) @@ -594,40 +593,40 @@ def test_process_rewards_and_penalties_for_finality( { 2: 31, # proposer index for inclusion slot 31: 6 3: 31, - 4: 32, # proposer index for inclusion slot 32: 19 + 4: 32, # proposer index for inclusion slot 32: 12 5: 32, 6: 32, - 9: 35, # proposer index for inclusion slot 35: 16 + 9: 35, # proposer index for inclusion slot 35: 19 10: 35, 11: 35, 12: 35, 13: 35, - 15: 38, # proposer index for inclusion slot 38: 1 + 15: 38, # proposer index for inclusion slot 38: 8 16: 38, 17: 38, }, 100, { 0: 0, - 1: 75, # 3 * (100 // 4) + 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 50, # 2 * (100 // 4) 7: 0, - 8: 0, + 8: 75, # 3 * (100 // 4) 9: 0, 10: 0, 11: 0, - 12: 0, + 12: 75, # 3 * (100 // 4) 13: 0, 14: 0, 15: 0, - 16: 125, # 5 * (100 // 4) + 16: 0, 17: 0, 18: 0, - 19: 75, # 3 * (100 // 4) + 19: 125, # 5 * (100 // 4) } ), ] @@ -974,7 +973,7 @@ def test_check_if_update_validator_registry(genesis_state, 2, True, # (state.current_epoch - state.validator_registry_update_epoch) is power of two 0, - [int_to_bytes32(i) for i in range(2**10)], + [i.to_bytes(32, 'little') for i in range(2**10)], 5, # expected current_shuffling_epoch is state.next_epoch ), ( @@ -985,7 +984,7 @@ def test_check_if_update_validator_registry(genesis_state, 1, False, # (state.current_epoch - state.validator_registry_update_epoch) != power of two 0, - [int_to_bytes32(i) for i in range(2**10)], + [i.to_bytes(32, 'little') for i in range(2**10)], 0, # expected_current_shuffling_epoch is current_shuffling_epoch because it will not be updated # noqa: E501 ), ] @@ -1094,7 +1093,7 @@ def test_update_latest_active_index_roots(genesis_state, index_root = hash_eth2( b''.join( [ - index.to_bytes(32, 'big') + index.to_bytes(32, 'little') for index in get_active_validator_indices( state.validator_registry, # TODO: change to `per-epoch` version diff --git a/tests/eth2/beacon/state_machines/forks/test_serenity_operation_processing.py b/tests/eth2/beacon/state_machines/forks/test_serenity_operation_processing.py index b9c4d11cf0..961e8835b4 100644 --- a/tests/eth2/beacon/state_machines/forks/test_serenity_operation_processing.py +++ b/tests/eth2/beacon/state_machines/forks/test_serenity_operation_processing.py @@ -4,6 +4,12 @@ ValidationError, ) +from eth2.beacon.committee_helpers import ( + get_beacon_proposer_index, +) +from eth2.beacon.configs import ( + CommitteeConfig, +) from eth2.beacon.types.blocks import ( BeaconBlockBody, ) @@ -91,15 +97,19 @@ def test_process_proposer_slashings(genesis_state, state = genesis_state.copy( slot=current_slot, ) - - proposer_index = 0 + whistleblower_index = get_beacon_proposer_index( + state, + state.slot, + CommitteeConfig(config), + ) + slashing_proposer_index = (whistleblower_index + 1) % len(state.validator_registry) proposer_slashing = create_mock_proposer_slashing_at_block( state, config, keymap, block_root_1=block_root_1, block_root_2=block_root_2, - proposer_index=proposer_index, + proposer_index=slashing_proposer_index, ) proposer_slashings = (proposer_slashing,) @@ -119,7 +129,8 @@ def test_process_proposer_slashings(genesis_state, ) # Check if slashed assert ( - new_state.validator_balances[proposer_index] < state.validator_balances[proposer_index] + new_state.validator_balances[slashing_proposer_index] < + state.validator_balances[slashing_proposer_index] ) else: with pytest.raises(ValidationError): diff --git a/tests/eth2/beacon/test_committee_helpers.py b/tests/eth2/beacon/test_committee_helpers.py index 6aa474b049..2a9523f69e 100644 --- a/tests/eth2/beacon/test_committee_helpers.py +++ b/tests/eth2/beacon/test_committee_helpers.py @@ -495,14 +495,14 @@ def mock_get_crosslink_committees_at_slot(state, 100, 64, (10, 11, 12), - b'\x80', + b'\x01', (10,), ), ( 100, 64, (10, 11, 12), - b'\xc0', + b'\x03', (10, 11), ), ( diff --git a/tests/eth2/beacon/test_epoch_processing_helpers.py b/tests/eth2/beacon/test_epoch_processing_helpers.py index 60d4e57d2c..00d5544c7a 100644 --- a/tests/eth2/beacon/test_epoch_processing_helpers.py +++ b/tests/eth2/beacon/test_epoch_processing_helpers.py @@ -10,10 +10,6 @@ strategies as st, ) -from eth_utils import ( - big_endian_to_int, -) - from eth2._utils.bitfield import ( set_voted, get_empty_bitfield, @@ -145,7 +141,7 @@ def test_get_previous_epoch_head_attestations( current_epoch = previous_epoch + 1 current_slot = get_epoch_start_slot(current_epoch + 1, slots_per_epoch) - 1 latest_block_roots = [ - hash_eth2(b'block_root' + i.to_bytes(1, 'big')) + hash_eth2(b'block_root' + i.to_bytes(1, 'little')) for i in range(latest_block_roots_length) ] @@ -320,9 +316,7 @@ def mock_get_crosslink_committees_at_slot(state, assert len(block_root_1_participants) == 0 and len(block_root_2_participants) == 0 else: if len(block_root_1_participants) == len(block_root_2_participants): - root_1_as_int = big_endian_to_int(competing_block_roots[0]) - root_2_as_int = big_endian_to_int(competing_block_roots[1]) - if root_1_as_int < root_2_as_int: + if competing_block_roots[0] < competing_block_roots[1]: assert winning_root == competing_block_roots[0] else: assert winning_root == competing_block_roots[1] diff --git a/tests/eth2/beacon/test_validator_status_helpers.py b/tests/eth2/beacon/test_validator_status_helpers.py index 03898d10ba..710f020609 100644 --- a/tests/eth2/beacon/test_validator_status_helpers.py +++ b/tests/eth2/beacon/test_validator_status_helpers.py @@ -52,7 +52,7 @@ def test_activate_validator(is_genesis, state = filled_beacon_state.copy( validator_registry=tuple( mock_validator_record( - pubkey=index.to_bytes(48, 'big'), + pubkey=index.to_bytes(48, 'little'), is_active=False, ) for index in range(validator_count) diff --git a/tests/eth2/beacon/types/test_slashable_attestation.py b/tests/eth2/beacon/types/test_slashable_attestation.py index dc831a7adc..abbc41c86f 100644 --- a/tests/eth2/beacon/types/test_slashable_attestation.py +++ b/tests/eth2/beacon/types/test_slashable_attestation.py @@ -61,8 +61,8 @@ def test_is_validator_indices_ascending( 'custody_bit_indices' ), [ - ((0, 1, 2), b'\x80', ((1, 2), (0,))), - ((0, 1, 2), b'\xC0', ((2,), (0, 1))), + ((0, 1, 2), b'\x01', ((1, 2), (0,))), + ((0, 1, 2), b'\x03', ((2,), (0, 1))), ], ) def test_custody_bit_indices( diff --git a/tests/eth2/bitfield-utils/test_bitfields.py b/tests/eth2/bitfield-utils/test_bitfields.py index cfb5963219..a9f017870d 100644 --- a/tests/eth2/bitfield-utils/test_bitfields.py +++ b/tests/eth2/bitfield-utils/test_bitfields.py @@ -43,12 +43,15 @@ def test_bitfield_single_votes(): attesters = list(range(10)) bitfield = get_empty_bitfield(len(attesters)) - assert set_voted(bitfield, 0) == b'\x80\x00' - assert set_voted(bitfield, 1) == b'\x40\x00' - assert set_voted(bitfield, 2) == b'\x20\x00' - assert set_voted(bitfield, 7) == b'\x01\x00' - assert set_voted(bitfield, 8) == b'\x00\x80' - assert set_voted(bitfield, 9) == b'\x00\x40' + assert set_voted(bitfield, 0) == b'\x01\x00' + assert set_voted(bitfield, 1) == b'\x02\x00' + assert set_voted(bitfield, 2) == b'\x04\x00' + assert set_voted(bitfield, 4) == b'\x10\x00' + assert set_voted(bitfield, 5) == b'\x20\x00' + assert set_voted(bitfield, 6) == b'\x40\x00' + assert set_voted(bitfield, 7) == b'\x80\x00' + assert set_voted(bitfield, 8) == b'\x00\x01' + assert set_voted(bitfield, 9) == b'\x00\x02' for voter in attesters: bitfield = set_voted(b'\x00\x00', voter) @@ -68,18 +71,23 @@ def test_bitfield_all_votes(): for attester in attesters: assert has_voted(bitfield, attester) - assert bitfield == b'\xff\xc0' + assert bitfield == b'\xff\x03' def test_bitfield_some_votes(): attesters = list(range(10)) - voters = [0, 4, 5, 9] + voters = [ + 0, # b'\x01\x00' + 4, # b'\x10\x00' + 5, # b'\x20\x00' + 9, # b'\x00\x02' + ] bitfield = get_empty_bitfield(len(attesters)) for voter in voters: bitfield = set_voted(bitfield, voter) - assert bitfield == b'\x8c\x40' + assert bitfield == b'\x31\x02' for attester in attesters: if attester in voters: