Skip to content
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

Add disable_process_reveal_deadlines decorator and reveal_deadlines_setting meta tag #2017

Merged
merged 8 commits into from
Sep 7, 2020

Conversation

hwwhww
Copy link
Contributor

@hwwhww hwwhww commented Aug 13, 2020

Issue

Fix #2015

Solution

  1. Add disable_process_reveal_deadlines decorator to disable phase 1 process_reveal_deadlines function.
  2. Add reveal_deadlines_setting meta tag: if reveal_deadlines_setting is 1, disable the process_reveal_deadlines function.

TODOs

  • Add @disable_process_reveal_deadlines to some custody game tests.
  • TBD: for the correctness of protocol, I'm inclined to have process_reveal_deadlines default to enabled. However, process_reveal_deadlines may affect some more tests' state balances and make it difficult to debug. We may want to disable it in more irrelevant test cases.

@hwwhww hwwhww marked this pull request as ready for review August 25, 2020 08:05
@hwwhww
Copy link
Contributor Author

hwwhww commented Aug 25, 2020

It's still unacceptable slow to generate these test vectors. I suggest applying @with_configs([MINIMAL]) (#2016) to these test cases, i.e., don't generate mainnet test vectors for now and think about other ways to test custody game with mainnet config.

@hwwhww hwwhww changed the title [WIP] Add disable_process_reveal_deadlines decorator and reveal_deadlines_setting meta tag Add disable_process_reveal_deadlines decorator and reveal_deadlines_setting meta tag Aug 25, 2020
@djrtwo
Copy link
Contributor

djrtwo commented Sep 1, 2020

for the correctness of protocol, I'm inclined to have process_reveal_deadlines default to enabled.

I agree

Skip the too-slow custody tests and turn on the generators
Copy link
Collaborator

@protolambda protolambda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mutating the spec during testing is tricky, but possible. See review comment, I think the new disable_process_reveal_deadlines decorator doesn't work as expected.

@@ -165,6 +165,9 @@ bls_setting: int -- optional, can have 3 different values:
but there is no change of outcome when running the test if BLS is ON or OFF.
1: known as "BLS required" - if the test validity is strictly dependent on BLS being ON
2: known as "BLS ignored" - if the test validity is strictly dependent on BLS being OFF
reveal_deadlines_setting: -- optional, can have 2 different values:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be a bool, but if we end up having more settings then this is compatible. 👍

def disable_process_reveal_deadlines(fn):
def entry(*args, spec: Spec, **kw):
if hasattr(spec, 'process_reveal_deadlines'):
spec.process_reveal_deadlines = lambda state: None
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mutates the spec object. Making it not re-usable. I.e. other tests afterwards will also have a no-operation process_reveal_deadlines. The decorator has to set the old function back, after running the wrapped test, for this to work as expected.

Also beware of returned generators not being evaluated directly; the wrapped function should be evaluated fully before undoing the no-op substitute. A similar thing is done in the BLS decorator, if you need an example. See bls_switch in context.py

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the catch! 👍👍
I forgot that the test generator mode scope != pytest unit test mode scope.

@protolambda
Copy link
Collaborator

protolambda commented Sep 4, 2020

Thinking long-term, a heavier but imho better approach for testing would be:

  • Define an eth2 Spec with a Protocol (py 3.8) for static type checking. (proposed this before, but didn't seem viable at the time)
  • Make each spec function isolated: first argument is spec: Spec, to access other functions and variables. No globals or implicit dependencies (yay).
  • Ability to mock any part of the spec by passing a special object, that implements the Spec interface (or Protocol in python), and implements it in it's own way. E.g. everything proxied to the real implementation (could be done with inheritance of functions) except the mocked function.
  • Solves the phase 0 / 1 compatibility issue. A clear interface would be defined.
  • Spec tests would be fully type-checkable, since their is no arbitrary spec module being passed around anymore. It would be a typed spec (Protocol)
  • Not just able to mock functions (like making disable_process_reveal_deadlines a no-op), but also able to verify a function was called with specific argument, by wrapping the real function. Could improve testing.

Shall I open an issue for this? I think it's out of scope for this PR, but given the easy mistake with disable_process_reveal_deadlines, and the many benefits, I think it's the way to go.

cc @djrtwo

…back to the spec function for other test cases afterwards
@hwwhww
Copy link
Contributor Author

hwwhww commented Sep 7, 2020

@protolambda

  • Define an eth2 Spec with a Protocol (py 3.8) for static type checking. (proposed this before, but didn’t seem viable at the time)
  • Make each spec function isolated: first argument is spec: Spec, to access other functions and variables. No globals or implicit dependencies (yay).
  • Solves the phase 0 / 1 compatibility issue. A clear interface would be defined.

Yes, I fully support it! 👍 I once tried to implement class Spec (not Protocol version) a long time ago but didn’t have one workable branch due to other higher priorities 🤦‍♀️

Trinity has a similar pattern. From what I can tell, it’s a much better way to handle the forks. The main benefit I see for other teams is that we could use Python super inheritance instead of copying the code and modify a piece of it. Although it’s a bit more Pythonic, IMO we will get a cleaner spec with it.

Copy link
Collaborator

@protolambda protolambda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@protolambda protolambda merged commit 62cd4e8 into testgenphase1 Sep 7, 2020
@protolambda protolambda deleted the reveal_deadlines_setting branch March 27, 2021 00:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants