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

EIP6914 discussion #3335

Open
djrtwo opened this issue Apr 19, 2023 · 9 comments
Open

EIP6914 discussion #3335

djrtwo opened this issue Apr 19, 2023 · 9 comments

Comments

@djrtwo
Copy link
Contributor

djrtwo commented Apr 19, 2023

General discussion thread for EIP6914 -- reuse validator indices.

Bulk of the core was merged in #3307, but there are many minor discussion points and design decisions on the table.

@djrtwo
Copy link
Contributor Author

djrtwo commented Apr 19, 2023

Note, potential non-substantive refactor #3311

@wenceslas-sanchez
Copy link
Contributor

Hi guys,

I am not sure about what I am saying, don't hesitate to confirm or not. In the inactivity period, validators that don't validate attestation see their score increasing. And it decreases if they did their job. What if a validator said he wants to exit during the inactivity period (or just before); it means the validator is still active for some epoch, but don't validate; so its score increase. He exits some epochs later, during the inactivity period (or not) and its score won't change (!=0). Since the score decrease only for eligible validators, the score for an exited validator different from 0 will be kept as is until he comes back as active.

My question is, will the inactivity score be reset to 0 for the validator that is going to get the index of the validator that lived with a score != 0 when he registers ?

Thanks guys !

@dapplion
Copy link
Collaborator

will the inactivity score be reset to 0 for the validator that is going to get the index of the validator that lived with a score != 0 when he registers ?

Yes, the inactivity score record is reset to zero at the moment of re-assigning the validator record

set_or_append_list(state.inactivity_scores, index, uint64(0))

@wenceslas-sanchez
Copy link
Contributor

will the inactivity score be reset to 0 for the validator that is going to get the index of the validator that lived with a score != 0 when he registers ?

Yes, the inactivity score record is reset to zero at the moment of re-assigning the validator record

set_or_append_list(state.inactivity_scores, index, uint64(0))

Thanks !

@ppopth
Copy link
Member

ppopth commented Jun 21, 2023

Another complicated thing about this EIP is the equivocating_indices field in the fork-choice Store.

Currently equivocating_indices keeps the list of slashed validators and it's append-only. If those validators' indices can be reused, we should have a mechanism to remove some indices from the list. I think this is not trivial and maybe complicated.

I think, if you have an idea how to do it, it's quite a good idea to add it to the consensus-specs soon. Otherwise, this EIP seems unviable to me.

@dapplion
Copy link
Collaborator

@ppopth that's a great point indeed. Clearly clients should drop reused indexes from the equivocating_indices when re-assigning to a new deposit. I wonder how specific de spec should be in that regard.

For example add a more general hook, called whenever any valid imported block triggers the reuse of an index. Clients will have to do some cache clean up anyway when a reuse event happens anyway.

def on_reused_index(store: Store, index: ValidatorIndex) -> None:
    store.equivocating_indices.delete(index)

Or define a more specific mechanism, such as

def on_tick_per_epoch(store: Store, epoch: Epoch) -> None:
    head_state = store.block_states[get_head(store)]

    for index in equivocating_indices:
        if state.validators[index].withdrawable_epoch + SAFE_EPOCHS_TO_REUSE_INDEX == epoch:
            equivocating_indices.delete(index)

I would be in favor of the first approach, as I think the specific details can be iron out latter

@ppopth
Copy link
Member

ppopth commented Jun 27, 2023

@ppopth that's a great point indeed. Clearly clients should drop reused indexes from the equivocating_indices when re-assigning to a new deposit. I wonder how specific de spec should be in that regard.

I think that will introduce a new attack vector. Let my_index be my index.

Let's say validators[my_index].withdrawable_epoch + SAFE_EPOCHS_TO_REUSE_INDEX is 100001.

Even if the withdrawable_epoch is far in the past, I can still deposit some balance and makes it effective. Let's say I deposit 32 ETH in the slot 319999. Even if my balance will be withdrawn immediately in the slot 320000, that doesn't matter because my effective balance is 32 ETH already.

Let's say at the beginning of the epoch 100001, epoch 100000 becomes justified, i.e. store.justified_checkpoint.epoch is 100000, and the state that I have effective balance will be used for the fork-choice.

Now consider the get_weight function.

def get_weight(store: Store, root: Root) -> Gwei:
    state = store.checkpoint_states[store.justified_checkpoint]
    unslashed_and_active_indices = [
        i for i in get_active_validator_indices(state, get_current_epoch(state))
        if not state.validators[i].slashed
    ]
    attestation_score = Gwei(sum(
        state.validators[i].effective_balance for i in unslashed_and_active_indices
        if (i in store.latest_messages
            and i not in store.equivocating_indices
            and get_ancestor(store, store.latest_messages[i].root, store.blocks[root].slot) == root)
    ))
    ...

Let's say I'm slashed, but not slashed in the current head block. I'm slashed like in some reorg-ed block or slashed directly from the wire. You can notice that my_index is in unslashed_and_active_indices because I'm not slashed in the head block and my_index is also in store.equivocating_indices because I'm slashed in some other way.

You can notice that my effective balance will not be counted in attestation_score, but let's say, at slot 320035, my_index is reused and I'm not in store.equivocating_indices any more. Now my effective balance will be counted in attestation_score.

@mkalinin
Copy link
Collaborator

Even if a validator is removed from equivocating_indices, validators[my_index].withdrawable_epoch + SAFE_EPOCHS_TO_REUSE_INDEX == epoch implies that it isn't active anymore and won't be counted by the get_weight function. Moreover, attestations from such validator won't be accepted by the network unless it is a new validator with the same index.

@ppopth
Copy link
Member

ppopth commented Jun 27, 2023

Even if a validator is removed from equivocating_indices, validators[my_index].withdrawable_epoch + SAFE_EPOCHS_TO_REUSE_INDEX == epoch implies that it isn't active anymore and won't be counted by the get_weight function.

That's right. Thanks. I forgot the activeness.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants
@ppopth @djrtwo @mkalinin @dapplion @wenceslas-sanchez and others