endo icon indicating copy to clipboard operation
endo copied to clipboard

Promise for non-Passable is not Passable

Open turadg opened this issue 1 year ago • 4 comments

Refs: #2406

Description

@mhofman suggested a fix for the FIXME in #2406. As expected it trip on recursion:

packages/pass-style/src/deeplyFulfilled.js:74:32 - error TS2589: Type instantiation is excessively deep and possibly infinite.

74 export const deeplyFulfilled = async val => {
                                  ~~~~~~~~~~~~~~

Leaving this PR in draft until that's solved. @mhofman @michaelfig feel free to push commits.

Security Considerations

Does this change introduce new assumptions or dependencies that, if violated, could introduce security vulnerabilities? How does this PR change the boundaries between mutually-suspicious components? What new authorities are introduced by this change, perhaps by new API calls?

Scaling Considerations

Does this change require or encourage significant increase in consumption of CPU cycles, RAM, on-chain storage, message exchanges, or other scarce resources? If so, can that be prevented or mitigated?

Documentation Considerations

Give our docs folks some hints about what needs to be described to downstream users. Backwards compatibility: what happens to existing data or deployments when this code is shipped? Do we need to instruct users to do something to upgrade their saved data? If there is no upgrade path possible, how bad will that be for users?

Testing Considerations

Every PR should of course come with tests of its own functionality. What additional tests are still needed beyond those unit tests? How does this affect CI, other test automation, or the testnet?

Compatibility Considerations

Does this change break any prior usage patterns? Does this change allow usage patterns to evolve?

Upgrade Considerations

What aspects of this PR are relevant to upgrading live production systems, and how should they be addressed?

Include *BREAKING*: in the commit message with migration instructions for any breaking change.

Update NEWS.md for user-facing changes.

Delete guidance from pull request description before merge (including this!)

turadg avatar Aug 20 '24 20:08 turadg

Promise for non-Passable is not Passable

When I first read this, I thought it was about promises and whether they were passable. Took me a bit to understand that this is actually about the Promise type and the Passable type. Would be good to rephrase to make clear this is not about what might actually happen at runtime.

The fact that a passable unresolved promise might later fulfill to a non-passable value is a significant hazard in our system we need to remain aware of, whatever the type system might claim to the contrary.

erights avatar Aug 20 '24 23:08 erights

The fact that a passable unresolved promise might later fulfill to a non-passable value is a significant hazard in our system we need to remain aware of, whatever the type system might claim to the contrary.

This is a good point, maybe this point to a mistake in the approach. The Promise (if an expected PassableCap) is Passable, but the result value may be never if it's itself non-Passable.

Edit: Ugh I keep confusion what happens between Passable definition and mapped types of potentially passable.

mhofman avatar Aug 20 '24 23:08 mhofman

I think I found a way to break the recursion issues, albeit with a theoretically breaking change in the type definition of Passable, but in practice I think it's backwards compatible.

I also took the opportunity to further narrow the type of PassableCap: when a promise, it's only a promise for a RemotableObject. I believe it matches actual explicit usages of the type.

I have not tested this change applied to agoric-sdk yet.

mhofman avatar Aug 21 '24 07:08 mhofman

tested this change applied to agoric-sdk

We can use https://github.com/Agoric/agoric-sdk/pull/9385 . I've pointed it to this branch.

Results with 017b2c8

turadg avatar Aug 21 '24 15:08 turadg