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

Constraint decider changes to simplify promise enqueuing logic #5023

Closed
mhofman opened this issue Apr 6, 2022 · 1 comment · Fixed by #5124
Closed

Constraint decider changes to simplify promise enqueuing logic #5023

mhofman opened this issue Apr 6, 2022 · 1 comment · Fixed by #5124
Assignees
Labels
enhancement New feature or request SwingSet package: SwingSet
Milestone

Comments

@mhofman
Copy link
Member

mhofman commented Apr 6, 2022

What is the Problem Being Solved?

Technically the kernel allows a decider to got from the exporting vat, to the kernel, to another vat, back to the kernel, then to another vat, etc. The decider can change one of 2 ways:

  • An existing promise is used as the result of a send
  • A promise is forwarded to another promise

In practice neither can currently happen:

  • liveslots and comms vat always create a new promise
  • Forwarding is not implemented

Description of the Design

If we assume that the decider will never change more than vat exporting new promise -> kernel -> receiver of message tied to result promise, then messages sent to the promise can only ever be placed on the promise queue (while the kernel is decider, or if the decider vat doesn't support pipelining), or the decider pipelining vat (aka comms only for now), and will only ever move from the first to the second.

This ties in with #4542 so that messages can be enqueued to the correct queue right away.

In the future, when forwarding is supported, simply placing a forwarding on the vat outbound queue will need to synchronously pluck messages sent to the promise that were sitting on the pipelining vat's inbound queue, and move them back to the kernel's promise's queue until the forwarding is later processed from the outbound queue.

Security Considerations

Audit kernel and liveslot code which deals with decider changes, and add assertions as necessary.

Test Plan

Update existing unit tests and add new negative tests.

@mhofman mhofman added enhancement New feature or request SwingSet package: SwingSet labels Apr 6, 2022
@mhofman mhofman self-assigned this Apr 6, 2022
@Tartuffo Tartuffo added this to the Mainnet 1 milestone Apr 6, 2022
@mhofman
Copy link
Member Author

mhofman commented Apr 14, 2022

After looking deeper into this, @warner and I realized that comms may in fact re-use an imported promise as the result of another send:

  • B exports a promise to A (e.g nested inside resolution data, or as arguments)
  • B learns that the previously exported promise is resolved, and the resolution is an object in A
  • B notifies A about the resolution (A was automatically subscribed), and begins retiring the promise
  • B receives a message from A targeted at the promise, with a result promise allocated by A. The message was already in flight / A hadn't heard about the resolution yet
  • B turns around and send the message back to the resolved target in A, and re-uses the result promise A had allocated
  • A receives the resolve from B
  • A receives the send from B for its own object, but its using a result promise that A had initially exported to B

Furthermore, there are legitimate cases where the kernel will need to pluck or gate messages pending in a pipelining vat's inbound queue to prevent delivering them:

  • Kernel queues message send for an object onto pipelining vat, marking the result promise as decided by the vat
  • kernel queues message send for the result promise onto the pipelining vat
  • vat processes the object send, and messages the kernel with a resolve for the result promise using an object owned by another vat of the kernel (allowing it to forget about the promise)
  • kernel can no longer deliver the pending messages for the promise to the pipelining vat, and must redirect them appropriately

This summary is that:

  • Comms must be able to reuse an existing promise when processing a remote message, regardless of whether it was imported or exported by the remote
  • A pipelining vat like comms must be allowed to use an imported promise it's the decider of as the result of a message send. However liveslots will never produce such a case: it doesn't support pipelining and cannot realize ahead of time that the result of a send done by the contract will be later used as the return value of the current delivery (this would require some static analysis of the code / compilation to non JavaScript)
  • The kernel must handle pending messages pipelined to a promise when that promise is resolved

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request SwingSet package: SwingSet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants