def build_aggregate(attestations): # All attestations are from the same slot, committee index and vote for # same source, target and beacon block. if len(attestations) == 0: return [] aggregation_bits = Bitlist[specs.MAX_VALIDATORS_PER_COMMITTEE]( *([0] * len(attestations[0].aggregation_bits))) for attestation in attestations: validator_index_in_committee = attestation.aggregation_bits.index(1) aggregation_bits[validator_index_in_committee] = True return specs.Attestation(aggregation_bits=aggregation_bits, data=attestations[0].data)
def honest_attest(validator, known_items): # Unpacking validator_index = validator.validator_index store = validator.store committee_slot = validator.data.current_attest_slot committee_index = validator.data.current_committee_index committee = validator.data.current_committee # What am I attesting for? block_root = validator.get_head() head_state = store.block_states[block_root].copy() if head_state.slot < committee_slot: specs.process_slots(head_state, committee_slot) start_slot = specs.compute_start_slot_at_epoch( specs.get_current_epoch(head_state)) epoch_boundary_block_root = block_root if start_slot == head_state.slot else specs.get_block_root_at_slot( head_state, start_slot) tgt_checkpoint = specs.Checkpoint( epoch=specs.get_current_epoch(head_state), root=epoch_boundary_block_root) att_data = specs.AttestationData( index=committee_index, slot=committee_slot, beacon_block_root=block_root, source=head_state.current_justified_checkpoint, target=tgt_checkpoint) # Set aggregation bits to myself only committee_size = len(committee) index_in_committee = committee.index(validator_index) aggregation_bits = Bitlist[specs.MAX_VALIDATORS_PER_COMMITTEE]( *([0] * committee_size)) aggregation_bits[ index_in_committee] = True # set the aggregation bit of the validator to True attestation = specs.Attestation(aggregation_bits=aggregation_bits, data=att_data) # print(validator.validator_index, "attests for slot", committee_slot) return attestation
def honest_attest(state, validator_index): # Given state w-[s], validators in committees of slot `s-1` form their attestations # In several places here, we need to check whether `s` is the first slot of a new epoch. current_epoch = specs.get_current_epoch(state) previous_epoch = specs.get_previous_epoch(state) # Since everyone is honest, we can assume that validators attesting during some epoch e # choose the first block of e as their target, and the first block of e-1 as their source # checkpoint. # # So let's assume the validator here is making an attestation at slot s in epoch e: # # - If the `state` variable is at epoch e, then the first block of epoch e-1 is # a checkpoint held in `state.current_justified_checkpoint`. # The target checkpoint root is obtained by calling # `get_block_root(state, current_epoch)` (since current_epoch = e). # # - If the `state` variable is at epoch e+1, then the first block of epoch e-1 # is a checkpoint held in `state.previous_justified_checkpoint`, # since in the meantime the first block of e was justified. # This is the case when s is the last slot of epoch e. # The target checkpoint root is obtained by calling # `get_block_root(state, previous_epoch)` (since current_epoch = e+1). # # ... still here? # If `state` is already at the start of a new epoch e+1 if state.slot == specs.compute_start_slot_at_epoch(current_epoch): # `committee_slot` is equal to s-1 (committee, committee_index, committee_slot) = specs.get_committee_assignment( state, previous_epoch, validator_index) # Since we are at state w-[s], we can get the block root of the block at slot s-1. block_root = specs.get_block_root_at_slot(state, committee_slot) src_checkpoint = specs.Checkpoint( epoch=state.previous_justified_checkpoint.epoch, root=state.previous_justified_checkpoint.root) tgt_checkpoint = specs.Checkpoint(epoch=previous_epoch, root=specs.get_block_root( state, previous_epoch)) # Otherwise, if `state` is at epoch e else: # `committee_slot` is equal to s-1 (committee, committee_index, committee_slot) = specs.get_committee_assignment( state, current_epoch, validator_index) # Since we are at state w-[s], we can get the block root of the block at slot s-1. block_root = specs.get_block_root_at_slot(state, committee_slot) src_checkpoint = specs.Checkpoint( epoch=state.current_justified_checkpoint.epoch, root=state.current_justified_checkpoint.root) tgt_checkpoint = specs.Checkpoint(epoch=current_epoch, root=specs.get_block_root( state, current_epoch)) att_data = specs.AttestationData(index=committee_index, slot=committee_slot, beacon_block_root=block_root, source=src_checkpoint, target=tgt_checkpoint) # if log: print("attestation for source", src_checkpoint.epoch, "and target", tgt_checkpoint.epoch) # For now we disregard aggregation of attestations. # Some validators are chosen as aggregators: they take a bunch of identical attestations # and join them together in one object, # with `aggregation_bits` identifying which validators are part of the aggregation. committee_size = len(committee) index_in_committee = committee.index(validator_index) aggregation_bits = Bitlist[specs.MAX_VALIDATORS_PER_COMMITTEE]( *([0] * committee_size)) aggregation_bits[ index_in_committee] = True # set the aggregation bits of the validator to True attestation = specs.Attestation(aggregation_bits=aggregation_bits, data=att_data) return attestation