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

Investigate and document the effects of code upgrade but without constitution update #3537

Closed
jumaffre opened this issue Feb 11, 2022 · 8 comments

Comments

@jumaffre
Copy link
Contributor

It is possible that operators do not update the constitution scripts when performing the code upgrade procedure described here.

We should make sure we understand what the implications are and how the system will behave in this case.

@wintersteiger
Copy link

Good observation. I imagine this could lead to serious bugs. Would it make sense to require a combined bundle of code + const scripts to upgrade, such as to force operators to chose the old version if they don't want/need to upgrade to a new version of the constitution?

@achamayou
Copy link
Member

achamayou commented Mar 12, 2022

@wintersteiger I don't think we can do that safely, because some of the new action samples just won't work on an old network.

Actions/constitution are user defined, there's no guarantee they match exactly the samples we ship (indeed, we know they often differ, for good reasons), so we aren't really in a position to mandate specific constitution identities for a given version of the code. Deciding that a (code, constitution, kv state) triplet is safe would require extremely sophisticated symbolic execution!

At a minima we should have:

We can also discuss a possible versioning scheme for actions, as a way to communicate these changes. e.g. transition_service_to_open_v1 vs transition_service_to_open_v2.

@wintersteiger
Copy link

Regarding versioning: the constitution is basically an application that relies on the API defined in wrap.cpp. Therefore any change to that API that we make will likely require checks/fixes in user constitutions. So, should that file get it's own version number that we can check against in the constitution scripts and alert users of mismatches?

@achamayou
Copy link
Member

@wintersteiger I don't quite understand how that works and how that helps? The constitution itself is a JS module with three hardcoded functions, validate(), resolve() and apply(). Each call supports a certain number of actions, it's the actions that tend to end up with a dependency on some of wrap.cpp rather than the entry points to the constitution itself.

Let's say wrap.cpp gets a version number, who is "we" and how does the "check" happen? The only check that can happen in the constitution file (eg. assert at the top of validate()) will be too late and will prevent any further governance including a constitution upgrade!

The check would need to happen when a new code update is proposed instead, and check compatibility between a claim on the binary that represents the version of wrap.cpp (*) and the version of the constitution. Except there is no meaningful version of the constitution, because it's user-defined.

So instead, what's needed is an operation that finds out if a binary supports the set of actions in the current constitution. But there is neither a way to extract that set from the constitution, nor from a binary. And even that relies on actions having fixed semantics/being immutable, and doesn't work for user-defined actions.

@wintersteiger am I missing something, and is there a simple solution I am missing?

(*) mrenclave isn't transparent!

@wintersteiger
Copy link

Yes, I wasn't thinking about hard rejects at runtime, that would be any good at all. Instead, I'm thinking about a declaration of the expected version of the API in wrap.cpp. Depending on the exact shape that takes, we can check it at compile time and/or at runtime and emit a warning if there's a mismatch between the two, to alert the operator to the fact that this needs attention.

But yes, user-defined actions wouldn't work and, conversely, users might have their own ideas about versioning their scripts. So, not sure it's worth the effort.

@wintersteiger
Copy link

Earlier today we discussed the following potential improvements:

  • Split constitution files
    • separate file for each proposal
    • automatically merge them
    • update only of the whole package, no partial updates
    • possibly organise as an npm package
  • Document the constitution-FFI interface better
    • Perhaps based on/in combination with the partial documentation in the app-ccf package
  • Introduce versioning
    • Not concrete scheme decided upon, but just adding *_v<n> to the proposal names would be a good start
    • Perhaps also in a separate field, next to the proposal name
  • We do not want to split application-JS and constitution-JS
    • They may intentionally interact with each other

@wintersteiger
Copy link

While it would be good to get as many improvements into 2.0 as possible, I think we should not plan to get all of this into the 2.0 release, so I'm taking the 2.0 label off.

@wintersteiger wintersteiger removed the 2.x label Apr 14, 2022
@achamayou
Copy link
Member

@wintersteiger yes, you're right, I think we wanted to get the documentation clarified, but the longer term solution is out of scope for 2.x.

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

No branches or pull requests

3 participants