-
Notifications
You must be signed in to change notification settings - Fork 208
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
design better vat-facing upgrade protocol (buildRootObject()? upgrade()?) #4382
Comments
I need to fully read the issue, but my thinking was a single This would also unify the case of sublibraries and sub baggage. |
This implements the primary vat-side interface for upgrade (#4325, #4382). However, it does not yet implement the set of post upgrade checks (#3062) that will be required (e.g., check upon return from `buildRootObject` to verify that all the durable kinds have had behavior associated with them or have been explicitly dismissed); the ability to test or otherwise exercise the latter portion of the upgrade machinery will have to wait until the kernel-side interfaces (#1848, #3062) are in place. I am going to tentative declarely that this PR closes #4325, leaving the remaining work to be covered by #3062.
This implements the primary vat-side interface for upgrade (#4325, #4382). However, it does not yet implement the set of post upgrade checks (#3062) that will be required (e.g., check upon return from `buildRootObject` to verify that all the durable kinds have had behavior associated with them or have been explicitly dismissed); the ability to test or otherwise exercise the latter portion of the upgrade machinery will have to wait until the kernel-side interfaces (#1848, #3062) are in place. I am going to tentative declarely that this PR closes #4325, leaving the remaining work to be covered by #3062.
This implements the primary vat-side interface for upgrade (#4325, #4382). However, it does not yet implement the set of post upgrade checks (#3062) that will be required (e.g., check upon return from `buildRootObject` to verify that all the durable kinds have had behavior associated with them or have been explicitly dismissed); the ability to test or otherwise exercise the latter portion of the upgrade machinery will have to wait until the kernel-side interfaces (#1848, #3062) are in place. I am going to tentative declarely that this PR closes #4325, leaving the remaining work to be covered by #3062.
@warner As with the other upgrade issues, aside from contracts (which are outside the scope of SwingSet per se), can we treat this as done? |
Kicking out to Mainnet 2 pending a more thorough conversation about upgrade of third party contracts. |
@warner Please either close this or remove this from the upgrade Epic. |
For MN-1, we're proceeding with the simple plan: For MN-2 (especially before external vat/contract developers are exposed to this pattern), I'd like to revisit it. I'm hoping we'll have some more experience with the practicalities of managing the upgraded source code by then, to inform the discussion. |
What is the Problem Being Solved?
We need to define how a new version of a vat is launched.
We expect the initial version of a vat to export a function named
buildRootObject
, which is called exactly once during that version's lifetime, and is supposed to return a single remotable object. The calling vat will get this object asroot
in the result ofvatAdminService~.createVat()
, so it can start interacting with its creation.However we haven't yet defined what the second (and subsequent) versions of a vat must do, when triggered by
vatAdminFacet~.upgrade(newBundleCap, newVatParameters)
. We know there will be some well-defined calling pattern, with either one function being exported, or one per version upgrade. This function will getvatPowers
just likebuildRootObject
, and it will get avatParameters
from the upgrading caller. The function must reassociate all the virtual-object Kinds that were created by the earlier version. I expect it must also reassociate vrefs for any non-virtual "precious" Remotables that were exported by its predecessor (but we might dodge that by instructing vat authors to use virtual objects even for singletons).#1848 is about what you (as a calling vat, e.g. Zoe) would use to tell the kernel about some other vat that you want to upgrade. This ticket is about what happens within the upgraded vat.
The questions we need to answer include:
buildRootObject
buildRootObject
, and version-2++ providesupgrade
orupgradeRootObject
upgradeV1ToV2
andupgradeV2ToV3
upgradeToV2
,upgradeToV3
vatPowers
?makeKind
reassociation is performedDescription of the Design
The simplest option is to just keep using
buildRootObject
in all versions of a vat. The return value from the version-2++ function would be reassociated with vat'so+0
export, as if the function had used the reassociation API directly (and had some handle which gave it the authority to claimo+0
). We'd disown or ground all other exported remotables (except TODO how could liveslots enumerate them??). Vat authors would need to use a pattern where the first thingbuildRootObject
does is to usevatstore
to find out what the previous version was (where "nothing was stored" means this is the first time), and then switch behavior as appropriate. If there was no previous version, the code should initialize using the latest version. Otherwise it will need to upgrade from saved state of some particular version. Depending upon how quickly versions are deployed, it may need to be prepared to handle any previous version.The next most featureful thing I can think of would be to keep using
buildRootObject
but provide a way to reassociate more Remotables than just the root. This option would imply that the root object is special enough to warrant a special-case upgrade tool (return the new root object, instead of call a reassociation function with a handle for it), which is a bit non-orthogonal but maybe ok.The next most principled thing I can think of is to use
upgrade(vatPowers, vatParameters)
for version-2 and all subsequent versions. This would not have any special return value (it returns a Promise, and the first crank isn't complete until it fires, but the resolution value isn't used for anything). Reassociating the root object must be done with a reassociation function (from vatPowers) and some handle (from vatstore), just like all the non-root objects. In a mature vat source repository that has seen many upgrades, you'd see two exports:buildRootObject
to initialize new vats, andupgrade
to upgrade old ones. Both would get modified for each new version.The approach with the fewest footguns, in my mind, would be to explicitly break out all the upgrade stages into separately exported functions, and allowing the calling code to know what version number is used for each (so
vatAdminFacet~.upgrade({ toVersion: 3, bundlecap, vatParameters })
). The calling code would invoke just the new vat'supgradeV2ToV3
method, skipping previous ones. If the vat were being upgraded from v1 to v4 in a single shot, the calling code would invoke the upgraders in sequence. It would be unwieldy, but I suspect it would cause fewer mistakes.Security Considerations
Test Plan
The text was updated successfully, but these errors were encountered: