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

Can state roots really be updated? #2374

Closed
roman-khimov opened this issue Mar 2, 2021 · 3 comments
Closed

Can state roots really be updated? #2374

roman-khimov opened this issue Mar 2, 2021 · 3 comments
Labels
question Used in questions

Comments

@roman-khimov
Copy link
Contributor

State roots signed by state validators are supposed to be updatable, they have versioning built-in for that, so the presumption is that we can change the version of state root and sign a new one if need be. But this raises some questions answers to which are not obvious from the current implementation:

  1. Current code treats all versions equal, that is the node will accept state root messages with any version. If there are two versions of state roots for a particular block how would a node know which one to use and which one is preferred?
  2. If anyone stores/uses proof of some state version 0, what should he do if the state is updated to version 1?
  3. To update old state roots SVs have to be reset and resynchronized from the genesis, but this process itself needs to be well-synchronized between SVs to properly collect votes without getting OOMed with VerificationContexts and without flooding the network with Vote messages (and we need to consider RelayCache size limitations too), is it really feasible?
  4. SVs can change, but for a particular block index only one set of SVs is considered to be valid, so old state roots have to be signed with old keys which might be completely impossible in some cases (lost keys), what are we gonna do then?

Related: #2373, #1526.

@roman-khimov
Copy link
Contributor Author

There is also a problem on questions №3 and №4 intersection. OnNewExtensiblePayload will check any Extensible against the current set of allowed nodes (SVs) which means that no Vote exchange is really possible for old set of nodes. So with the current P2P protocol we can't sign old state roots even if we have all the keys needed.

@ZhangTao1596
Copy link
Contributor

ZhangTao1596 commented Mar 5, 2021

In current StateService design, old state root will be ignored and won't be updated.
Once a node receive a StateRoot with witness, it only check if the index is heigher than local verified, not strictly check if its index is equal local verified index + 1. If check passed, it will ignore those with lower index. Not like neo-2.x verify StateRoot one by one.
The version byte is to mark MPT uncompatible updates.
So after neo updated, StateService just continue verifying new state and ignore the old blocks.

@roman-khimov
Copy link
Contributor Author

old state root will be ignored and won't be updated

If that's the case, then I don't see any value in versioning. We just have some "stateroot" messages floating around for current blocks and version number means nothing to the message receiver.

Which also destroys one of state root use cases, that is checking that the node has correct state at particular block, the node can only check the latest state, but it won't be able to detect which block went wrong if it synchronizes from the genesis.

But if SV-signed state roots aren't supposed to be updated, then this issue is irrelevant.

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

No branches or pull requests

2 participants