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

IBC types and refactoring #9191

Merged
merged 8 commits into from
Apr 12, 2024
Merged

IBC types and refactoring #9191

merged 8 commits into from
Apr 12, 2024

Conversation

turadg
Copy link
Member

@turadg turadg commented Apr 3, 2024

refs: #9042

Description

In the course of reviewing #9114 it wasn't clear what the /ibc-hop encoding spec was. This PR separates an ibc-utils.js to try to encapsulate that. @iomekam @michaelfig can you provide some additional documentation on its design?

This also adds types I used to understand the code, dropping any bindings from 338 to 86.

One type change was in vows to add the context param.

Security Considerations

Scaling Considerations

Documentation Considerations

Testing Considerations

Upgrade Considerations

@turadg turadg marked this pull request as ready for review April 3, 2024 22:13
Copy link
Member

@michaelfig michaelfig left a comment

Choose a reason for hiding this comment

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

Thanks! This PR brings to light many of the subtle details of the IBC+network implementation. I really appreciate this effort, since it will result in better clarity.

I just took a quick look right now, but will drop some comments here and return to it later.

async onListen(_port, localAddr, _listenHandler) {
/**
* @param {Port} _port
* @param {LocalIbcAddress} localAddr
Copy link
Member

Choose a reason for hiding this comment

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

Implementation signatures of these callbacks, like onListen's localAddr parameter, must be compatible with their interface signatures, specified in packages/network/src/types.js. IBC is just the first of several possible supported network implementations.

export const REMOTE_ADDR_RE =
/^(\/ibc-hop\/[^/]+)*\/ibc-port\/([^/]+)\/(ordered|unordered)\/([^/]+)$/s;
harden(REMOTE_ADDR_RE);
/** @typedef {`/ibc-hop/${string}/ibc-port/${string}/{'ordered'|'unordered'}/${string}`} RemoteIbcAddress */
Copy link
Member

Choose a reason for hiding this comment

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

This is a valiant attempt at expressing the type of an IBC multiaddr, whose basic format is described in agoric-sdk/packages/network/src/multiaddr.js.

The REMOTE_ADDR_RE correctly specifies a remote address, but unfortunately, RemoteIbcAddress looks like it disallows certain details of the RE's structure, namely:

  1. zero or more /ibc-hop/${nonSlashString} prefixes, and
  2. all but the final ${string} cannot contain a slash.

Also, there's a simple typo (missing $ in ${'ordered'|'unordered'}).

) => {
const ibcHops = hops.map(hop => `/ibc-hop/${hop}`).join('/');
return /** @type {RemoteIbcAddress} */ (
`${ibcHops}/ibc-port/${rPortID}/${order.toLowerCase()}/${rVersion}/ibc-channel/${rChannelID}`
Copy link
Member

Choose a reason for hiding this comment

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

Do we want to distinguish between requested and negotiated (active) address? In the beginning of the channel lifecycle, I believe we'll want to omit /ibc-channel/${rChannelID}

Copy link
Member

Choose a reason for hiding this comment

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

Bumping this comment. It is maybe out of scope for the PR, but if we had encodeRequestedRemoteIbcAddress it could be used in makeICAChannelAddress in orchestration/src/utils/address.js.

Impartial to what you call these functions, but i think "requested" and "negotiated" are good keywords to use to distinguish between the behavior.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't have a well enough informed opinion on this yet. Open to it in a future PR

};
harden(encodeRemoteIbcAddress);

export const encodeLocalIbcAddress = (portID, order, version) => {
Copy link
Member

Choose a reason for hiding this comment

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

I think we might be able to add types for portID and rPortID. Maybe something like:

type LocalPortID =  `icacontroller-${number}` | `icqcontroller-${number}`;
type RemotePortID = 'transfer' | 'icahost' | 'icqhost';

Copy link
Member

Choose a reason for hiding this comment

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

I disagree here. That would be overspecification, which is a pitfall that ibc-go made when first specifying ICA. The names of ports (Identifiers) should be as general as what the IBC spec allows, not a restricted set of "what we think people will use".

Copy link
Member

Choose a reason for hiding this comment

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

Good feedback, thank you. Maybe these definitions should instead live in orchestration and extend the more generalized specification in here?

@turadg turadg marked this pull request as draft April 5, 2024 23:33
@turadg turadg marked this pull request as ready for review April 10, 2024 16:09
Copy link
Member

@michaelfig michaelfig left a comment

Choose a reason for hiding this comment

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

Please consider my feedback, but I don't see anything that absolutely must be addressed before merging.

Comment on lines 12 to 14
const match = remoteAddr.match(
/^(\/ibc-hop\/[^/]+)*\/ibc-port\/([^/]+)\/(ordered|unordered)\/([^/]+)$/s,
);
Copy link
Member

Choose a reason for hiding this comment

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

Why not:

Suggested change
const match = remoteAddr.match(
/^(\/ibc-hop\/[^/]+)*\/ibc-port\/([^/]+)\/(ordered|unordered)\/([^/]+)$/s,
);
const match = remoteAddr.match(REMOTE_ADDR_RE);

If that's not readable enough, we could switch to using named capturing groups

Copy link
Member Author

Choose a reason for hiding this comment

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

good idea!

packages/vats/tools/ibc-utils.js Outdated Show resolved Hide resolved
packages/vats/tools/ibc-utils.js Outdated Show resolved Hide resolved
packages/vats/tools/ibc-utils.js Outdated Show resolved Hide resolved
* @typedef {object} Watcher
* @property {(value: T) => Vow<TResult1> | PromiseVow<TResult1> | TResult1} [onFulfilled]
* @property {(value: T, context?: C) => Vow<TResult1> | PromiseVow<TResult1> | TResult1} [onFulfilled]
Copy link
Member

Choose a reason for hiding this comment

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

💯

@turadg turadg added the automerge:rebase Automatically rebase updates, then merge label Apr 10, 2024
Copy link

@turadg - This PR appears to be stuck. It's had a merge label for > 24 hours

@mergify mergify bot merged commit b5bea48 into master Apr 12, 2024
66 checks passed
@mergify mergify bot deleted the ta/ibc-types branch April 12, 2024 14:20
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.

3 participants