Merge pull request #865 from ethereum/vbuterin-patch-2

Possible aesthetic rework to get_domain
This commit is contained in:
Danny Ryan 2019-04-18 21:19:49 -06:00 committed by GitHub
commit 23fffe6490
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 88 deletions

View File

@ -81,7 +81,6 @@
- [`bytes_to_int`](#bytes_to_int) - [`bytes_to_int`](#bytes_to_int)
- [`get_effective_balance`](#get_effective_balance) - [`get_effective_balance`](#get_effective_balance)
- [`get_total_balance`](#get_total_balance) - [`get_total_balance`](#get_total_balance)
- [`get_fork_version`](#get_fork_version)
- [`get_domain`](#get_domain) - [`get_domain`](#get_domain)
- [`get_bitfield_bit`](#get_bitfield_bit) - [`get_bitfield_bit`](#get_bitfield_bit)
- [`verify_bitfield`](#verify_bitfield) - [`verify_bitfield`](#verify_bitfield)
@ -264,7 +263,7 @@ These configurations are updated for releases, but may be out of sync during `de
| Name | Value | | Name | Value |
| - | - | | - | - |
| `DOMAIN_BEACON_BLOCK` | `0` | | `DOMAIN_BEACON_PROPOSER` | `0` |
| `DOMAIN_RANDAO` | `1` | | `DOMAIN_RANDAO` | `1` |
| `DOMAIN_ATTESTATION` | `2` | | `DOMAIN_ATTESTATION` | `2` |
| `DOMAIN_DEPOSIT` | `3` | | `DOMAIN_DEPOSIT` | `3` |
@ -359,7 +358,7 @@ The types are defined topologically to aid in facilitating an executable version
# Attestation data # Attestation data
'data': AttestationData, 'data': AttestationData,
# Aggregate signature # Aggregate signature
'aggregate_signature': 'bytes96', 'signature': 'bytes96',
} }
``` ```
@ -374,7 +373,7 @@ The types are defined topologically to aid in facilitating an executable version
# Amount in Gwei # Amount in Gwei
'amount': 'uint64', 'amount': 'uint64',
# Container self-signature # Container self-signature
'proof_of_possession': 'bytes96', 'signature': 'bytes96',
} }
``` ```
@ -473,7 +472,7 @@ The types are defined topologically to aid in facilitating an executable version
# Custody bitfield # Custody bitfield
'custody_bitfield': 'bytes', 'custody_bitfield': 'bytes',
# BLS aggregate signature # BLS aggregate signature
'aggregate_signature': 'bytes96', 'signature': 'bytes96',
} }
``` ```
@ -912,7 +911,7 @@ def get_block_root(state: BeaconState,
return state.latest_block_roots[slot % SLOTS_PER_HISTORICAL_ROOT] return state.latest_block_roots[slot % SLOTS_PER_HISTORICAL_ROOT]
``` ```
`get_block_root(_, s)` should always return `signed_root` of the block in the beacon chain at slot `s`, and `get_crosslink_committees_at_slot(_, s)` should not change unless the [validator](#dfn-validator) registry changes. `get_block_root(_, s)` should always return `signing_root` of the block in the beacon chain at slot `s`, and `get_crosslink_committees_at_slot(_, s)` should not change unless the [validator](#dfn-validator) registry changes.
### `get_state_root` ### `get_state_root`
@ -1046,30 +1045,18 @@ def get_total_balance(state: BeaconState, validators: List[ValidatorIndex]) -> G
return sum([get_effective_balance(state, i) for i in validators]) return sum([get_effective_balance(state, i) for i in validators])
``` ```
### `get_fork_version`
```python
def get_fork_version(fork: Fork,
epoch: Epoch) -> bytes:
"""
Return the fork version of the given ``epoch``.
"""
if epoch < fork.epoch:
return fork.previous_version
else:
return fork.current_version
```
### `get_domain` ### `get_domain`
```python ```python
def get_domain(fork: Fork, def get_domain(state: BeaconState,
epoch: Epoch, domain_type: int,
domain_type: int) -> int: message_epoch: int=None) -> int:
""" """
Get the domain number that represents the fork meta and signature domain. Return the signature domain (fork version concatenated with domain type) of a message.
""" """
return bytes_to_int(get_fork_version(fork, epoch) + int_to_bytes4(domain_type)) epoch = get_current_epoch(state) if message_epoch is None else message_epoch
fork_version = state.fork.previous_version if epoch < state.fork.epoch else state.fork.current_version
return bytes_to_int(fork_version + int_to_bytes4(domain_type))
``` ```
### `get_bitfield_bit` ### `get_bitfield_bit`
@ -1115,7 +1102,7 @@ def convert_to_indexed(state: BeaconState, attestation: Attestation) -> IndexedA
custody_bit_0_indices=custody_bit_0_indices, custody_bit_0_indices=custody_bit_0_indices,
custody_bit_1_indices=custody_bit_1_indices, custody_bit_1_indices=custody_bit_1_indices,
data=attestation.data, data=attestation.data,
aggregate_signature=attestation.aggregate_signature, signature=attestation.signature,
) )
``` ```
@ -1153,8 +1140,8 @@ def verify_indexed_attestation(state: BeaconState, indexed_attestation: IndexedA
hash_tree_root(AttestationDataAndCustodyBit(data=indexed_attestation.data, custody_bit=0b0)), hash_tree_root(AttestationDataAndCustodyBit(data=indexed_attestation.data, custody_bit=0b0)),
hash_tree_root(AttestationDataAndCustodyBit(data=indexed_attestation.data, custody_bit=0b1)), hash_tree_root(AttestationDataAndCustodyBit(data=indexed_attestation.data, custody_bit=0b1)),
], ],
signature=indexed_attestation.aggregate_signature, signature=indexed_attestation.signature,
domain=get_domain(state.fork, slot_to_epoch(indexed_attestation.data.slot), DOMAIN_ATTESTATION), domain=get_domain(state, DOMAIN_ATTESTATION, slot_to_epoch(indexed_attestation.data.slot)),
) )
``` ```
@ -1947,12 +1934,7 @@ def process_block_header(state: BeaconState, block: BeaconBlock) -> None:
proposer = state.validator_registry[get_beacon_proposer_index(state)] proposer = state.validator_registry[get_beacon_proposer_index(state)]
assert not proposer.slashed assert not proposer.slashed
# Verify proposer signature # Verify proposer signature
assert bls_verify( assert bls_verify(proposer.pubkey, signing_root(block), block.signature, get_domain(state, DOMAIN_BEACON_PROPOSER))
pubkey=proposer.pubkey,
message_hash=signing_root(block),
signature=block.signature,
domain=get_domain(state.fork, get_current_epoch(state), DOMAIN_BEACON_BLOCK)
)
``` ```
#### RANDAO #### RANDAO
@ -1961,12 +1943,7 @@ def process_block_header(state: BeaconState, block: BeaconBlock) -> None:
def process_randao(state: BeaconState, block: BeaconBlock) -> None: def process_randao(state: BeaconState, block: BeaconBlock) -> None:
proposer = state.validator_registry[get_beacon_proposer_index(state)] proposer = state.validator_registry[get_beacon_proposer_index(state)]
# Verify that the provided randao value is valid # Verify that the provided randao value is valid
assert bls_verify( assert bls_verify(proposer.pubkey, hash_tree_root(get_current_epoch(state)), block.body.randao_reveal, get_domain(state, DOMAIN_RANDAO))
pubkey=proposer.pubkey,
message_hash=hash_tree_root(get_current_epoch(state)),
signature=block.body.randao_reveal,
domain=get_domain(state.fork, get_current_epoch(state), DOMAIN_RANDAO)
)
# Mix it in # Mix it in
state.latest_randao_mixes[get_current_epoch(state) % LATEST_RANDAO_MIXES_LENGTH] = ( state.latest_randao_mixes[get_current_epoch(state) % LATEST_RANDAO_MIXES_LENGTH] = (
xor(get_randao_mix(state, get_current_epoch(state)), xor(get_randao_mix(state, get_current_epoch(state)),
@ -2007,12 +1984,9 @@ def process_proposer_slashing(state: BeaconState,
assert is_slashable_validator(proposer, get_current_epoch(state)) assert is_slashable_validator(proposer, get_current_epoch(state))
# Signatures are valid # Signatures are valid
for header in (proposer_slashing.header_1, proposer_slashing.header_2): for header in (proposer_slashing.header_1, proposer_slashing.header_2):
assert bls_verify( domain = get_domain(state, DOMAIN_BEACON_PROPOSER, slot_to_epoch(header.slot))
pubkey=proposer.pubkey, assert bls_verify(proposer.pubkey, signing_root(header), header.signature, domain)
message_hash=signing_root(header),
signature=header.signature,
domain=get_domain(state.fork, slot_to_epoch(header.slot), DOMAIN_BEACON_BLOCK)
)
slash_validator(state, proposer_slashing.proposer_index) slash_validator(state, proposer_slashing.proposer_index)
``` ```
@ -2146,18 +2120,8 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None:
amount = deposit.data.amount amount = deposit.data.amount
if pubkey not in validator_pubkeys: if pubkey not in validator_pubkeys:
# Verify the proof of possession # Verify the deposit signature (proof of possession)
proof_is_valid = bls_verify( if not bls_verify(pubkey, signing_root(deposit.data), deposit.data.signature, get_domain(state, DOMAIN_DEPOSIT)):
pubkey=pubkey,
message_hash=signing_root(deposit.data),
signature=deposit.data.proof_of_possession,
domain=get_domain(
state.fork,
get_current_epoch(state),
DOMAIN_DEPOSIT,
)
)
if not proof_is_valid:
return return
# Add new validator # Add new validator
@ -2204,12 +2168,8 @@ def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None:
# Verify the validator has been active long enough # Verify the validator has been active long enough
assert get_current_epoch(state) - validator.activation_epoch >= PERSISTENT_COMMITTEE_PERIOD assert get_current_epoch(state) - validator.activation_epoch >= PERSISTENT_COMMITTEE_PERIOD
# Verify signature # Verify signature
assert bls_verify( domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, exit.epoch)
pubkey=validator.pubkey, assert bls_verify(validator.pubkey, signing_root(exit), exit.signature, domain)
message_hash=signing_root(exit),
signature=exit.signature,
domain=get_domain(state.fork, exit.epoch, DOMAIN_VOLUNTARY_EXIT)
)
# Initiate exit # Initiate exit
initiate_validator_exit(state, exit.validator_index) initiate_validator_exit(state, exit.validator_index)
``` ```
@ -2243,12 +2203,7 @@ def process_transfer(state: BeaconState, transfer: Transfer) -> None:
BLS_WITHDRAWAL_PREFIX_BYTE + hash(transfer.pubkey)[1:] BLS_WITHDRAWAL_PREFIX_BYTE + hash(transfer.pubkey)[1:]
) )
# Verify that the signature is valid # Verify that the signature is valid
assert bls_verify( assert bls_verify(transfer.pubkey, signing_root(transfer), transfer.signature, get_domain(state, DOMAIN_TRANSFER))
pubkey=transfer.pubkey,
message_hash=signing_root(transfer),
signature=transfer.signature,
domain=get_domain(state.fork, slot_to_epoch(transfer.slot), DOMAIN_TRANSFER)
)
# Process the transfer # Process the transfer
decrease_balance(state, transfer.sender, transfer.amount + transfer.fee) decrease_balance(state, transfer.sender, transfer.amount + transfer.fee)
increase_balance(state, transfer.recipient, transfer.amount) increase_balance(state, transfer.recipient, transfer.amount)

View File

@ -68,7 +68,7 @@ def set_bitfield_bit(bitfield, i):
def create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves=None): def create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves=None):
if not deposit_data_leaves: if not deposit_data_leaves:
deposit_data_leaves = [] deposit_data_leaves = []
proof_of_possession = b'\x33' * 96 signature = b'\x33' * 96
deposit_data_list = [] deposit_data_list = []
for i in range(num_validators): for i in range(num_validators):
@ -78,7 +78,7 @@ def create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves=N
# insecurely use pubkey as withdrawal key as well # insecurely use pubkey as withdrawal key as well
withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + hash(pubkey)[1:], withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + hash(pubkey)[1:],
amount=spec.MAX_DEPOSIT_AMOUNT, amount=spec.MAX_DEPOSIT_AMOUNT,
proof_of_possession=proof_of_possession, signature=signature,
) )
item = hash(deposit_data.serialize()) item = hash(deposit_data.serialize())
deposit_data_leaves.append(item) deposit_data_leaves.append(item)
@ -130,18 +130,17 @@ def build_deposit_data(state, pubkey, privkey, amount):
# insecurely use pubkey as withdrawal key as well # insecurely use pubkey as withdrawal key as well
withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + hash(pubkey)[1:], withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + hash(pubkey)[1:],
amount=amount, amount=amount,
proof_of_possession=EMPTY_SIGNATURE, signature=EMPTY_SIGNATURE,
) )
proof_of_possession = bls.sign( signature = bls.sign(
message_hash=signing_root(deposit_data), message_hash=signing_root(deposit_data),
privkey=privkey, privkey=privkey,
domain=get_domain( domain=get_domain(
state.fork, state,
get_current_epoch(state),
spec.DOMAIN_DEPOSIT, spec.DOMAIN_DEPOSIT,
) )
) )
deposit_data.proof_of_possession = proof_of_possession deposit_data.signature = signature
return deposit_data return deposit_data
@ -192,9 +191,9 @@ def build_voluntary_exit(state, epoch, validator_index, privkey):
message_hash=signing_root(voluntary_exit), message_hash=signing_root(voluntary_exit),
privkey=privkey, privkey=privkey,
domain=get_domain( domain=get_domain(
fork=state.fork, state=state,
epoch=epoch,
domain_type=spec.DOMAIN_VOLUNTARY_EXIT, domain_type=spec.DOMAIN_VOLUNTARY_EXIT,
message_epoch=epoch,
) )
) )
@ -243,9 +242,8 @@ def get_valid_proposer_slashing(state):
header_2.slot = slot + 1 header_2.slot = slot + 1
domain = get_domain( domain = get_domain(
fork=state.fork, state=state,
epoch=get_current_epoch(state), domain_type=spec.DOMAIN_BEACON_PROPOSER,
domain_type=spec.DOMAIN_BEACON_BLOCK,
) )
header_1.signature = bls.sign( header_1.signature = bls.sign(
message_hash=signing_root(header_1), message_hash=signing_root(header_1),
@ -340,9 +338,9 @@ def get_attestation_signature(state, attestation_data, privkey, custody_bit=0b0)
message_hash=message_hash, message_hash=message_hash,
privkey=privkey, privkey=privkey,
domain=get_domain( domain=get_domain(
fork=state.fork, state=state,
epoch=slot_to_epoch(attestation_data.slot),
domain_type=spec.DOMAIN_ATTESTATION, domain_type=spec.DOMAIN_ATTESTATION,
message_epoch=slot_to_epoch(attestation_data.slot),
) )
) )

View File

@ -356,8 +356,7 @@ def test_voluntary_exit(state):
message_hash=signing_root(voluntary_exit), message_hash=signing_root(voluntary_exit),
privkey=privkeys[validator_index], privkey=privkeys[validator_index],
domain=get_domain( domain=get_domain(
fork=pre_state.fork, state=pre_state,
epoch=get_current_epoch(pre_state),
domain_type=spec.DOMAIN_VOLUNTARY_EXIT, domain_type=spec.DOMAIN_VOLUNTARY_EXIT,
) )
) )
@ -405,8 +404,7 @@ def test_transfer(state):
message_hash=signing_root(transfer), message_hash=signing_root(transfer),
privkey=transfer_privkey, privkey=transfer_privkey,
domain=get_domain( domain=get_domain(
fork=pre_state.fork, state=pre_state,
epoch=get_current_epoch(pre_state),
domain_type=spec.DOMAIN_TRANSFER, domain_type=spec.DOMAIN_TRANSFER,
) )
) )