-
Notifications
You must be signed in to change notification settings - Fork 228
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
implement bundlecaps, bundle device #4372
Labels
Milestone
Comments
This was referenced Jan 25, 2022
warner
added a commit
that referenced
this issue
Feb 7, 2022
…(bundlecap) Add kernel support for code "bundles", specifically objects with `{ moduleFormat: "EndoZipBase64" }` whose `.EndoZipBase64` property is a large string (base64-encoded zipfile with a compartment map and module components). Each bundle has a "bundleID" which is the versioning prefix `b1-` followed by the lowercase hex encoding of the SHA512 hash of the compartment map bytes. Bundles are represented within userspace as "bundlecaps", which are device nodes owned by a new "bundle device" (`devices.bundle`). These can be passed in messages from one vat to another, just like Remotables. Bundlecaps are used to create vats in lieu of passing the actual (large) code bundles around through messages. Bundlecaps can also be asked for their code bundle in case you need to `importBundle` one directly into userspace (e.g. when ZCF evaluates a contract bundle). The `config.bundles` table is now handled by installing the bundles at `initializeSwingset` time, and populating a name->ID table for later. The new APIs are: * `computedBundleID = controller.validateAndInstallBundle(bundle, allegedBundleID)` will validate the bundle against the claimed ID and add it to the kernel tables (NOTE: validation is minimal so far, must be improved before release) * `kernel.installBundle(bundleID, bundle)` will install a bundle under the given ID without validation * `devices.bundle` provides access to bundles * `D(devices.bundle).getBundleCap(bundleID)` yields a bundlecap or `undefined` if no bundle was installed with that ID * `D(devices.bundle).getNamedBundleCap(name)` yields a bundlecap or `undefined` if config.bundles lacked a bundle with that name * bundlescaps are device nodes * `D(bundlecap).getBundleID()` yields the bundleID * `D(bundlecap).getBundle()` yields a code bundle, for `importBundle()` * `E(vatAdminService).createVat(bundleOrBundleCap)` creates a dynamic vat * eventually we'll remove the option to use a bundle, making this strictly `E(vatAdminService).createVat(bundlecap)` * `E(vatAdminService).createVatByName(name)` still works, but eventually it will be removed in favor of userspace doing `getNamedBundleCap` first refs #4372
This was referenced Feb 7, 2022
warner
added a commit
that referenced
this issue
Feb 7, 2022
This removes support for passing a full bundle to `E(vatAdminService).createVat()`, leaving a bundlecap as the only remaining option. Userspace is obligated to obtain a bundlecap as early as possible. This can't land until Zoe/ertp/governance are changed to use bundlecaps, as well as changing their unit tests to match. Eventually I also want to remove `E(vatAdminService).createVatByName()`, and have the code that needs it (zoe creating ZCF vats?) use `getNamedBundleCap()` first. refs #4372
mergify bot
pushed a commit
that referenced
this issue
Feb 9, 2022
…(bundlecap) Add kernel support for code "bundles", specifically objects with `{ moduleFormat: "EndoZipBase64" }` whose `.EndoZipBase64` property is a large string (base64-encoded zipfile with a compartment map and module components). Each bundle has a "bundleID" which is the versioning prefix `b1-` followed by the lowercase hex encoding of the SHA512 hash of the compartment map bytes. Bundles are represented within userspace as "bundlecaps", which are device nodes owned by a new "bundle device" (`devices.bundle`). These can be passed in messages from one vat to another, just like Remotables. Bundlecaps are used to create vats in lieu of passing the actual (large) code bundles around through messages. Bundlecaps can also be asked for their code bundle in case you need to `importBundle` one directly into userspace (e.g. when ZCF evaluates a contract bundle). The `config.bundles` table is now handled by installing the bundles at `initializeSwingset` time, and populating a name->ID table for later. The new APIs are: * `computedBundleID = controller.validateAndInstallBundle(bundle, allegedBundleID)` will validate the bundle against the claimed ID and add it to the kernel tables (NOTE: validation is minimal so far, must be improved before release) * `kernel.installBundle(bundleID, bundle)` will install a bundle under the given ID without validation * `devices.bundle` provides access to bundles * `D(devices.bundle).getBundleCap(bundleID)` yields a bundlecap or `undefined` if no bundle was installed with that ID * `D(devices.bundle).getNamedBundleCap(name)` yields a bundlecap or `undefined` if config.bundles lacked a bundle with that name * bundlescaps are device nodes * `D(bundlecap).getBundleID()` yields the bundleID * `D(bundlecap).getBundle()` yields a code bundle, for `importBundle()` * `E(vatAdminService).createVat(bundleOrBundleCap)` creates a dynamic vat * eventually we'll remove the option to use a bundle, making this strictly `E(vatAdminService).createVat(bundlecap)` * `E(vatAdminService).createVatByName(name)` still works, but eventually it will be removed in favor of userspace doing `getNamedBundleCap` first refs #4372 closes #3269 closes #4373
warner
added a commit
that referenced
this issue
Feb 9, 2022
warner
added a commit
that referenced
this issue
Feb 9, 2022
Mention bundlecaps, update options, update metering, update vat termination description. refs #4372
warner
added a commit
that referenced
this issue
Feb 9, 2022
Zoe needs a way to create a new ZCF vat to host each contract instance. Inside swingset, zoe uses `vatAdminService`, and this is used from unit tests (zoe and other packages that use zoe) when they are willing to take the time to run a full swingset environment. Unit tests that use zoe, but not swingset, use `tools/fakeVatAdmin.js` as a replacement, which implements `createVat(bundle)` but not `createVatByName(name)`. This is used to evaluate the ZCF bundle in a new Compartment (using `importBundle` and `evalContractBundle`). The primary export of `@agoric/zoe` is `makeZoeKit()`, which is called with `vatAdminService` and an optional `zcfBundleName`. This function runs `setupCreateZCFVat(vatAdminService)` to attenuate the vat-making power into one that can only create ZCF vats. Previously, `setupCreateZCFVat` closed over a copy of the ZCF bundle, and passed it to `vatAdminService~.createVat(zcfBundle)`. This hides the existence of the ZCF bundle from other packages that just want to use Zoe. However, to remove these large code bundles from userspace messages (#4372), we need the ZCF bundle to be installed "off to the side", by the code that prepares the swingset environment (usually as `config.bundles.zcf=`). This commit changes `fakeVatAdmin.js` to implement `createVatByName('zcf')`, and to move the copy of the zcfBundle out of `makeZoeKit()` and into `fakeVatAdmin.js` . In addition, it changes `createZCFVat.js` to provide a default bundle name of 'zcf'. Any unit test that uses `fakeVatAdmin.js` can continue to do so without changes, and the fake service will magically know how to create Zoe's ZCF vat without any additional configuration. Unit tests that use swingset, however, need to be updated to install the ZCF bundle into the kernel, with something like: ``` import zcfBundle from `@agoric/zoe/bundles/bundle-contractFacet.js`; ... config.bundles.zcf = { bundle: zcfBundle }; ``` Note: if we used `{ sourceSpec: '@agoric/zoe/contractFacet.js' }`, then we would not depend upon a recent `cd packages/zoe && yarn build`, and each kernel instance would bundle its own copy. This would be slower, but perhaps less prone to stale-bundle surprises, and might be a nicer export commitment. refs #4487
This was referenced Feb 13, 2022
turadg
pushed a commit
that referenced
this issue
Feb 17, 2022
* `D(devices.bundle).getBundlecap()`, not `getBundleCap` * `D(devices.bundle).getNamedBundlecap()`, not `getNamedBundleCap` I want code to use `bundlecap` in variable names, rather than `bundleCap`, and this reinforces the pattern. refs #4372
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What is the Problem Being Solved?
As detailed in #3269 (comment) , the goal of moving large contract bundles out of vat messages requires a "kernel-native" way to refer to code bundles. This also helps with vat upgrade, and even kernel/liveslots upgrade.
This ticket is specifically about implementing the bundle device and bundlecaps, not about how Agoric code will use them.
Description of the Design
As copied from #3269:
moduleFormat:
and some format-specific properties, whereendoZipBase64
is the only one acceptedb1-
concatenated with the lowercase hex-encoded SHA512 hash of the "compartment map" fileD(bundleCap).getBundle() -> bundle
methodcontroller.installBundle(allegedBundleID, bundle) -> bundleID or throws
is how you install a bundle at runtime, from the outside of the kernelD(devices.bundle).getBundleCap(bundleID) -> bundleCap
turns the hash into a bundleCapcontroller.installBundle
firstE(vatAdmin).createVat(bundleCap) -> { root, controlFacet }
turns bundleCaps into dynamic vatsimportBundle(D(bundleCap).getBundle()) -> Promise<namespace>
evaluates the bundle and gives you the resulting namespace, e.g. for when ZCF loads a contract bundleSecurity Considerations
Test Plan
The text was updated successfully, but these errors were encountered: