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: CosmosChainInfo includes pfmEnabled: bool #10329

Merged
merged 12 commits into from
Nov 26, 2024
Merged

Conversation

0xpatrickdev
Copy link
Member

@0xpatrickdev 0xpatrickdev commented Oct 23, 2024

refs: #10006
refs: #10445

Description

  • adds pfmEnabled: bool to CosmosChainInfo to support multi-hop forwarding logic
  • adds and exports withChainCapabilities helper that mixes in PfmEnabled and IcqEnabled constants to ChainInfo
  • adds and exports registerChainsAndAssets helper that registers info in a chainHub in a contract startFn
  • implements chainHub initialization in fast-usdc and send-anywhere contracts

Security Considerations

  • chain-capabilities.js is authoritative, but consumers have the ability to provide their own data. It's not published to vstorage and will be mixed in to local ChainHub's in example contracts that rely on it.

Scaling Considerations

  • Authors must maintain chain-capabilities.js over time

Documentation Considerations

  • documented via typedoc

Testing Considerations

  • updates snapshot tests

Upgrade Considerations

Library code, part of an NPM Orch release

Copy link

cloudflare-workers-and-pages bot commented Oct 23, 2024

Deploying agoric-sdk with  Cloudflare Pages  Cloudflare Pages

Latest commit: 118bc6a
Status: ✅  Deploy successful!
Preview URL: https://305f3f1e.agoric-sdk.pages.dev
Branch Preview URL: https://10006-transfer-pfm.agoric-sdk.pages.dev

View logs

Comment on lines 360 to 362
{ opts, amount, destination },
{ opts, denomAmount, destination, isPfm },
Copy link
Member

Choose a reason for hiding this comment

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

is renaming the amount property a breaking change?

probably doesn't matter yet, but we should keep this sort of thing in mind

Copy link
Member Author

Choose a reason for hiding this comment

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

This change will be part of a new PR, see comment, but thanks for pointing this out.

This interface is part of .transfer()'s internals, and doesn't get exposed to a consumer. I believe that means it's not a breaking change, but let me know if that's off base. Exo upgrade considerations are something I'm always looking to better understand.

Copy link
Member

Choose a reason for hiding this comment

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

The state record gets written to virtual storage. Upgraded exos have to use the same state properties, IIUC.
I think our baggage test captures this. Once the contract is deployed, we're committed to the state in baggage. We can evolve it, but only in certain limited ways.

@0xpatrickdev
Copy link
Member Author

0xpatrickdev commented Nov 11, 2024

Reviewers, we are moving the .transfer() changes to a new PR (tracked by #10445) and keeping this scoped to ChainInfo changes.

@0xpatrickdev 0xpatrickdev changed the title feat(local-orchestration-account): transfer supports multi-hop pfm routes feat: CosmosChainInfo includes pfmEnabled: bool Nov 11, 2024
@0xpatrickdev 0xpatrickdev assigned 0xpatrickdev and unassigned iomekam Nov 11, 2024
@0xpatrickdev 0xpatrickdev force-pushed the 10006-transfer-pfm branch 2 times, most recently from e0fbda5 to d8057f2 Compare November 11, 2024 16:32
@0xpatrickdev 0xpatrickdev marked this pull request as ready for review November 11, 2024 16:38
@0xpatrickdev 0xpatrickdev requested a review from a team as a code owner November 11, 2024 16:38
@0xpatrickdev 0xpatrickdev added the force:integration Force integration tests to run on PR label Nov 12, 2024
@0xpatrickdev 0xpatrickdev force-pushed the 10006-transfer-pfm branch 4 times, most recently from 5617071 to 784feb2 Compare November 12, 2024 01:39
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.

Putting stuff that does not come from the chain registry into fetched-chain-info doesn't seem right to me.

Whatever consumes fetched-chain-info should mix in PFM_ENABLED, IMO.

#!/usr/bin/env tsx
#!/usr/bin/env TS_BLANK_SPACE_EMIT=false node --import ts-blank-space/register
Copy link
Member

Choose a reason for hiding this comment

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

interesting!

Comment on lines 98 to 99
icqEnabled: ICQ_ENABLED.includes(
// @ts-expect-error string not assignable to `ICQ_ENABLED` const
Copy link
Member

Choose a reason for hiding this comment

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

suggestion: cast ICQ_ENABLED to string[] instead.

@@ -9,6 +9,7 @@ export default /** @type {const} } */ ({
},
],
icqEnabled: false,
pfmEnabled: true,
Copy link
Member

Choose a reason for hiding this comment

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

Putting stuff that does not come from the chain registry into fetched-chain-info doesn't seem right to me.

Whatever consumes fetched-chain-info should mix in PFM_ENABLED, IMO.

@0xpatrickdev 0xpatrickdev force-pushed the 10006-transfer-pfm branch 3 times, most recently from 2c1661d to b746eee Compare November 26, 2024 00:18
@0xpatrickdev 0xpatrickdev dismissed turadg’s stale review November 26, 2024 00:25

more changes included

Copy link
Member

@turadg turadg left a comment

Choose a reason for hiding this comment

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

Thanks for the clean commits. LGTM.

@0xpatrickdev 0xpatrickdev force-pushed the 10006-transfer-pfm branch 6 times, most recently from 737a964 to d6db026 Compare November 26, 2024 02:58
0xpatrickdev and others added 11 commits November 26, 2024 02:07
- in order to determine whether its possible to route a transfer through a particular ibc chain, we must know if they have the PFM module installed
- adds `IcqEnabled` and `PfmEnabled` constants to support `CosmosChainInfo`
- this data is not available via a well-known registry like cosmos/chain-registry,
  but necessary for the Orchestration API
- exports `withChainCapabilities` helper so consumers can include this data with fetched-chain-info.js
- use `ts-blank-space` since `tsx` is no longer in `node_modules/.bin`
- prefer yarn command instead of standalone script
- helper function that takes chainInfo and assetInfo and registers the data in ChainHub
- `withOrchestration` the baggage that was provided to it by the original caller
- needed so users of `withOrchestration` can access baggage
- split start-send-anywhere.js into proposal and start script so we can pass options
- init-send-anywhere.js takes `--chainInfo` and `--assetInfo` options
- send-anywhere.contrac.js registers chainInfo and assetInfo from privateArgs in ChainHub
- this test is flaky and will be addressed as part of #10565
@0xpatrickdev 0xpatrickdev added the automerge:rebase Automatically rebase updates, then merge label Nov 26, 2024
@mergify mergify bot merged commit 8657c4c into master Nov 26, 2024
86 of 95 checks passed
@mergify mergify bot deleted the 10006-transfer-pfm branch November 26, 2024 17:06
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.

this is how far I got before a meeting

Comment on lines +48 to +53
[`ibc/${denomHash({ denom: 'uatom', channelId: chainInfo.agoric.connections['gaialocal'].transferChannel.channelId })}`]:
{
baseName: 'cosmoshub',
chainName: 'agoric',
baseDenom: 'uatom',
},
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't connect the relevant brand.


test.before(async t => {
const { deleteTestKeys, setupTestKeys, ...rest } = await commonSetup(t);
deleteTestKeys(accounts).catch();
const wallets = await setupTestKeys(accounts);
t.context = { ...rest, wallets, deleteTestKeys };
const { startContract } = rest;
await startContract(contractName, contractBuilder);

const assetInfo = {
Copy link
Member

Choose a reason for hiding this comment

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

a helper for this comes to mind:

const assetInfo = Object.fromEntries([
  assetOn('uosmo', 'osmosis'),
  assetOn('uosmo', 'osmosis', 'agoric', chainInfo),
  assetOn('uatom', 'cosmoshub'),
  assetOn('uatom', 'cosmoshub', 'agoric', 'chainInfo),
])


await startContract(contractName, contractBuilder, {
chainInfo: JSON.stringify(withChainCapabilities(chainInfo)),
assetInfo: JSON.stringify(assetInfo),
Copy link
Member

Choose a reason for hiding this comment

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

Using LegibleCapData would let us include brands in assetInfo.

/**
* The smallCaps body is a string, which simplifies some usage.
* But it's hard to read and write.
*
* The parsed structure makes a convenient notation for configuration etc.

*/

const { keys } = Object;

const defaultAssetInfo = {
Copy link
Member

Choose a reason for hiding this comment

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

again:

const defaultAssetInfo = Object.fromEntries([
  assetOn('uusdc', 'noble'),
  assetOn('uusdc', 'noble', 'agoric', chainInfo),
  assetOn('uusdc', 'noble', 'osmosis', chainInfo),
]);

baseName: 'noble',
chainName: 'agoric',
baseDenom: 'uusdc',
brandKey: 'USDC',
Copy link
Member

Choose a reason for hiding this comment

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

What consumes brandKey? What's the type of defaultAssetInfo?

brandKey is another example of the sort of thing that LegibleCapData is designed to address.

For background, see

Copy link
Member Author

Choose a reason for hiding this comment

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

This is good feedback. I went with brandKey since I'm not well versed in this area.

I created a ticket to track the removal of brandKey in favor of this approach: #10580

Copy link
Member

Choose a reason for hiding this comment

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

Thanks. I think it's an entirely internal interface, so it's not a big deal.

@@ -33,6 +35,8 @@ const contractName = 'fastUsdc';
* oracles: Record<string, string>;
* feeConfig: FeeConfig;
* feedPolicy: FeedPolicy & Passable;
* chainInfo: Record<string, CosmosChainInfo & Passable>;
* assetInfo: Record<Denom, DenomDetail & {brandKey?: string}>;
Copy link
Member

Choose a reason for hiding this comment

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

FastUSDCConfig shouldn't need brandKey. It's already designed to work with LegibleCapData.

Copy link
Member Author

Choose a reason for hiding this comment

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

assetInfo,
) => {
if (!chainInfo) {
console.log('No chain info provided, returning early.');
Copy link
Member

Choose a reason for hiding this comment

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

How about logging the keys of chainInfo in any case?

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, I see you've tackled this in #10572

Copy link
Member

Choose a reason for hiding this comment

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

Yup

}
}
}

Copy link
Member

Choose a reason for hiding this comment

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

log registeredPairs for connection info?

}

if (!assetInfo) {
console.log('No asset info provided, returning early.');
Copy link
Member

Choose a reason for hiding this comment

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

again, how about logging the keys of assetInfo in any case?
Logging IBC denoms is kinda noisy, but probably not too bad.

* @param {ChainHub} chainHub
* @param {Record<string, Brand<'nat'>>} brands
* @param {Record<string, CosmosChainInfo> | undefined} chainInfo
* @param {Record<Denom, DenomDetail & { brandKey?: string }> | undefined} assetInfo
Copy link
Member

Choose a reason for hiding this comment

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

Using LegibleCapData would avoid the special case for brandKey here.

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 force:integration Force integration tests to run on PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants