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

[WIP] Execution-ified fork choice, draft 1 #1068

Closed
wants to merge 15 commits into from
Closed

[WIP] Execution-ified fork choice, draft 1 #1068

wants to merge 15 commits into from

Conversation

vbuterin
Copy link
Contributor

@vbuterin vbuterin commented May 9, 2019

Not tested at all. Also missing one optimization that's probably crucial to have even enough efficiency for testing, which is a children cache.

Also missing weak-subjectivity-aware safety measurement and time-aware justified head switching.

@JustinDrake JustinDrake self-assigned this May 13, 2019
@JustinDrake
Copy link
Contributor

JustinDrake commented May 13, 2019

Looking at this today. (Assigned PR to myself to avoid conflicts with other reviewers.)

Edit: This PR addresses points 1, 3, 4, 5, 6, 9, 10 of issue #1053.

@JustinDrake JustinDrake removed their assignment May 13, 2019
@djrtwo
Copy link
Contributor

djrtwo commented May 15, 2019

reviewing now! please don't merge even though "approved"

@hwwhww hwwhww changed the title Execution-ified fork choice, draft 1 [WIP] Execution-ified fork choice, draft 1 May 16, 2019
@JustinDrake
Copy link
Contributor

We probably want a couple tests before merging.

hwwhww added 3 commits May 17, 2019 00:45
1. signed_root -> signing_root
2. `get_attesting_balance` is used in state transition spec.  Rename `get_attesting_balance` to `get_attesting_balance_from_store`
@hwwhww
Copy link
Contributor

hwwhww commented May 16, 2019

Changelog:

  1. Build both 0_beacon-chain.md and 0_fork-choice.md.
    • change the order of build_spec argvs from <source phase0> <output phase0 pyspec> to <output phase0 pyspec> <source 0_beacon-chain> <source 0_fork-choice>
  2. Fork choice rule spec
    1. signed_root -> signing_root
    2. The name get_attesting_balance is used in state transition spec. Rename fork choice rule get_attesting_balance to get_attesting_balance_from_store.

It's blocking by the new SSZ Map type(???).
Is making Store SSZ serializable a requirement? Otherwise, we can transform Store into a simple Python class (not SSZ) in function_puller.py.

@vbuterin
Copy link
Contributor Author

I don't think we need Store to be an SSZ object. It's not a consensus object.

if state.current_justified_epoch > slot_to_epoch(store.blocks[store.justified_root].slot):
store.justified_root = state.current_justified_root
if state.previous_justified_epoch > slot_to_epoch(store.blocks[store.justified_root].slot):
store.justified_root = state.previous_justified_root
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. I think it's impossible of that both state.current_justified_epoch > slot_to_epoch(store.blocks[store.justified_root].slot) and state.previous_justified_epoch > slot_to_epoch(store.blocks[store.justified_root].slot) happen?
  2. IMHO it's better to avoid using the possible updated store.justified_root in the second condition check (if state.previous_justified_epoch > ...), it looks confusing.

Suggestion:

    if state.current_justified_epoch > slot_to_epoch(store.blocks[store.justified_root].slot):
        store.justified_root = state.current_justified_root
    elif state.previous_justified_epoch > slot_to_epoch(store.blocks[store.justified_root].slot):
        store.justified_root = state.previous_justified_root

@hwwhww
Copy link
Contributor

hwwhww commented May 16, 2019

I don't think we need Store to be an SSZ object. It's not a consensus object.

👍

An option: if we upgrade the CI to Python 3.7 env (it's currently Python 3.6), we can use @dataclass to define Store concisely.

@dataclass
class Store:
    blocks: Dict[Bytes32, BeaconBlock] = {}
    states: Dict[Bytes32, BeaconState] = {}
    time: int = 0
    latest_targets: Dict[int, Target] = {}
    justified_root: Bytes32 = ZERO_HASH
    finalized_root: Bytes32 = ZERO_HASH

```python
def on_block(store: Store, block: BeaconBlock) -> None:
# Check block is a descendant of the finalized block
assert get_ancestor(store, signing_root(block), store.blocks[store.finalized_root].slot) == store.finalized_root
Copy link
Contributor

Choose a reason for hiding this comment

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

The given block hasn't been stored yet here, so inside get_ancestor, it can't access the given block from store.

As a beacon node, I support it needs to store the block before these verifications?

pre_state = store.states[block.parent_root]
assert store.time >= pre_state.genesis_time + block.slot * SECONDS_PER_SLOT
# Check the block is valid and compute the post-state
state = state_transition(pre_state, block)
Copy link
Contributor

@hwwhww hwwhww May 20, 2019

Choose a reason for hiding this comment

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

Ahhhh a mutability issue here! 💣

  1. state_transition returns a state, but note that there is side effect - the given state input would be changed anyway. (Avoid side effect in state transition with mutable object #1059)
  2. Since store.states is a dict, the updated pre_state would mess up store.states.

A quick fix for this PR might still be adding the scary deepcopy inside state_transition that I know people really don't want to have in the spec. :'(

But open to continue discussing in #1059.

hwwhww added 2 commits May 21, 2019 11:55
1. Make `Target` as a dataclass
2. Fix `on_attestation` typos
3. Add basic tests

TBD:
1. deepcopy?
2. Add new block to the store before validation
@hwwhww
Copy link
Contributor

hwwhww commented May 21, 2019

Changelog:

  1. Add SSZType.copy() helper to deal with copy.deepcopy
  2. Add some basic tests and make the tests pass:
    1. Make Target as a dataclass
    2. Fix on_attestation typos
    3. Add basic tests
    4. Move forward to deal with [WIP] Execution-ified fork choice, draft 1 #1068 (comment) and [WIP] Execution-ified fork choice, draft 1 #1068 (comment)

TBD: to confirm if pre_state = store.states[block.parent_root].copy() and #1068 (comment) are okay.

@protolambda
Copy link
Contributor

Is anyone still working on this? Shall I take a look? (Other fork-choice implementation work here: https://github.com/protolambda/lmd-ghost/).

@JustinDrake
Copy link
Contributor

Shall I take a look?

Please do :) No one seems to have taken "merge responsibility" for this one.

@JustinDrake JustinDrake added the milestone:June 30 freeze 🥶 Phase 0 spec freeze for long-lived cross-client testnet label Jun 15, 2019
@CarlBeek CarlBeek self-assigned this Jun 16, 2019
@CarlBeek CarlBeek mentioned this pull request Jun 16, 2019
@CarlBeek
Copy link
Contributor

This PR has been deprecated by #1185. This was forked from such an old version of dev, it was easier to start afresh. In addition, all of @hwwhww's open comments have been handled in #1185.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
milestone:June 30 freeze 🥶 Phase 0 spec freeze for long-lived cross-client testnet scope:fork-choice
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants