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

feat: ChainAccountKit returns vows #9562

Merged
merged 4 commits into from
Jun 26, 2024
Merged

feat: ChainAccountKit returns vows #9562

merged 4 commits into from
Jun 26, 2024

Conversation

turadg
Copy link
Member

@turadg turadg commented Jun 21, 2024

refs: #9449

Description

  • More returning of vows, using asVow helper
  • Adjusts resumable custom lint rules to ignore onOpen and onClose when they are properties of connectionHandler
  • removes unused onReceive handler or connectionHandler for chainAccountKit and icqConnectionKit

Security Considerations

none

Scaling Considerations

none

Documentation Considerations

none

Testing Considerations

CI for now

Upgrade Considerations

not yet deployed

Copy link

cloudflare-workers-and-pages bot commented Jun 21, 2024

Deploying agoric-sdk with  Cloudflare Pages  Cloudflare Pages

Latest commit: 9bc7afb
Status: ✅  Deploy successful!
Preview URL: https://8ee90ae4.agoric-sdk.pages.dev
Branch Preview URL: https://9449-chain-account-vows.agoric-sdk.pages.dev

View logs

Base automatically changed from ta/heap-vows to master June 22, 2024 14:11
@michaelfig
Copy link
Member

My only question is: are you concerned that in a non-async function, a throw blah is synchronous, not reified as a return Promise.reject(blah)?

If you're fine with that, I will review this PR having understood that you're doing it in order to accommodate linting rules. My only request before I do, is that you update it with master to make the actual changes clearer to me.

Thanks!

@turadg
Copy link
Member Author

turadg commented Jun 23, 2024

are you concerned that in a non-async function, a throw blah is synchronous, not reified as a return Promise.reject(blah)?

Per #9449 these methods must always return Vows, so must not throw. IIUC returning a rejected promise is no better.

@@ -188,15 +187,27 @@ export const prepareChainAccountKit = (zone, { watch, when }) =>
chainId: this.state.chainId,
addressEncoding: 'bech32',
});
return Promise.resolve(watch(undefined));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why return anything here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consistent return type

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I relaxed the lint rule for connectionHandler > onOpen | onClose children in 2863d1b. The connectionHandler is only used internally by the exo, and won't/can't be called by a consumer of orchestrate. Replying to network vat with an empty vow / promise also seems like a waste since it's not interested in our answer.

An alternative explored was adjusting the types:

diff --git a/packages/network/src/types.js b/packages/network/src/types.js
index d40be9ad1..e70033ace 100644
--- a/packages/network/src/types.js
+++ b/packages/network/src/types.js
@@ -101,7 +101,7 @@ export {};
  *   localAddr: Endpoint,
  *   remoteAddr: Endpoint,
  *   c: Remote<ConnectionHandler>,
- * ) => PromiseVow<void>} [onOpen]
+ * ) => PromiseVow<void> | void} [onOpen]
  *   The connection has been opened
  * @property {(
  *   connection: Remote<Connection>,
@@ -114,7 +114,7 @@ export {};
  *   connection: Remote<Connection>,
  *   reason?: CloseReason,
  *   c?: Remote<ConnectionHandler>,
- * ) => PromiseVow<void>} [onClose]
+ * ) => PromiseVow<void | void>} [onClose]
  *   The connection has been closed
  *
  * @typedef {any | null} CloseReason The reason a connection was closed

trace(`ICA Channel onReceive`, connection, bytes);
return '';
return Promise.resolve(watch(''));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we instead do this?

Suggested change
return Promise.resolve(watch(''));
return watch(Promise.resolve(''));

Also, I'm not sure we need to return anything here - return '' might be an artifact from satisfying this type guard:

.returns(Shape.Data),

Copy link
Member

@0xpatrickdev 0xpatrickdev Jun 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need for the onReceive handler. I removed it in d6bd228

packages/orchestration/src/exos/chain-account-kit.js Outdated Show resolved Hide resolved
@michaelfig
Copy link
Member

Per #9449 these methods must always return Vows, so must not throw. IIUC returning a rejected promise is no better.

Please use the wrapper pattern recommended by @mhofman in #9454 (comment)

mergify bot added a commit that referenced this pull request Jun 25, 2024
refs: #9449

## Description

- Add `asVow` helper to `VowTools` to ensure we always return vows, even in the event of early synchronous errors.
- Implement the helper in `ChainAccountKit` against #9562
@0xpatrickdev
Copy link
Member

@michaelfig I've commandeered 🏴‍☠️ Turadg's PR if you could PTAL. When we come to agreement on the approach for connectionHandler, I will revise the PR body. Also tagging @dckc if he's interested to provide feedback.

@0xpatrickdev 0xpatrickdev requested a review from dckc June 25, 2024 20:26
@dckc
Copy link
Member

dckc commented Jun 25, 2024

... To conform to the new lint rules, this removes the async but returns Promise.resolve(watch( as an idiom for immediate PromiseVow.

is that still true? or is it overtaken by asVow?

Copy link
Member

@dckc dckc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a few non-critical suggestions

.eslintrc.cjs Outdated
Comment on lines 35 to 37
selector: 'FunctionExpression[async=true]',
selector:
'FunctionExpression[async=true]:not(Property[key.name="connectionHandler"] > ObjectExpression > Property[key.name=/^(onOpen|onClose)$/] > FunctionExpression[async=true])',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could sure use a comment to help read this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a comment in e7b839a

Comment on lines 145 to 146
// TODO #9281 do not throw synchronously when returning a promise; return a rejected Vow
/// see https://github.com/Agoric/agoric-sdk/pull/9454#discussion_r1626898694
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the addVow() call means this TODO is done now, isn't it?

Suggested change
// TODO #9281 do not throw synchronously when returning a promise; return a rejected Vow
/// see https://github.com/Agoric/agoric-sdk/pull/9454#discussion_r1626898694

Comment on lines 128 to 130
return asVow(() => {
throw new Error('not yet implemented');
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

orthogonal to this PR, but I think our preference is Error(...), not new Error(...)

Suggested change
return asVow(() => {
throw new Error('not yet implemented');
});
return asVow(() => {
throw Error('not yet implemented');
});

I'm struggling to confirm from Coding Style though.

Comment on lines 128 to 130
return asVow(() => {
throw new Error('not yet implemented');
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or, for brevity:

Suggested change
return asVow(() => {
throw new Error('not yet implemented');
});
return asVow(() => assert.fail('not yet implemented'));

const { connection } = this.state;
// TODO #9281 do not throw synchronously when returning a promise; return a rejected Vow
/// see https://github.com/Agoric/agoric-sdk/pull/9454#discussion_r1626898694
if (!connection) throw Fail`connection not available`;
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 partial to doing that on one line, but I'm pretty sure others prefer...

Suggested change
if (!connection) throw Fail`connection not available`;
if (!connection) {
throw Fail`connection not available`;
}

I'm not sure why our lint tools don't require that. Maybe it's OK.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (!connection) throw Fail`connection not available`;

doesn't seem too different from:

connection || Fail`connection not available`;

from a readability standpoint.

The latter I understand to be a preferred pattern, but it unfortunately does not satisfy ts-check.

I've implemented your other suggestions, thanks for the review!

turadg and others added 4 commits June 25, 2024 18:59
- ICA and ICQ channels only send outbound requests; they do not receive incoming requests they need to respond to
- renames ConnectionHandlerI to OutboundConnectionHandlerI to better reflect the behavior
…ble rule

- onOpen and onClose are event listeners that handle incoming notifications
- these methods do not return values and are not expected to be resumable
error TS2741: Property 'account' is missing in type '{}' but required in type '{ account: OrchestrationAccount<any> | undefined; }'
@0xpatrickdev 0xpatrickdev added the automerge:rebase Automatically rebase updates, then merge label Jun 25, 2024
@mergify mergify bot merged commit 23e1921 into master Jun 26, 2024
85 checks passed
@mergify mergify bot deleted the 9449-chain-account-vows branch June 26, 2024 00:28
gibson042 pushed a commit that referenced this pull request Jul 2, 2024
refs: #9449

## Description

- Add `asVow` helper to `VowTools` to ensure we always return vows, even in the event of early synchronous errors.
- Implement the helper in `ChainAccountKit` against #9562
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.

4 participants