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

misc Orch factoring improvements #9676

Merged
merged 6 commits into from
Jul 10, 2024
Merged

misc Orch factoring improvements #9676

merged 6 commits into from
Jul 10, 2024

Conversation

turadg
Copy link
Member

@turadg turadg commented Jul 10, 2024

refs: #9449

Description

Adapted from #9657 . The retriable helper and withOrchestration refactor landed already.

This has the rest:

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

Copy link

cloudflare-workers-and-pages bot commented Jul 10, 2024

Deploying agoric-sdk with  Cloudflare Pages  Cloudflare Pages

Latest commit: ecb67b1
Status: ✅  Deploy successful!
Preview URL: https://5a41eef7.agoric-sdk.pages.dev
Branch Preview URL: https://ta-orch-factoring.agoric-sdk.pages.dev

View logs

Copy link
Member

@0xpatrickdev 0xpatrickdev left a 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.

Comment on lines +142 to +148
return {
...facade,
chainHub,
vowTools,
zoeTools,
zone: zones.contract,
};
Copy link
Member

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:

  1. Smaller bundles for guest code + less code on chain
  2. (marginal) less setup for devs since they can just grab a power

Copy link
Member Author

@turadg turadg Jul 10, 2024

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({
Copy link
Member

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?

Copy link
Member Author

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.

Copy link
Member

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)

Comment on lines +13 to +25
/**
* @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,
Copy link
Member

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?

Copy link
Member Author

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
Copy link
Member

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?

Copy link
Member Author

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?

Copy link
Member

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

Copy link
Member Author

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(
Copy link
Member

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.

Copy link
Member Author

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

Copy link
Member

@0xpatrickdev 0xpatrickdev Jul 10, 2024

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({
Copy link
Member

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
Copy link
Member

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(
Copy link
Member

@0xpatrickdev 0xpatrickdev Jul 10, 2024

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.

turadg and others added 6 commits July 10, 2024 12:14
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>
@turadg turadg added the automerge:rebase Automatically rebase updates, then merge label Jul 10, 2024
@mergify mergify bot merged commit 0b6d5f3 into master Jul 10, 2024
86 checks passed
@mergify mergify bot deleted the ta/orch-factoring branch July 10, 2024 20:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge:rebase Automatically rebase updates, then merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants