-
Notifications
You must be signed in to change notification settings - Fork 996
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fork-choice test vectors: starting with get_head
tests
#2202
Conversation
When I was designing my fork choice tests, I avoided explicit instantiation of Store objects, for the same reasons. While any implementation should know how to handle |
|
To reduce test vector generation time, I have been using either a caching BLS implementation or a dummy BLS implementation (which is completely insecure, but still able to distinguish good and bad signatures). |
Right, and we have a test function decorator |
So do we leave the fork choice unit tests untouched? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome! only minor comments
Should we remove the old unittest test_get_head
file? This new file is strictly the previous functionality + generators, right?
Co-authored-by: Danny Ryan <dannyjryan@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some minor comments, looks good to me, nice work 👍
for attestation in attestations: | ||
spec.on_attestation(store, attestation) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: run_on_block
will run on_attestation
for each attestation from block.message.body.attestations
.
|
||
|
||
@with_all_phases | ||
@spec_state_test | ||
@with_configs([MINIMAL], reason="too slow") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: the test generation time of other tests is acceptable, for me.
- For each execution, look up the corresponding ssz_snappy file. Execute the corresponding helper function on the current store. | ||
- For the `on_block` execution step: if `len(block.message.body.attestations) > 0`, execute each attestation with `on_attestation(store, attestation)` after executing `on_block(store, block)`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: on_block
execution step implies running on_attestation
.
09fc717
to
ee82203
Compare
Note that to execute on_attestation after on_block Output more checking field Disable mainnet config test_filtered_block_tree Fix after rectoring + use more run_on_block Fix and refactor `tick_and_run_on_attestation`
ee82203
to
e77ba91
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm!
I’m transforming the current pyspec fork choice test cases into test vectors. 🧶
get_head
helper.test/phase0/fork_choice/test_get_head.py
is basically copied fromtest/phase0/unittests/fork_choice/test_get_head.py
, but with some extrayield
to output the test vectors. Minimal configget_head
test vectors are here.Test formats
anchor_state.yaml
andanchor_block.yaml
: the inputs ofget_forkchoice_store(anchor_state: BeaconState, anchor_block: BeaconBlock)
, to initialize thestore
.genesis
. But in our case, the anchor state may not be genesis.block_<block_root>.yaml
:SignedBeaconBlock
objectattestation_<attestation_root>.yaml
:Attestation
objectsteps.yaml
: the execution steps. Basically similar to Fork-choice integration test format and example (WIP) consensus-spec-tests#17 "steps". The member elements may be:tick: <time>
: integer, the time for callingon_tick(store: Store, time: uint64)
slot
.block: <block_file_name>
: theSignedBeaconBlock
object for callingon_block(store: Store, signed_block: SignedBeaconBlock)
attestation: <attestation_file_name>
: theAttestation
object for callingon_attestation(store: Store, attestation: Attestation)
checks
dict:head
: the block root when callingget_head(store: Store)
justified_checkpoint_root
: the hash tree root ofStore.justified_checkpoint
.Discussions
Any suggestions on the above proposal?
It's easy to convert
get_head
tests. However, in ouron_block
tests, we directly set the fields ofStore
to prepare the tests. For example:https://github.com/ethereum/eth2.0-specs/blob/8ec082fcf9ca58bf143977abb4dce9c8c417dbdd/tests/core/pyspec/eth2spec/test/phase0/unittests/fork_choice/test_on_block.py#L30-L31
https://github.com/ethereum/eth2.0-specs/blob/8ec082fcf9ca58bf143977abb4dce9c8c417dbdd/tests/core/pyspec/eth2spec/test/phase0/unittests/fork_choice/test_on_block.py#L129-L132
I may have to rewrite them to get rid of the Store field manipulations if we are going to follow the above test formats.
Alternatively, we can output the whole
store
object. However, some drawbacks:Store
object could be really huge. We probably can only outputMinimal
config tests.Store
in a very different, optimized solution.20210313 updated:
See fork choice test format doc