Agoric / agoric-sdk

monorepo for the Agoric Javascript smart contract platform
Apache License 2.0
327 stars 207 forks source link

Async-flow aware zone #10433

Open mhofman opened 2 weeks ago

mhofman commented 2 weeks ago

What is the Problem Being Solved?

To support async flow exo methods (#9832) without liveslots support (#9881), we need to provide exo state access on top of the existing exo infrastructure. This could be done as an async-flow aware zone which imposes some restrictions on exo definitions (no single facet exo, and possibly no singleton exo either), and expose the async flow maker on the zone itself, as well as supports guard "marks" to designate exo methods as being async flow enabled.

Description of the Design

An async-flow zone which does the following:

For compatibility with endowments, it would be great if the makers of these exos could be durable compatible, but that requires changes in the Virtual Object Manager to support in the first place.

Security Considerations

None, zones are already a user land wrapper on top VatData. This is simply further expanding the capabilities of that wrapper.

Scaling Considerations

To avoid rewriting the context object for every method call, it's preferable to prevent async flow methods on single facet exos, and disallow internal facet names from all multi facet exos (likely _ prefixed)

Test Plan

Fake liveslots based tests are likely sufficient

Upgrade Considerations

User land library update that can be published to NPM.

In case we ever implement support in liveslots for the state accessor facet (#9881), we may want newer definitions through this async-flow aware zone to use that mechanism, however for existing definitions we may need to maintain the behavior described above. This points towards a versioning of exo definitions, which is a similar problem to verifying baggage compatibility of exo definitions (see #10434)

mhofman commented 2 weeks ago

Related, we will likely want to make M.await be vow aware too (issue TBD), and figure out how M.callWhen and M.asyncFlow interact. (M.callWhen(M.asyncFlow(M.await(Foo))) ?)