Custody tests

This commit is contained in:
Dankrad Feist 2020-06-12 22:47:45 +01:00
parent 04fb9926e8
commit f857dbfac2
No known key found for this signature in database
GPG Key ID: 6815E6A20BEBBABA
2 changed files with 111 additions and 38 deletions

View File

@ -59,7 +59,7 @@ def bitlist_from_int(max_len, num_bits, n):
return Bitlist[max_len](*[(n >> i) & 0b1 for i in range(num_bits)]) return Bitlist[max_len](*[(n >> i) & 0b1 for i in range(num_bits)])
def get_valid_custody_slashing(spec, state, attestation, shard_transition, invalid_custody_bit=False): def get_valid_custody_slashing(spec, state, attestation, shard_transition, custody_secret, data, data_index=0):
beacon_committee = spec.get_beacon_committee( beacon_committee = spec.get_beacon_committee(
state, state,
attestation.data.slot, attestation.data.slot,
@ -68,21 +68,10 @@ def get_valid_custody_slashing(spec, state, attestation, shard_transition, inval
malefactor_index = beacon_committee[0] malefactor_index = beacon_committee[0]
whistleblower_index = beacon_committee[-1] whistleblower_index = beacon_committee[-1]
epoch = spec.get_randao_epoch_for_custody_period(attestation.data.target.epoch,
malefactor_index)
# Generate the responder key
domain = spec.get_domain(state, spec.DOMAIN_RANDAO, epoch)
signing_root = spec.compute_signing_root(spec.Epoch(epoch), domain)
malefactor_key = bls.Sign(privkeys[malefactor_index], signing_root)
data_index = 0
data = ByteList[spec.MAX_SHARD_BLOCK_SIZE](
get_custody_test_vector(shard_transition.shard_block_lengths[data_index]))
slashing = spec.CustodySlashing( slashing = spec.CustodySlashing(
data_index=data_index, data_index=data_index,
malefactor_index=malefactor_index, malefactor_index=malefactor_index,
malefactor_secret=malefactor_key, malefactor_secret=custody_secret,
whistleblower_index=whistleblower_index, whistleblower_index=whistleblower_index,
shard_transition=shard_transition, shard_transition=shard_transition,
attestation=attestation, attestation=attestation,
@ -165,9 +154,9 @@ def get_valid_custody_chunk_response(spec, state, chunk_challenge, block_length,
) )
def get_custody_test_vector(bytelength): def get_custody_test_vector(bytelength, offset=0):
ints = bytelength // 4 + 1 ints = bytelength // 4 + 1
return (b"".join(i.to_bytes(4, "little") for i in range(ints)))[:bytelength] return (b"".join((i + offset).to_bytes(4, "little") for i in range(ints)))[:bytelength]
def get_shard_transition(spec, start_slot, block_lengths): def get_shard_transition(spec, start_slot, block_lengths):
@ -181,3 +170,30 @@ def get_shard_transition(spec, start_slot, block_lengths):
proposer_signature_aggregate=spec.BLSSignature(), proposer_signature_aggregate=spec.BLSSignature(),
) )
return shard_transition return shard_transition
def get_custody_secret(spec, state, validator_index, epoch=None):
period = spec.get_custody_period_for_validator(validator_index, epoch if epoch is not None
else spec.get_current_epoch(state))
epoch_to_sign = spec.get_randao_epoch_for_custody_period(period, validator_index)
domain = spec.get_domain(state, spec.DOMAIN_RANDAO, epoch_to_sign)
signing_root = spec.compute_signing_root(spec.Epoch(epoch_to_sign), domain)
return bls.Sign(privkeys[validator_index], signing_root)
def get_custody_slashable_test_vector(spec, custody_secret, length, slashable=True):
test_vector = get_custody_test_vector(length)
offset = 0
while spec.compute_custody_bit(custody_secret, test_vector) != slashable:
offset += 1
test_vector = test_vector = get_custody_test_vector(length, offset)
return test_vector
def get_custody_slashable_shard_transition(spec, start_slot, block_lengths, custody_secret, slashable=True):
shard_transition = get_shard_transition(spec, start_slot, block_lengths)
slashable_test_vector = get_custody_slashable_test_vector(spec, custody_secret,
block_lengths[0], slashable=slashable)
shard_transition.shard_data_roots[0] = ByteList[spec.MAX_SHARD_BLOCK_SIZE](slashable_test_vector) \
.get_backing().get_left().merkle_root()
return shard_transition, slashable_test_vector

View File

@ -1,6 +1,7 @@
from eth2spec.test.helpers.custody import ( from eth2spec.test.helpers.custody import (
get_valid_custody_slashing, get_valid_custody_slashing,
get_shard_transition, get_custody_secret,
get_custody_slashable_shard_transition,
) )
from eth2spec.test.helpers.attestations import ( from eth2spec.test.helpers.attestations import (
get_valid_on_time_attestation, get_valid_on_time_attestation,
@ -58,9 +59,18 @@ def test_custody_slashing(spec, state):
transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH) transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH)
shard = 0 shard = 0
offset_slots = spec.get_offset_slots(state, shard) offset_slots = spec.get_offset_slots(state, shard)
shard_transition = get_shard_transition(spec, state.slot, [2**15 // 3] * len(offset_slots))
validator_index = spec.get_beacon_committee(
state,
state.slot,
shard,
)[0]
custody_secret = get_custody_secret(spec, state, validator_index)
shard_transition, slashable_test_vector = get_custody_slashable_shard_transition(spec, state.slot,
[2**15 // 3] * len(offset_slots), custody_secret)
attestation = get_valid_on_time_attestation(spec, state, index=shard, signed=True, attestation = get_valid_on_time_attestation(spec, state, index=shard, signed=True,
shard_transition=shard_transition, valid_custody_bits=False) shard_transition=shard_transition)
transition_to(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) transition_to(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY)
@ -68,8 +78,8 @@ def test_custody_slashing(spec, state):
transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * (spec.EPOCHS_PER_CUSTODY_PERIOD - 1)) transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * (spec.EPOCHS_PER_CUSTODY_PERIOD - 1))
slashing = get_valid_custody_slashing(spec, state, attestation, shard_transition) slashing = get_valid_custody_slashing(spec, state, attestation, shard_transition,
custody_secret, slashable_test_vector)
yield from run_custody_slashing_processing(spec, state, slashing, correct=True) yield from run_custody_slashing_processing(spec, state, slashing, correct=True)
@ -79,9 +89,18 @@ def test_incorrect_custody_slashing(spec, state):
transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH) transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH)
shard = 0 shard = 0
offset_slots = spec.get_offset_slots(state, shard) offset_slots = spec.get_offset_slots(state, shard)
shard_transition = get_shard_transition(spec, state.slot, [2**15 // 3] * len(offset_slots))
validator_index = spec.get_beacon_committee(
state,
state.slot,
shard,
)[0]
custody_secret = get_custody_secret(spec, state, validator_index)
shard_transition, slashable_test_vector = get_custody_slashable_shard_transition(spec, state.slot,
[2**15 // 3] * len(offset_slots), custody_secret, slashable=False)
attestation = get_valid_on_time_attestation(spec, state, index=shard, signed=True, attestation = get_valid_on_time_attestation(spec, state, index=shard, signed=True,
shard_transition=shard_transition, valid_custody_bits=True) shard_transition=shard_transition)
transition_to(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) transition_to(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY)
@ -89,7 +108,8 @@ def test_incorrect_custody_slashing(spec, state):
transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * (spec.EPOCHS_PER_CUSTODY_PERIOD - 1)) transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * (spec.EPOCHS_PER_CUSTODY_PERIOD - 1))
slashing = get_valid_custody_slashing(spec, state, attestation, shard_transition) slashing = get_valid_custody_slashing(spec, state, attestation,
shard_transition, custody_secret, slashable_test_vector)
yield from run_custody_slashing_processing(spec, state, slashing, correct=False) yield from run_custody_slashing_processing(spec, state, slashing, correct=False)
@ -100,9 +120,18 @@ def test_multiple_epochs_custody(spec, state):
transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * 3) transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * 3)
shard = 0 shard = 0
offset_slots = spec.get_offset_slots(state, shard) offset_slots = spec.get_offset_slots(state, shard)
shard_transition = get_shard_transition(spec, state.slot, [2**15 // 3] * len(offset_slots))
validator_index = spec.get_beacon_committee(
state,
state.slot,
shard,
)[0]
custody_secret = get_custody_secret(spec, state, validator_index)
shard_transition, slashable_test_vector = get_custody_slashable_shard_transition(spec, state.slot,
[2**15 // 3] * len(offset_slots), custody_secret)
attestation = get_valid_on_time_attestation(spec, state, index=shard, signed=True, attestation = get_valid_on_time_attestation(spec, state, index=shard, signed=True,
shard_transition=shard_transition, valid_custody_bits=False) shard_transition=shard_transition)
transition_to(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) transition_to(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY)
@ -110,8 +139,8 @@ def test_multiple_epochs_custody(spec, state):
transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * (spec.EPOCHS_PER_CUSTODY_PERIOD - 1)) transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * (spec.EPOCHS_PER_CUSTODY_PERIOD - 1))
slashing = get_valid_custody_slashing(spec, state, attestation, shard_transition) slashing = get_valid_custody_slashing(spec, state, attestation, shard_transition,
custody_secret, slashable_test_vector)
yield from run_custody_slashing_processing(spec, state, slashing, correct=True) yield from run_custody_slashing_processing(spec, state, slashing, correct=True)
@ -121,9 +150,18 @@ def test_many_epochs_custody(spec, state):
transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * 20) transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * 20)
shard = 0 shard = 0
offset_slots = spec.get_offset_slots(state, shard) offset_slots = spec.get_offset_slots(state, shard)
shard_transition = get_shard_transition(spec, state.slot, [2**15 // 3] * len(offset_slots))
validator_index = spec.get_beacon_committee(
state,
state.slot,
shard,
)[0]
custody_secret = get_custody_secret(spec, state, validator_index)
shard_transition, slashable_test_vector = get_custody_slashable_shard_transition(spec, state.slot,
[2**15 // 3] * len(offset_slots), custody_secret)
attestation = get_valid_on_time_attestation(spec, state, index=shard, signed=True, attestation = get_valid_on_time_attestation(spec, state, index=shard, signed=True,
shard_transition=shard_transition, valid_custody_bits=False) shard_transition=shard_transition)
transition_to(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) transition_to(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY)
@ -131,8 +169,8 @@ def test_many_epochs_custody(spec, state):
transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * (spec.EPOCHS_PER_CUSTODY_PERIOD - 1)) transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * (spec.EPOCHS_PER_CUSTODY_PERIOD - 1))
slashing = get_valid_custody_slashing(spec, state, attestation, shard_transition) slashing = get_valid_custody_slashing(spec, state, attestation, shard_transition,
custody_secret, slashable_test_vector)
yield from run_custody_slashing_processing(spec, state, slashing, correct=True) yield from run_custody_slashing_processing(spec, state, slashing, correct=True)
@ -142,14 +180,23 @@ def test_off_chain_attestation(spec, state):
transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH) transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH)
shard = 0 shard = 0
offset_slots = spec.get_offset_slots(state, shard) offset_slots = spec.get_offset_slots(state, shard)
shard_transition = get_shard_transition(spec, state.slot, [2**15 // 3] * len(offset_slots))
validator_index = spec.get_beacon_committee(
state,
state.slot,
shard,
)[0]
custody_secret = get_custody_secret(spec, state, validator_index)
shard_transition, slashable_test_vector = get_custody_slashable_shard_transition(spec, state.slot,
[2**15 // 3] * len(offset_slots), custody_secret)
attestation = get_valid_on_time_attestation(spec, state, index=shard, signed=True, attestation = get_valid_on_time_attestation(spec, state, index=shard, signed=True,
shard_transition=shard_transition, valid_custody_bits=False) shard_transition=shard_transition)
transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * (spec.EPOCHS_PER_CUSTODY_PERIOD - 1)) transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * (spec.EPOCHS_PER_CUSTODY_PERIOD - 1))
slashing = get_valid_custody_slashing(spec, state, attestation, shard_transition) slashing = get_valid_custody_slashing(spec, state, attestation, shard_transition,
custody_secret, slashable_test_vector)
yield from run_custody_slashing_processing(spec, state, slashing, correct=True) yield from run_custody_slashing_processing(spec, state, slashing, correct=True)
@ -159,9 +206,18 @@ def test_invalid_custody_slashing(spec, state):
transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH) transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH)
shard = 0 shard = 0
offset_slots = spec.get_offset_slots(state, shard) offset_slots = spec.get_offset_slots(state, shard)
shard_transition = get_shard_transition(spec, state.slot, [2**15 // 3] * len(offset_slots))
validator_index = spec.get_beacon_committee(
state,
state.slot,
shard,
)[0]
custody_secret = get_custody_secret(spec, state, validator_index)
shard_transition, slashable_test_vector = get_custody_slashable_shard_transition(spec, state.slot,
[2**15 // 3] * len(offset_slots), custody_secret)
attestation = get_valid_on_time_attestation(spec, state, index=shard, signed=True, attestation = get_valid_on_time_attestation(spec, state, index=shard, signed=True,
shard_transition=shard_transition, valid_custody_bits=False) shard_transition=shard_transition)
transition_to(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) transition_to(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY)
@ -169,7 +225,8 @@ def test_invalid_custody_slashing(spec, state):
transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * (spec.EPOCHS_PER_CUSTODY_PERIOD - 1)) transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * (spec.EPOCHS_PER_CUSTODY_PERIOD - 1))
slashing = get_valid_custody_slashing(spec, state, attestation, shard_transition) slashing = get_valid_custody_slashing(spec, state, attestation, shard_transition,
custody_secret, slashable_test_vector)
slashing.message.data = ByteList[spec.MAX_SHARD_BLOCK_SIZE]() slashing.message.data = ByteList[spec.MAX_SHARD_BLOCK_SIZE]()