working through shard chain tests

This commit is contained in:
Danny Ryan 2019-09-27 13:02:16 +09:00
parent 86ed3937dc
commit b892d46f26
No known key found for this signature in database
GPG Key ID: 2765A792E42CE07A
5 changed files with 71 additions and 60 deletions

View File

@ -81,7 +81,7 @@ def get_spec(file_name: str) -> SpecObject:
if c not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789':
is_constant_def = False
if is_constant_def:
constants[row[0]] = row[1].replace('**TBD**', '0x1234567890123456789012345678901234567890')
constants[row[0]] = row[1].replace('**TBD**', '2**32')
elif row[1].startswith('uint') or row[1].startswith('Bytes'):
custom_types[row[0]] = row[1]
return functions, custom_types, constants, ssz_objects, inserts

View File

@ -248,6 +248,11 @@ def get_genesis_shard_state(shard: Shard) -> ShardState:
return ShardState(
shard=shard,
slot=ShardSlot(SHARD_GENESIS_EPOCH * SHARD_SLOTS_PER_EPOCH),
latest_block_header=ShardBlockHeader(
shard=shard,
slot=ShardSlot(SHARD_GENESIS_EPOCH * SHARD_SLOTS_PER_EPOCH),
body_root=hash_tree_root(List[byte, MAX_SHARD_BLOCK_SIZE - SHARD_HEADER_SIZE]()),
),
block_body_price=MIN_BLOCK_BODY_PRICE,
)
```
@ -335,9 +340,14 @@ def process_shard_block_header(beacon_state: BeaconState, shard_state: ShardStat
assert block.slot == shard_state.slot
# Verify the beacon chain root
parent_epoch = compute_epoch_of_shard_slot(shard_state.latest_block_header.slot)
assert block.beacon_block_root == get_block_root(beacon_state, parent_epoch)
# --super dirty. need to think-- #
if parent_epoch * SLOTS_PER_EPOCH == beacon_state.slot:
beacon_block_root = signing_root(beacon_state.latest_block_header)
else:
beacon_block_root = get_block_root(beacon_state, parent_epoch)
assert block.beacon_block_root == beacon_block_root
# Verify the parent root
assert block.parent_root == hash_tree_root(shard_state.latest_block_header)
assert block.parent_root == signing_root(shard_state.latest_block_header)
# Save current block as the new latest block
shard_state.latest_block_header = ShardBlockHeader(
shard=block.shard,
@ -376,12 +386,17 @@ def process_shard_attestations(beacon_state: BeaconState, shard_state: ShardStat
pubkeys.append(beacon_state.validators[validator_index].pubkey)
process_delta(beacon_state, shard_state, validator_index, get_base_reward(beacon_state, validator_index))
attestation_count += 1
# Exit early if no participants
if not any(pubkeys):
assert block.attestations == BLSSignature()
return
# Verify there are no extraneous bits set beyond the shard committee
for i in range(len(shard_committee), 2 * MAX_PERIOD_COMMITTEE_SIZE):
assert block.aggregation_bits[i] == 0b0
# Verify attester aggregate signature
domain = get_domain(beacon_state, DOMAIN_SHARD_ATTESTER, compute_epoch_of_shard_slot(block.slot))
message = hash_tree_root(ShardAttestationData(shard_state.slot, block.parent_root))
message = hash_tree_root(ShardAttestationData(slot=shard_state.slot, parent_root=block.parent_root))
assert bls_verify(bls_aggregate_pubkeys(pubkeys), message, block.attestations, domain)
# Proposer micro-reward
proposer_index = get_shard_proposer_index(beacon_state, shard_state.shard, block.slot)

View File

@ -5,17 +5,20 @@ from eth2spec.utils.bls import (
)
def sign_shard_attestation(spec, shard_state, beacon_state, block, participants):
def sign_shard_attestation(spec, beacon_state, shard_state, block, participants):
signatures = []
message_hash = block.core.parent_root
block_epoch = spec.compute_epoch_of_shard_slot(block.core.slot)
message_hash = spec.ShardAttestationData(
slot=block.slot,
parent_root=block.parent_root,
).hash_tree_root()
block_epoch = spec.compute_epoch_of_shard_slot(block.slot)
for validator_index in participants:
privkey = privkeys[validator_index]
signatures.append(
get_attestation_signature(
spec,
shard_state,
beacon_state,
shard_state,
message_hash,
block_epoch,
privkey,
@ -25,7 +28,7 @@ def sign_shard_attestation(spec, shard_state, beacon_state, block, participants)
return bls_aggregate_signatures(signatures)
def get_attestation_signature(spec, shard_state, beacon_state, message_hash, block_epoch, privkey):
def get_attestation_signature(spec, beacon_state, shard_state, message_hash, block_epoch, privkey):
return bls_sign(
message_hash=message_hash,
privkey=privkey,

View File

@ -1,3 +1,5 @@
from copy import deepcopy
from eth2spec.test.helpers.keys import privkeys
from eth2spec.utils.bls import (
bls_sign,
@ -13,66 +15,63 @@ from .attestations import (
@only_with_bls()
def sign_shard_block(spec, state, block, shard, proposer_index=None):
def sign_shard_block(spec, beacon_state, block, shard, proposer_index=None):
if proposer_index is None:
proposer_index = spec.get_shard_block_proposer_index(state, shard, block.core.slot)
proposer_index = spec.get_shard_proposer_index(beacon_state, shard, block.slot)
privkey = privkeys[proposer_index]
block.signatures.proposer_signature = bls_sign(
block.signature = bls_sign(
message_hash=signing_root(block),
privkey=privkey,
domain=spec.get_domain(
state,
beacon_state,
spec.DOMAIN_SHARD_PROPOSER,
spec.compute_epoch_of_shard_slot(block.core.slot),
spec.compute_epoch_of_shard_slot(block.slot),
)
)
def build_empty_shard_block(spec,
shard_state,
beacon_state,
shard_state,
slot,
parent_root,
signed=False,
full_attestation=False):
if slot is None:
slot = shard_state.slot
parent_epoch = spec.compute_epoch_of_shard_slot(shard_state.latest_block_header.slot)
if parent_epoch * spec.SLOTS_PER_EPOCH == beacon_state.slot:
beacon_block_root = spec.signing_root(beacon_state.latest_block_header)
else:
beacon_block_root = spec.get_block_root(beacon_state, parent_epoch)
previous_block_header = deepcopy(shard_state.latest_block_header)
if previous_block_header.state_root == spec.Hash():
previous_block_header.state_root = shard_state.hash_tree_root()
parent_root = signing_root(previous_block_header)
block = spec.ShardBlock(
core=spec.ExtendedShardBlockCore(
slot=slot,
beacon_chain_root=beacon_state.block_roots[beacon_state.slot % spec.SLOTS_PER_HISTORICAL_ROOT],
parent_root=parent_root,
),
signatures=spec.ShardBlockSignatures(
attestation_signature=b'\x00' * 96,
proposer_signature=b'\x25' * 96,
)
shard=shard_state.shard,
slot=slot,
beacon_block_root=beacon_block_root,
parent_root=parent_root,
block_size_sum=shard_state.block_size_sum + spec.SHARD_HEADER_SIZE,
)
# attestation
if full_attestation:
attester_committee = spec.get_persistent_committee(beacon_state, shard_state.shard, block.core.slot)
block.core.attester_bitfield = list(
(True,) * len(attester_committee) +
(False,) * (spec.TARGET_PERSISTENT_COMMITTEE_SIZE * 2 - len(attester_committee))
shard_committee = spec.get_shard_committee(beacon_state, shard_state.shard, block.slot)
block.aggregation_bits = list(
(True,) * len(shard_committee) +
(False,) * (spec.MAX_PERIOD_COMMITTEE_SIZE * 2 - len(shard_committee))
)
block.signatures.attestation_signature = sign_shard_attestation(
block.attestations = sign_shard_attestation(
spec,
shard_state,
beacon_state,
block,
participants=attester_committee,
)
else:
block.signatures.attestation_signature = sign_shard_attestation(
spec,
shard_state,
beacon_state,
block,
participants=(),
participants=shard_committee,
)
if signed:

View File

@ -9,22 +9,19 @@ from eth2spec.test.context import (
@with_all_phases_except(['phase0'])
@always_bls
@spec_state_test
@always_bls
def test_process_empty_shard_block(spec, state):
beacon_state = state
shard_slot = spec.PHASE_1_FORK_SLOT
beacon_state.slot = spec.Slot(spec.PHASE_1_FORK_EPOCH * spec.SLOTS_PER_EPOCH)
shard_state = spec.get_default_shard_state(beacon_state, shard=spec.Shard(0))
shard_state.slot = shard_slot
beacon_state.slot = spec.Slot(spec.SHARD_GENESIS_EPOCH * spec.SLOTS_PER_EPOCH)
shard_state = spec.get_genesis_shard_state(spec.Shard(0))
shard_state.slot = spec.ShardSlot(spec.SHARD_GENESIS_EPOCH * spec.SHARD_SLOTS_PER_EPOCH)
block = build_empty_shard_block(
spec,
shard_state,
beacon_state,
slot=shard_slot + 1,
parent_root=spec.Hash(),
shard_state,
slot=shard_state.slot + 1,
signed=True,
full_attestation=False,
)
@ -33,28 +30,25 @@ def test_process_empty_shard_block(spec, state):
yield 'beacon_state', beacon_state
yield 'block', block
spec.shard_state_transition(shard_state, beacon_state, block)
spec.shard_state_transition(beacon_state, shard_state, block)
yield 'post', shard_state
@with_all_phases_except(['phase0'])
@always_bls
@spec_state_test
@always_bls
def test_process_full_attestation_shard_block(spec, state):
beacon_state = state
shard_slot = spec.PHASE_1_FORK_SLOT
beacon_state.slot = spec.Slot(spec.PHASE_1_FORK_EPOCH * spec.SLOTS_PER_EPOCH)
shard_state = spec.get_default_shard_state(beacon_state, shard=spec.Shard(0))
shard_state.slot = shard_slot
beacon_state.slot = spec.Slot(spec.SHARD_GENESIS_EPOCH * spec.SLOTS_PER_EPOCH)
shard_state = spec.get_genesis_shard_state(spec.Shard(0))
shard_state.slot = spec.SHARD_GENESIS_EPOCH * spec.SHARD_SLOTS_PER_EPOCH
block = build_empty_shard_block(
spec,
shard_state,
beacon_state,
slot=shard_slot + 1,
parent_root=spec.Hash(),
shard_state,
slot=shard_state.slot + 1,
signed=True,
full_attestation=True,
)
@ -63,6 +57,6 @@ def test_process_full_attestation_shard_block(spec, state):
yield 'beacon_state', beacon_state
yield 'block', block
spec.shard_state_transition(shard_state, beacon_state, block)
spec.shard_state_transition(beacon_state, shard_state, block)
yield 'post', shard_state