-
Notifications
You must be signed in to change notification settings - Fork 212
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
9449 membrane types #9685
9449 membrane types #9685
Conversation
Deploying agoric-sdk with Cloudflare Pages
|
be1b9e8
to
7aa206d
Compare
7aa206d
to
7bf6edf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only reviewed asyncFlow changes so far. More soon...
@@ -154,14 +154,9 @@ export const makeReplayMembrane = ({ | |||
const passStyle = passStyleOf(h); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love that we can now stop tolerating host promises and instead reject them with errors!
However, this leaves the doc-comment above and the function name tolerate*
stale. Please revise to be consistent either with consistent rejection, or at least as the function which decides whether to tolerate or to reject. I don't have a name to suggest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok to fully remove tolerateHostPromiseToVow
? I was trying to be surgical because I didn't know if you needed it to be there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removal is good
export type GuestOf<F extends HostAsyncFuncWrapper> = F extends ( | ||
...args: infer A | ||
) => Vow<infer R> | ||
? (...args: A) => Promise<R> | ||
: F; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow!
Thanks for translating all those type declarations into better .d.ts types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tsc did the work! yarn prepack
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL! Good to know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work 👏
async-flow/src/types.d.ts#L118-L252 is foreign to me but seems like its mostly porting things from js to ts
// XXX makeAccount returns a Promise for an exo but reserves being able to return a vow | ||
// so we use heapVowE to shorten the promise path | ||
// eslint-disable-next-line no-restricted-syntax -- will run in one turn | ||
allVows([lcaP, heapVowE(lcaP).getAddress()]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised we need to reach for heapVowE here. Original E + pipelining should work, since lcaP
is a Promise and not a Vow. There's a test demonstrating the behavior mentioned in: #9591 (comment)
Maybe we need to improve the ah allVows
type?E
doesn't understand PromiseVow
. Still, seems like it's maybe a type issue and we shouldn't need heapVowE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to explain this in the comment. The value actually being returned is not a vow, but the return signature says it could be. @michaelfig wanted to reserve that option for the future. So this code should comply. (i.e. not to accelerate Hyrum's Law).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense, thanks
/** | ||
* Public topics are a map to different vstorage paths and subscribers that | ||
* can be shared with on or offchain clients. | ||
* When returned as part of a continuing invitation, it will appear | ||
* in the {@link CurrentWalletRecord} in vstorage. | ||
*/ | ||
getPublicTopics: () => Promise<TopicsRecord>; | ||
getPublicTopics: () => Promise<Record<string, ResolvedPublicTopic<unknown>>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. Consider exporting a ResolvedTopicsRecord
from zoe/contractSupport/topics.js
| 'Done'; | ||
|
||
/** | ||
* `T` defaults to `any`, not `Passable`, because unwrapped guests include |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Realize this is an existing comment, but consider an @internal
directive
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when I added it there was a jsdoc lint error the tag should be empty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does @internal mean/do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#9690 fixes the lint error. I'm still not sure whether this should be @internal
.
type HostInterface<T> = { | ||
[K in keyof T]: HostOf<T[K]>; | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work on these. Do we also need a GuestInterface
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When we define an interface it should be in the view of the guest.
return watch(h); | ||
const e = Error('where promise detected'); | ||
console.error('vow expected, not promise', h, e); | ||
throw e; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👏
@@ -21,6 +21,16 @@ export const PublicTopicShape = M.splitRecord( | |||
* }} PublicTopic | |||
*/ | |||
|
|||
/** | |||
* A {PublicTopic} in which the `storagePath` is a string. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a why to one of the Resolved*
types
* A {PublicTopic} in which the `storagePath` is a string. | |
* A {PublicTopic} in which the `storagePath` is a string. | |
* Useful when working with Vows and async-flow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good idea. we can use more "what this is for"
@@ -83,7 +84,7 @@ export const IcaAccountHolderI = M.interface('IcaAccountHolder', { | |||
undelegate: M.call(M.arrayOf(DelegationShape)).returns(VowShape), | |||
}); | |||
|
|||
/** @type {{ [name: string]: [description: string, valueShape: Pattern] }} */ | |||
/** @type {{ [name: string]: [description: string, valueShape: Matcher] }} */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why change the type from Pattern
to Matcher
? Do you intend to exclude other patterns that are not themselves matchers, even if they contain matchers?
Likewise for other similar changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why change the type from Pattern to Matcher?
because makeRecordKit
accepts only a Matcher for the valueShape:
agoric-sdk/packages/zoe/src/contractSupport/recorder.js
Lines 148 to 149 in 4d54c56
* @param {TypedMatcher<T>} [valueShape] | |
* @returns {RecorderKit<T>} |
Do you intend to exclude other patterns that are not themselves matchers, even if they contain matchers?
For now.
agoric-sdk/packages/zoe/src/contractSupport/recorder.js
Lines 261 to 271 in 4d54c56
/** | |
* Stop-gap until https://github.com/Agoric/agoric-sdk/issues/6160 | |
* explictly specify the type that the Pattern will verify through a match. | |
* | |
* This is a Pattern but since that's `any`, including in the typedef turns the | |
* whole thing to `any`. | |
* | |
* @template T | |
* @typedef {import('@endo/patterns').Matcher & { validatedType?: T }} TypedMatcher | |
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pattern
is no longer any
(thanks to you IIRC)
@typedef {Exclude<Passable, Error | Promise>} Pattern
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. From endojs/endo#2238
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, we can fix that now: 6b41829
@@ -59,7 +60,7 @@ const HolderI = M.interface('holder', { | |||
executeTx: M.call(M.arrayOf(M.record())).returns(Vow$(M.record())), | |||
}); | |||
|
|||
/** @type {{ [name: string]: [description: string, valueShape: Pattern] }} */ | |||
/** @type {{ [name: string]: [description: string, valueShape: Matcher] }} */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pattern vs matcher
now in packages/async-flow
86e05ae
to
f10c9c1
Compare
@Mergifyio requeue main |
✅ The queue state of this pull request has been cleaned. It can be re-embarked automatically |
@Mergifyio queue main |
🛑 The pull request has been removed from the queue
|
@Mergifyio requeue main |
☑️ This pull request is already queued |
This is failing only on getting-started link-cli because of a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is one behavioral change in this PR, and it is problematic
const { remoteChainInfo, connectionInfo } = this.state; | ||
const stakingDenom = remoteChainInfo.stakingTokens?.[0]?.denom; | ||
if (!stakingDenom) { | ||
return asVow(Fail`chain info lacks staking denom`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will not do what you expect, and throw an error instead of returning a rejected vow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should have been this?
return asVow(Fail`chain info lacks staking denom`); | |
return asVow(() => Fail`chain info lacks staking denom`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would work but I'm not sure why this PR removed the surrounding asVow
in the first place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I the assume bug is that Fail
throws immediately here instead of propoagating as a vow?
What's a good way to catch this in a test? When reviewing this, I made similar edits to cosmos-orch-acct and didn't see any of these tests break:
agoric-sdk/packages/orchestration/test/examples/stake-ica.contract.test.ts
Lines 246 to 261 in 24528f1
await t.throwsAsync(E(account).getBalances(), { | |
message: 'not yet implemented', | |
}); | |
await t.throwsAsync(E(account).send(mockChainAddress, mockAmountArg), { | |
message: 'not yet implemented', | |
}); | |
// XXX consider, positioning amount + address args the same for .send and .transfer | |
await t.throwsAsync(E(account).transfer(mockAmountArg, mockChainAddress), { | |
message: 'not yet implemented', | |
}); | |
await t.throwsAsync(E(account).transferSteps(mockAmountArg, null as any), { | |
message: 'not yet implemented', | |
}); | |
await t.throwsAsync(E(account).withdrawRewards(), { | |
message: 'Not Implemented. Try using withdrawReward.', | |
}); |
The above does not go through the membrane, though. Would the membrane catch this? On my short list to test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didn't see any of these tests break
yeah, we need breaking tests. Addressing in #9696
follow up on #9449 ## Description #9685 unwrapped an `asVow()` to get the promise failure to propagate. This reverts that now that #9704 removed the need for it. ### Security Considerations none ### Scaling Considerations none ### Documentation Considerations none ### Testing Considerations CI ### Upgrade Considerations not yet deployed
closes: #9449
Description
Address all the FIXMEs about types and vows in Orchestration. To do so I moved some stuff down to async-flow and zoe packages. I also made some small fixes in smart-wallet.
I believe this ticks the last box of #9449.
Security Considerations
none
Scaling Considerations
none
Documentation Considerations
none
Testing Considerations
This adds type tests and I used
type-coverage
to verify no regressions.Upgrade Considerations
orchestration and async-flow not yet deployed.
The changes in zoe and smart-wallet are just typedefs so safe to deploy anytime.