Merge pull request #2849 from ethereum/yield-attester-slashing

Output `attester_slashing` data to fork choice test vectors
This commit is contained in:
Hsiao-Wei Wang 2022-03-14 07:14:14 -07:00 committed by GitHub
commit 3458d12c2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 8 deletions

View File

@ -92,6 +92,10 @@ def get_attestation_file_name(attestation):
return f"attestation_{encode_hex(attestation.hash_tree_root())}" return f"attestation_{encode_hex(attestation.hash_tree_root())}"
def get_attester_slashing_file_name(attester_slashing):
return f"attester_slashing_{encode_hex(attester_slashing.hash_tree_root())}"
def on_tick_and_append_step(spec, store, time, test_steps): def on_tick_and_append_step(spec, store, time, test_steps):
spec.on_tick(store, time) spec.on_tick(store, time)
test_steps.append({'tick': int(time)}) test_steps.append({'tick': int(time)})
@ -142,6 +146,10 @@ def add_block(spec,
for attestation in signed_block.message.body.attestations: for attestation in signed_block.message.body.attestations:
run_on_attestation(spec, store, attestation, is_from_block=True, valid=True) run_on_attestation(spec, store, attestation, is_from_block=True, valid=True)
# An on_block step implies receiving block's attester slashings
for attester_slashing in signed_block.message.body.attester_slashings:
run_on_attester_slashing(spec, store, attester_slashing, valid=True)
block_root = signed_block.message.hash_tree_root() block_root = signed_block.message.hash_tree_root()
assert store.blocks[block_root] == signed_block.message assert store.blocks[block_root] == signed_block.message
assert store.block_states[block_root].hash_tree_root() == signed_block.message.state_root assert store.block_states[block_root].hash_tree_root() == signed_block.message.state_root
@ -168,6 +176,38 @@ def add_block(spec,
return store.block_states[signed_block.message.hash_tree_root()] return store.block_states[signed_block.message.hash_tree_root()]
def run_on_attester_slashing(spec, store, attester_slashing, valid=True):
if not valid:
try:
spec.on_attester_slashing(store, attester_slashing)
except AssertionError:
return
else:
assert False
spec.on_attester_slashing(store, attester_slashing)
def add_attester_slashing(spec, store, attester_slashing, test_steps, valid=True):
slashing_file_name = get_attester_slashing_file_name(attester_slashing)
yield get_attester_slashing_file_name(attester_slashing), attester_slashing
if not valid:
try:
run_on_attester_slashing(spec, store, attester_slashing)
except AssertionError:
test_steps.append({
'attester_slashing': slashing_file_name,
'valid': False,
})
return
else:
assert False
run_on_attester_slashing(spec, store, attester_slashing)
test_steps.append({'attester_slashing': slashing_file_name})
def get_formatted_head_output(spec, store): def get_formatted_head_output(spec, store):
head = spec.get_head(store) head = spec.get_head(store)
slot = store.blocks[head].slot slot = store.blocks[head].slot

View File

@ -8,24 +8,27 @@ from eth2spec.test.context import (
with_presets, with_presets,
) )
from eth2spec.test.helpers.attestations import get_valid_attestation, next_epoch_with_attestations from eth2spec.test.helpers.attestations import get_valid_attestation, next_epoch_with_attestations
from eth2spec.test.helpers.block import build_empty_block_for_next_slot from eth2spec.test.helpers.block import (
apply_empty_block,
build_empty_block_for_next_slot,
)
from eth2spec.test.helpers.constants import MINIMAL from eth2spec.test.helpers.constants import MINIMAL
from eth2spec.test.helpers.fork_choice import ( from eth2spec.test.helpers.fork_choice import (
tick_and_run_on_attestation, add_attester_slashing,
tick_and_add_block, add_block,
get_anchor_root, get_anchor_root,
get_genesis_forkchoice_store_and_block, get_genesis_forkchoice_store_and_block,
get_formatted_head_output, get_formatted_head_output,
on_tick_and_append_step, on_tick_and_append_step,
add_block, run_on_attestation,
tick_and_run_on_attestation,
tick_and_add_block,
) )
from eth2spec.test.helpers.state import ( from eth2spec.test.helpers.state import (
next_slots, next_slots,
next_epoch, next_epoch,
state_transition_and_sign_block, state_transition_and_sign_block,
) )
from tests.core.pyspec.eth2spec.test.helpers.block import apply_empty_block
from tests.core.pyspec.eth2spec.test.helpers.fork_choice import run_on_attestation
rng = random.Random(1001) rng = random.Random(1001)
@ -411,7 +414,7 @@ def test_discard_equivocations(spec, state):
# Process attester_slashing # Process attester_slashing
# The head should revert to block_2 # The head should revert to block_2
spec.on_attester_slashing(store, attester_slashing) yield from add_attester_slashing(spec, store, attester_slashing, test_steps)
assert spec.get_head(store) == spec.hash_tree_root(block_2) assert spec.get_head(store) == spec.hash_tree_root(block_2)
test_steps.append({ test_steps.append({

View File

@ -76,11 +76,27 @@ Adds `PowBlock` data which is required for executing `on_block(store, block)`.
{ {
pow_block: string -- the name of the `pow_block_<32-byte-root>.ssz_snappy` file. pow_block: string -- the name of the `pow_block_<32-byte-root>.ssz_snappy` file.
To be used in `get_pow_block` lookup To be used in `get_pow_block` lookup
} }
``` ```
The file is located in the same folder (see below). The file is located in the same folder (see below).
PowBlocks should be used as return values for `get_pow_block(hash: Hash32) -> PowBlock` function if hashes match. PowBlocks should be used as return values for `get_pow_block(hash: Hash32) -> PowBlock` function if hashes match.
#### `on_attester_slashing` execution step
The parameter that is required for executing `on_attester_slashing(store, attester_slashing)`.
```yaml
{
attester_slashing: string -- the name of the `attester_slashing_<32-byte-root>.ssz_snappy` file.
To execute `on_attester_slashing(store, attester_slashing)` with the given attester slashing.
valid: bool -- optional, default to `true`.
If it's `false`, this execution step is expected to be invalid.
}
```
The file is located in the same folder (see below).
After this step, the `store` object may have been updated.
#### Checks step #### Checks step
The checks to verify the current status of `store`. The checks to verify the current status of `store`.