-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Resolve TODOs and Improve EIP-7805 (FOCIL) Spec #4351
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
base: master
Are you sure you want to change the base?
Conversation
93df232
to
3824af8
Compare
f6951fa
to
281edd1
Compare
3626348
to
2ec3c4a
Compare
There is a constant that is inconsistent in the SEPC and EIP documents. |
As of now, the latest discussion on this PR can be found here: https://hackmd.io/@jihoonsong/S1c2dhMrle Please review it and provide some feedback. Thank you. |
This PR has been followed by lots of discussions and changes. To preserve history, those changes are contained in the second commit. For easier review, here is the change log:
|
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.
@jihoonsong this looks great, nice work! Just a couple nits + notes for later.
key = (inclusion_list.slot, inclusion_list.inclusion_list_committee_root) | ||
|
||
inclusion_lists = store.inclusion_lists.setdefault(key, set()) | ||
equivocators = store.equivocators.setdefault(key, set()) |
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.
The setdefault
stuff here is ugly 😅 I'll look into fixing that in a follow up PR.
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.
I believe we should just remove setdefault
stuff. This is because the store
must already be initialized outside of this function call, thus setdefault
becomes redundant
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.
It's not about store
. It's just about Python's Dictionary.
I also don't like this part and that's why I asked @jtraglia if we can use DefaultDict. Let me think about how to improve this.
inclusion_list_transactions = { | ||
transaction | ||
for inclusion_list in inclusion_lists | ||
if inclusion_list.validator_index not in equivocators | ||
for transaction in inclusion_list.transactions | ||
} | ||
|
||
return list(inclusion_list_transactions) |
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.
This is implicitly deduping the list of transactions, right? I think we should make this a little more explicit, because I almost missed this myself. Maybe something like this:
inclusion_list_transactions = { | |
transaction | |
for inclusion_list in inclusion_lists | |
if inclusion_list.validator_index not in equivocators | |
for transaction in inclusion_list.transactions | |
} | |
return list(inclusion_list_transactions) | |
inclusion_list_transactions = [ | |
transaction | |
for inclusion_list in inclusion_lists | |
if inclusion_list.validator_index not in equivocators | |
for transaction in inclusion_list.transactions | |
] | |
# Deduplicate, order does not need to be preserved | |
return list(set(inclusion_list_transactions)) |
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.
Well, the deduplication comes from the fact that inclusion_lists
field of InclusionListStore
has the value of set
. Would adding a comment regarding this inside get_inclusion_list_transactions
enhance readability?
|
||
## New inclusion list committee duty | ||
*Note*: The only change to `prepare_execution_payload` is to call | ||
`get_inclusion_list_store()` and `get_inclusion_list_transactions()` to set the |
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.
We don't usually include the ()
to indicate a function in the specs. Personally, I do the same though 😢
`get_inclusion_list_store()` and `get_inclusion_list_transactions()` to set the | |
`get_inclusion_list_store` and `get_inclusion_list_transactions` to set the |
create and broadcast the `signed_inclusion_list` to the global `inclusion_list` | ||
subnet by `INCLUSION_LIST_SUBMISSION_DEADLINE` seconds into the slot after | ||
processing the block for the current slot and confirming it as the head. If no | ||
block is received by `INCLUSION_LIST_SUBMISSION_DEADLINE - 1` seconds into the |
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.
I think there might need to be a config variable for this too. Let's deal with this later though.
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.
I think I added it at L54. Do you mean preset?
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 a few comments, a general question: what if we introduce inclusion_list.md
and move InclusionListStore
and on_inclusion_list
to that new document? This will make FC spec cleaner. cc @jtraglia
#### New `notify_inclusion_lists` | ||
|
||
```python | ||
def notify_inclusion_lists( |
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.
A slight preference on the naming: is_inclusion_list_satisfied
or something like that. Similarly to is_block_hash_valid
and is_valid_versioned_hashes
key = (inclusion_list.slot, inclusion_list.inclusion_list_committee_root) | ||
|
||
inclusion_lists = store.inclusion_lists.setdefault(key, set()) | ||
equivocators = store.equivocators.setdefault(key, set()) |
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.
I believe we should just remove setdefault
stuff. This is because the store
must already be initialized outside of this function call, thus setdefault
becomes redundant
continue | ||
|
||
if stored_inclusion_list != inclusion_list: | ||
equivocators.add(inclusion_list.validator_index) |
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.
We should stop processing equivocations at some point in time. Potentially, at the beginning of the next slot. I believe this check can be introduced in a separate PR
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.
Yes I still remember this discussion on Discord. As it would change both the EIP and the CL spec, I think we need more eyes on this. I guess we can revisit this after we're in right momentum, i.e., SFIing EIP-7805. For now, I think we could focus on improvements and tests. But I'll keep this in mind.
### New `store_inclusion_list` | ||
|
||
```python | ||
def store_inclusion_list( |
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.
This function processes the list, but not necessarily stores it. Slight preference in favour of process_inclusion_list
name
|
||
```python | ||
def get_sync_committee_message( | ||
state: BeaconState, | ||
block_root: Root, | ||
validator_index: ValidatorIndex, | ||
privkey: int, | ||
store: Store, | ||
store: Store, # [New in EIP7805] |
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.
A better way to spec this out would be stating which block_root
should passed to the get_sync_committee_message
call without modification of the function
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.
Sounds great!
Some validators are selected to submit signed inclusion list. Validators should | ||
call `get_inclusion_committee_assignment` at the beginning of an epoch to be | ||
prepared to submit their inclusion list during the next epoch. | ||
*Note*: The proposer should call `prepare_execution_payload` at |
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.
It doesn’t sound right, a proposer may call prepare_execution_payload
at 11.5s into a slot or even later in the case of re-org. I think the spec should say that proposer must not start the build process before the PROPOSER_INCLUSION_LIST_CUT_OFF
and that a proposer must use a snapshot of ILs made at PROPOSER_INCLUSION_LIST_CUT_OFF
in the prepare_execution_payload
call
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.
I think it's up to proposers. They still have the freedom to start payload building process before PROPOSER_INCLUSION_LIST_CUT_OFF
and we don't want to take it away. But you're right, this is misleading. A proposer can choose either start payload building earlier and update it with ILs after the deadline, or start payload building after the deadline. Let me change it.
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.
Is this safe for a proposer to start building earlier? It can lead to the situation where proposer’s ILs are more relaxed because they started to build earlier and haven’t received some ILs yet. I think proposer "should not” start the build process before the cut off — this would probably be the right wording
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.
Isn't it safe as long as a proposer update the building process after the deadline? What I meant is a proposer can start payload building earlier AND update it with ILs after the deadline.
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.
Oh, I see what you mean but in this case proposer will have to ensure that no new IL arrived after it has started to build earlier. Otherwise, that early built payload can’t be safely used. I agree, this should be up to proposer’s implementation. So, the ultimate requirement is: built payload should satisfy IL constraints observed by a proposer at the cut off
This PR resolves TODOs and improves the honest validator section of EIP-7805 spec. It contains minimal test changes and rest of tests will be added by the subsequent PR.