Replace with empty instead of popping finished challenges

This commit is contained in:
vbuterin 2019-03-31 21:20:43 -05:00 committed by GitHub
parent f5c5c166af
commit 3fc24f3d41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 36 additions and 8 deletions

View File

@ -31,6 +31,7 @@
- [`get_crosslink_chunk_count`](#get_crosslink_chunk_count)
- [`get_custody_chunk_bit`](#get_custody_chunk_bit)
- [`epoch_to_custody_period`](#epoch_to_custody_period)
- [`replace_empty_or_append`](#replace_empty_or_append)
- [`verify_custody_key`](#verify_custody_key)
- [Per-block processing](#per-block-processing)
- [Transactions](#transactions)
@ -229,6 +230,18 @@ def epoch_to_custody_period(epoch: Epoch) -> int:
return epoch // EPOCHS_PER_CUSTODY_PERIOD
```
### `replace_empty_or_append`
```python
def replace_empty_or_append(list: List[Any], empty_element: Any, new_element: Any) -> int:
for i in range(len(list)):
if list[i] == empty_element:
list[i] = new_element
return i
list.append(new_element)
return len(list) - 1
```
### `verify_custody_key`
```python
@ -321,7 +334,7 @@ def process_chunk_challenge(state: BeaconState,
depth = math.log2(next_power_of_two(get_custody_chunk_count(challenge.attestation)))
assert challenge.chunk_index < 2**depth
# Add new chunk challenge record
state.custody_chunk_challenge_records.append(CustodyChunkChallengeRecord(
new_record = CustodyChunkChallengeRecord(
challenge_index=state.custody_challenge_index,
challenger_index=get_beacon_proposer_index(state, state.slot),
responder_index=challenge.responder_index
@ -329,7 +342,13 @@ def process_chunk_challenge(state: BeaconState,
crosslink_data_root=challenge.attestation.data.crosslink_data_root,
depth=depth,
chunk_index=challenge.chunk_index,
))
)
replace_empty_or_append(
list=state.custody_chunk_challenge_records,
empty_element=CustodyChunkChallengeRecord(),
new_element=new_record
)
state.custody_challenge_index += 1
# Postpone responder withdrawability
responder.withdrawable_epoch = FAR_FUTURE_EPOCH
@ -385,7 +404,7 @@ def process_bit_challenge(state: BeaconState,
custody_bit = get_bitfield_bit(attestation.custody_bitfield, attesters.index(responder_index))
assert custody_bit != chunk_bits_xor
# Add new bit challenge record
state.custody_bit_challenge_records.append(CustodyBitChallengeRecord(
new_record = CustodyBitChallengeRecord(
challenge_index=state.custody_challenge_index,
challenger_index=challenge.challenger_index,
responder_index=challenge.responder_index,
@ -393,7 +412,12 @@ def process_bit_challenge(state: BeaconState,
crosslink_data_root=challenge.attestation.crosslink_data_root,
chunk_bits=challenge.chunk_bits,
responder_key=challenge.responder_key,
))
)
replace_empty_or_append(
list=state.custody_bit_challenge_records,
empty_element=CustodyBitChallengeRecord(),
new_element=new_record
)
state.custody_challenge_index += 1
# Postpone responder withdrawability
responder.withdrawable_epoch = FAR_FUTURE_EPOCH
@ -434,7 +458,8 @@ def process_chunk_challenge_response(state: BeaconState,
root=challenge.crosslink_data_root,
)
# Clear the challenge
state.custody_chunk_challenge_records.remove(challenge)
records = state.custody_chunk_challenge_records
records[records.index(challenge)] = CustodyChunkChallengeRecord()
# Reward the proposer
proposer_index = get_beacon_proposer_index(state, state.slot)
increase_balance(state, proposer_index, base_reward(state, index) // MINOR_REWARD_QUOTIENT)
@ -457,7 +482,8 @@ def process_bit_challenge_response(state: BeaconState,
# Verify the chunk bit does not match the challenge chunk bit
assert get_custody_chunk_bit(challenge.responder_key, response.chunk) != get_bitfield_bit(challenge.chunk_bits, response.chunk_index)
# Clear the challenge
state.custody_bit_challenge_records.remove(challenge)
records = state.custody_bit_challenge_records
records[records.index(challenge)] = CustodyBitChallengeRecord()
# Slash challenger
slash_validator(state, challenge.challenger_index, challenge.responder_index)
```
@ -471,12 +497,14 @@ def process_challenge_deadlines(state: BeaconState) -> None:
for challenge in state.custody_chunk_challenge_records:
if get_current_epoch(state) > challenge.deadline:
slash_validator(state, challenge.responder_index, challenge.challenger_index)
state.custody_chunk_challenge_records.remove(challenge)
records = state.custody_chunk_challenge_records
records[records.index(challenge)] = CustodyChunkChallengeRecord()
for challenge in state.custody_bit_challenge_records:
if get_current_epoch(state) > challenge.deadline:
slash_validator(state, challenge.responder_index, challenge.challenger_index)
state.custody_bit_challenge_records.remove(challenge)
records = state.custody_bit_challenge_records
records[records.index(challenge)] = CustodyBitChallengeRecord()
```
In `process_penalties_and_exits`, change the definition of `eligible` to the following (note that it is not a pure function because `state` is declared in the surrounding scope):