-
Notifications
You must be signed in to change notification settings - Fork 208
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
misc Orch factoring improvements #9676
Conversation
Deploying agoric-sdk with Cloudflare Pages
|
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.
LGTM. Holding approval til I better understand testing and the comment around seat recoverability.
return { | ||
...facade, | ||
chainHub, | ||
vowTools, | ||
zoeTools, | ||
zone: zones.contract, | ||
}; |
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.
Tangential - wondering what parts of this we can make widely available in the bootstrap space. Thinking the benefits would be:
- Smaller bundles for guest code + less code on chain
- (marginal) less setup for devs since they can just grab a power
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.
None because these all depend on a baggage from the host vat. We could put the withOrchestration
function in bootstrap to save bundling, but the more general solution to deduping across bundles is to let bundles import from other bundles. That's on the roadmap.
We can consider less maintainable hacks if we run up against bundle size limits and have no other options that are more maintainable.
// in guest file (the orchestration functions) | ||
// the second argument is all the endowments provided | ||
|
||
export const orchestrationFns = harden({ |
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 not crazy about moving this to a separate file. Did we feel sendAnywhere.contract.js
got too big, or was there a different motivation?
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.
Motivation is that it's a different runtime environment than the contract. Keeping the flows in a separate file will help prevent trying to access host values directly. Also it will let us improve linting. E.g. the "no async" lint rules need only apply to these files, not the contract.
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.
Keeping the flows in a separate file will help prevent trying to access host values directly
Agree, but putting them at the top of the file also achieves the same
the "no async" lint rules
Think you meant to say no E
, but I see your point. Noting this can be achieved intra-file with something like Property[key.name=/OfferHandler$/]
or Property[key.name=/Handler$/]
if we enforce the convention (sendIt -> sendItHandler)
/** | ||
* @param {Orchestrator} orch | ||
* @param {object} ctx | ||
* @param {{ account: OrchestrationAccount<any> }} ctx.contractState | ||
* @param {any} ctx.localTransfer | ||
* @param {any} ctx.findBrandInVBank | ||
* @param {ZCFSeat} seat | ||
* @param {{ chainName: string; destAddr: string }} offerArgs | ||
*/ | ||
async sendIt( | ||
orch, | ||
{ contractState, localTransfer, findBrandInVBank }, | ||
seat, |
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.
Is there anything we can do to reduce boilerplate around this? (orch
, ctx
, seat
params). The bulk of the noise in kitchen-sink.contract.js seems to be from these.
Maybe curry orch and ctx so sendIt
takes the normal OfferHandler
type?
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.
because sendIt is a flow (guest fn) and not a regular function I think that's asking for trouble
const userSeat = await userSeatP; | ||
atomicTransfer(zcf, srcSeat, tempSeat, give); | ||
tempSeat.exit(); | ||
// TODO get the userSeat into baggage so it's at least recoverable |
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's stopping us from doing this now?
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's no specific impediment. the TODO is because it's not done. Are you requesting that it be done before any of this lands?
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 was more so curious, but if it's not a lot of effort it would be nice to see in this PR. If not, a ticket number so we remember to come back to it would be helpful
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's some design to figure out wrt subZone
* @param {AmountKeywordRecord} give | ||
* @returns {Promise<void>} | ||
*/ | ||
const localTransfer = vowTools.retriable( |
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's the best test to look at for this? sendAnywhere.test.ts
should no longer have warnings about promises from async-flow
?
Tangential: swapExample.test.ts
has a test.skip we can hopefully restore soon.
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, the sendAnywhere test. I'm not aware of those warnings but if the test passes then this function works
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.
They look something like this on master
and what we are trying to eliminate with #9449:
Warning for now: vow expected, not promise Promise { }
Warning for now: vow expected, not promise Promise { <pending> } (Error#1)
Error#1: where warning happened
at tolerateHostPromiseToVow (.../async-flow/src/replay-membrane.js:157:9)
at eval (.../common/object-map.js:45:40)
at Array.map (<anonymous>)
at objectMap (.../common/object-map.js:44:20)
at tolerateHostPromiseToVow (.../async-flow/src/replay-membrane.js:168:8)
at performCall (.../async-flow/src/replay-membrane.js:196:12)
at guestCallsHost (.../async-flow/src/replay-membrane.js:256:9)
at In "makeEmptySeatKit" method of (zcf) [as makeEmptySeatKit] (.../async-flow/src/replay-membrane.js:525:8)
at withdrawFromSeat (.../zoe/src/contractSupport/zoeHelpers.js:226:52)
at sendItFn (.../orchestration/src/examples/sendAnywhere.contract.js:71:24)
Warning for now: vow expected, not promise Promise { <pending> } (Error#2)
Error#2: where warning happened
at tolerateHostPromiseToVow (.../async-flow/src/replay-membrane.js:157:9)
at eval (.../common/object-map.js:45:40)
at Array.map (<anonymous>)
at objectMap (.../common/object-map.js:44:20)
at tolerateHostPromiseToVow (.../async-flow/src/replay-membrane.js:168:8)
at performCall (.../async-flow/src/replay-membrane.js:196:12)
at guestCallsHost (.../async-flow/src/replay-membrane.js:256:9)
at In "makeEmptySeatKit" method of (zcf) [as makeEmptySeatKit] (.../async-flow/src/replay-membrane.js:525:8)
at withdrawFromSeat (.../zoe/src/contractSupport/zoeHelpers.js:226:52)
at sendItFn (.../orchestration/src/examples/sendAnywhere.contract.js:71:24)
Warning for now: vow expected, not promise Promise { <pending> } (Error#3)
Error#3: where warning happened
at tolerateHostPromiseToVow (.../async-flow/src/replay-membrane.js:157:9)
at eval (.../common/object-map.js:45:40)
at Array.map (<anonymous>)
at objectMap (.../common/object-map.js:44:20)
at tolerateHostPromiseToVow (.../async-flow/src/replay-membrane.js:168:8)
at performCall (.../async-flow/src/replay-membrane.js:196:12)
at guestCallsHost (.../async-flow/src/replay-membrane.js:256:9)
at In "makeEmptySeatKit" method of (zcf) [as makeEmptySeatKit] (.../async-flow/src/replay-membrane.js:525:8)
at withdrawFromSeat (.../zoe/src/contractSupport/zoeHelpers.js:226:52)
at sendItFn (.../orchestration/src/examples/sendAnywhere.contract.js:71:24)
But are no longer present in this PR 🎉 .
Hoping we can tighten the warning to an error, perhaps with the closing of #9449. We might also consider a parameter to asyncFlow tools to toggle the behavior while E
support is being worked out.
// in guest file (the orchestration functions) | ||
// the second argument is all the endowments provided | ||
|
||
export const orchestrationFns = harden({ |
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.
Keeping the flows in a separate file will help prevent trying to access host values directly
Agree, but putting them at the top of the file also achieves the same
the "no async" lint rules
Think you meant to say no E
, but I see your point. Noting this can be achieved intra-file with something like Property[key.name=/OfferHandler$/]
or Property[key.name=/Handler$/]
if we enforce the convention (sendIt -> sendItHandler)
const userSeat = await userSeatP; | ||
atomicTransfer(zcf, srcSeat, tempSeat, give); | ||
tempSeat.exit(); | ||
// TODO get the userSeat into baggage so it's at least recoverable |
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 was more so curious, but if it's not a lot of effort it would be nice to see in this PR. If not, a ticket number so we remember to come back to it would be helpful
* @param {AmountKeywordRecord} give | ||
* @returns {Promise<void>} | ||
*/ | ||
const localTransfer = vowTools.retriable( |
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.
They look something like this on master
and what we are trying to eliminate with #9449:
Warning for now: vow expected, not promise Promise { }
Warning for now: vow expected, not promise Promise { <pending> } (Error#1)
Error#1: where warning happened
at tolerateHostPromiseToVow (.../async-flow/src/replay-membrane.js:157:9)
at eval (.../common/object-map.js:45:40)
at Array.map (<anonymous>)
at objectMap (.../common/object-map.js:44:20)
at tolerateHostPromiseToVow (.../async-flow/src/replay-membrane.js:168:8)
at performCall (.../async-flow/src/replay-membrane.js:196:12)
at guestCallsHost (.../async-flow/src/replay-membrane.js:256:9)
at In "makeEmptySeatKit" method of (zcf) [as makeEmptySeatKit] (.../async-flow/src/replay-membrane.js:525:8)
at withdrawFromSeat (.../zoe/src/contractSupport/zoeHelpers.js:226:52)
at sendItFn (.../orchestration/src/examples/sendAnywhere.contract.js:71:24)
Warning for now: vow expected, not promise Promise { <pending> } (Error#2)
Error#2: where warning happened
at tolerateHostPromiseToVow (.../async-flow/src/replay-membrane.js:157:9)
at eval (.../common/object-map.js:45:40)
at Array.map (<anonymous>)
at objectMap (.../common/object-map.js:44:20)
at tolerateHostPromiseToVow (.../async-flow/src/replay-membrane.js:168:8)
at performCall (.../async-flow/src/replay-membrane.js:196:12)
at guestCallsHost (.../async-flow/src/replay-membrane.js:256:9)
at In "makeEmptySeatKit" method of (zcf) [as makeEmptySeatKit] (.../async-flow/src/replay-membrane.js:525:8)
at withdrawFromSeat (.../zoe/src/contractSupport/zoeHelpers.js:226:52)
at sendItFn (.../orchestration/src/examples/sendAnywhere.contract.js:71:24)
Warning for now: vow expected, not promise Promise { <pending> } (Error#3)
Error#3: where warning happened
at tolerateHostPromiseToVow (.../async-flow/src/replay-membrane.js:157:9)
at eval (.../common/object-map.js:45:40)
at Array.map (<anonymous>)
at objectMap (.../common/object-map.js:44:20)
at tolerateHostPromiseToVow (.../async-flow/src/replay-membrane.js:168:8)
at performCall (.../async-flow/src/replay-membrane.js:196:12)
at guestCallsHost (.../async-flow/src/replay-membrane.js:256:9)
at In "makeEmptySeatKit" method of (zcf) [as makeEmptySeatKit] (.../async-flow/src/replay-membrane.js:525:8)
at withdrawFromSeat (.../zoe/src/contractSupport/zoeHelpers.js:226:52)
at sendItFn (.../orchestration/src/examples/sendAnywhere.contract.js:71:24)
But are no longer present in this PR 🎉 .
Hoping we can tighten the warning to an error, perhaps with the closing of #9449. We might also consider a parameter to asyncFlow tools to toggle the behavior while E
support is being worked out.
Co-Authored-By: Dean Tribble <dtribble@users.noreply.github.com>
Co-Authored-By: Dean Tribble <dtribble@users.noreply.github.com>
Co-Authored-By: Dean Tribble <dtribble@users.noreply.github.com>
Co-Authored-By: Dean Tribble <dtribble@users.noreply.github.com>
56c16b4
to
ecb67b1
Compare
refs: #9449
Description
Adapted from #9657 . The
retriable
helper andwithOrchestration
refactor landed already.This has the rest:
withdrawFromSeat
à la orchestration facade returns promises backed by vows #9449 )Security Considerations
orchestrateAll
grants the same context to each orchFn. If they have to be different, the author can make multiple calls grouping what is the same.Improves POLA of some Orchestration services by passing a
makeOrchestrator
.Scaling Considerations
none
Documentation Considerations
none yet
Testing Considerations
CI
Upgrade Considerations
not yet deployed