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

devices cannot persist exports #62

Open
warner opened this issue Oct 16, 2019 · 0 comments
Open

devices cannot persist exports #62

warner opened this issue Oct 16, 2019 · 0 comments
Labels
SwingSet package: SwingSet

Comments

@warner
Copy link
Member

warner commented Oct 16, 2019

@Chris-Hibbert, working on the Timer device in Agoric/SwingSet#123, discovered that our devices cannot persist exported device nodes, which is a shame. The workaround is to index device nodes with integers, pair each device with a Vat, give the Vat full authority over the device (i.e. the right to issue commands with an integer node index), and have the Vat issue lower-authority objects to downstream clients.

We initially talked about introducing these per-device Vats as a way to enable migration of downstream client vats (i.e. "device comity") since devices themselves certainly aren't going to be migratory. But this limitation may provide a second motivation for these extra vats.

I wasn't expecting this limitation when I originally implemented devices: I wanted them to be full participants in the POLA world. I decided that transcript-based persistence wouldn't work, because a device's internal state is a function of both deterministic/repeatable inbound messages, and non-deterministic host-level stuff (like messages arriving, or clocks ticking, or Balances shifting). I figured it would be easier to get right if we make devices be responsible for their own persistence, giving them a getDeviceState() and setDeviceState() API.

To accomodate the Mailbox device that needs to remember an imported inboundHandler, I made setDeviceState() serialize a state object in the same way as message sends work: m.serialize(), which references the c-lists. This allows the state object to include references to imports, which allowed inboundHandler to work: the kernel remembers that some other Vat exported the handler, and the device's c-list imports it (under some device-specific ObjectID), and the call to getDeviceState() (which does m.unserialize()) causes that ObjectID/oid to be wrapped in a Presence and returned to the startup code. The Presence created in one generation wraps a specific oid, and any Presence wrapping that same oid (e.g. in the subsequent generation) will behave the same way. So we don't really need anything beyond the oid to capture the behavior.

But exports are different: they have device-defined methods, and can close over other values (like the expiration time and repeat interval, in the Timer device). There are only two orthogonal/transparent ways to implement this: replaying a transcript, or engine-level heap snapshots. We can't use the former easily, and we don't have the latter.

We could imagine an API in which the device's startup code creates a new object and somehow registers it with the state-management calls. Something that could retrieve a state object from getDeviceState() which contains "export holes", and then create new objects and register them as filling the holes. The device wouldn't be ready for messages until it finished filling all the holes, because any inbound message might target the export inside one of those holes.

But for now, since we want the paired Vat for migration/comity purposes, we're going to fall back to the easier approach of giving each "export" a simple integer index. The only real export is the root object, which is held (closely) by the paired Vat. The Timer Device's API will be rewritten to accept a small number of methods on this root object (more deserving of the name "function" than the name "method", really), each of which will accept an integer describing which timer or repeater or whatever is being addressed. Then the paired Vat will export distinct objects that each wrap an integer and curry it into the methods that it exposes to downstream clients.

@warner warner transferred this issue from Agoric/SwingSet Dec 1, 2019
@warner warner added the SwingSet package: SwingSet label Dec 1, 2019
dckc pushed a commit to dckc/agoric-sdk that referenced this issue Dec 5, 2019
dckc pushed a commit to dckc/agoric-sdk that referenced this issue Dec 5, 2019
dckc pushed a commit to dckc/agoric-sdk that referenced this issue Dec 5, 2019
R4R: Translate document of ledger to chinese. Related: Agoric#62
dckc pushed a commit to dckc/agoric-sdk that referenced this issue Dec 5, 2019
make kernel log do varargs and abbreviate long strings
dckc pushed a commit to dckc/agoric-sdk that referenced this issue Dec 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
SwingSet package: SwingSet
Projects
None yet
Development

No branches or pull requests

2 participants