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

feat(swingset): support raw devices #4419

Merged
merged 1 commit into from
Feb 4, 2022
Merged

feat(swingset): support raw devices #4419

merged 1 commit into from
Feb 4, 2022

Conversation

warner
Copy link
Member

@warner warner commented Jan 28, 2022

"Raw devices" bypass the deviceSlots layer and allow device code direct
access to syscall, and the arguments arriving through the dispatch object
it must produce. This makes some patterns much easier to implement, such as
producing new device nodes as part of the device's API (e.g. one device node
per code bundle).

It also provides vatstoreGet/Set/Delete, so the device code can manage one
piece of state at a time, instead of doing an expensive read-modify-write
cycle on a single large aggregate state object.

A helper library named deviceTools.js was added to make it slightly easier to
write a raw device.

In the longer run (see #1346), we'd like these devices to support Promises
and plain object references. This change doesn't go that far. The remaining
limitations are:

  • the deviceTools.js library refuses to handle exported objects, imported
    foreign device nodes, or promises of any sort
  • the outbound translator (deviceKeeper.js mapDeviceSlotToKernelSlot)
    refuses to handle exported objects and exported promises
  • the vat outbound translator (vatTranslator.js translateCallNow) refuses
    to handle promises
  • liveslots rejects promises in D() arguments

refs #1346

@warner warner added the SwingSet package: SwingSet label Jan 28, 2022
@warner warner requested a review from FUDCo January 28, 2022 23:22
@warner warner self-assigned this Jan 28, 2022
@warner warner force-pushed the warner-improve-swingset-types branch from f93f537 to 42cb11e Compare January 29, 2022 01:51
@warner warner force-pushed the warner-improve-swingset-types branch from 42cb11e to 85c2881 Compare January 29, 2022 02:26
@warner warner force-pushed the warner-improve-swingset-types branch from 85c2881 to 8de185f Compare January 29, 2022 06:01
@warner warner force-pushed the 1346-raw-device branch 2 times, most recently from 17a7b58 to 954c24c Compare January 31, 2022 00:25
@warner warner force-pushed the warner-improve-swingset-types branch from 3165b61 to 67cc5a4 Compare February 3, 2022 21:00
@warner warner force-pushed the warner-improve-swingset-types branch from 67cc5a4 to 52a96e2 Compare February 3, 2022 21:48
Base automatically changed from warner-improve-swingset-types to master February 3, 2022 22:05
Copy link
Contributor

@FUDCo FUDCo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine, modulo the concern I raised in my first comment which is a bigger question than is worth confronting in a PR.

This mode makes it possible to create new device nodes as part of the normal
API, because the code can learn the raw device ref (dref) of the target
device node on each inbound invocation, without needing a pre-registered
table of JavaScript `Object` instances for every export.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if an alternate model would be to implement devices using deviceSlots but treat the root object of a (more sophisticated kind of) device rather the way we treat the root object of a vat: the contact point for bootstrapping further interactions with whatever services it provides. As part of the API provided by deviceSlots, devices would have access to a createDeviceNode power that would create a device node that could be returned when a method is invoked on the root object. In essence, device node 0 would be qualitatively different: a privileged control device that hands out function-specific device nodes, in contrast to the function-specific device nodes themselves which would provide whatever services the "device" is being created to support.

Obviously this would require a somewhat different model than we have now of what it means to be the client of a device, since this controller vs. service distinction would have to be reflected in whatever vat(s) are using the device.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I think a more unified model (which would fully satisfy the goals of #1346) would probably allow the export of both objects and device nodes, and then the root could be a plain object, from which you must ask for device nodes via E() calls. maybe.

vatstoreGet: key => {
const dso = harden(['vatstoreGet', key]);
return deviceSyscallHandler(dso);
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choosing not to support vatstoreGetAfter or just not gotten around to it? I could argue the desirability of support this syscall either way.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not gotten around to it: my use case doesn't need it yet, and I didn't want to put the energy into figuring out the protective get-during-iterate invalidation logic we went through for vats. I'm happy to allow devices to use vatstoreGetAfter some day.

"Raw devices" bypass the deviceSlots layer and allow device code direct
access to `syscall`, and the arguments arriving through the `dispatch` object
it must produce. This makes some patterns much easier to implement, such as
producing new device nodes as part of the device's API (e.g. one device node
per code bundle).

It also provides vatstoreGet/Set/Delete, so the device code can manage one
piece of state at a time, instead of doing an expensive read-modify-write
cycle on a single large aggregate state object.

A helper library named deviceTools.js was added to make it slightly easier to
write a raw device.

In the longer run (see #1346), we'd like these devices to support Promises
and plain object references. This change doesn't go that far. The remaining
limitations are:

* the deviceTools.js library refuses to handle exported objects, imported
foreign device nodes, or promises of any sort
* the outbound translator (deviceKeeper.js `mapDeviceSlotToKernelSlot`)
refuses to handle exported objects and exported promises
* the vat outbound translator (vatTranslator.js `translateCallNow`) refuses
to handle promises
* liveslots rejects promises in `D()` arguments

refs #1346
@warner warner added the automerge:rebase Automatically rebase updates, then merge label Feb 4, 2022
@mergify mergify bot merged commit 72f4982 into master Feb 4, 2022
@mergify mergify bot deleted the 1346-raw-device branch February 4, 2022 02:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge:rebase Automatically rebase updates, then merge SwingSet package: SwingSet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants