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

register any chain info #9452

Merged
merged 8 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions packages/orchestration/src/chain-info.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// UNTIL https://github.com/Agoric/agoric-sdk/issues/8879

/** @file temporary static lookup of chain info */

/** @import {CosmosChainInfo, EthChainInfo} from './types.js'; */

/** @typedef {CosmosChainInfo | EthChainInfo} ChainInfo */

// TODO generate this automatically with a build script drawing on data sources such as https://github.com/cosmos/chain-registry

export const wellKnownChainInfo =
/** @satisfies {Record<string, ChainInfo>} */ (
harden({
// https://github.com/cosmos/chain-registry/blob/master/stride/chain.json
stride: {
chainId: 'stride-1',
connections: {},
icaEnabled: true,
icqEnabled: true,
pfmEnabled: true,
ibcHooksEnabled: true,
allowedMessages: [],
allowedQueries: [],
stakingTokens: [{ denom: 'ustride' }],
},
cosmos: {
chainId: 'cosmoshub-4',
connections: {},
icaEnabled: true,
icqEnabled: true,
pfmEnabled: true,
ibcHooksEnabled: true,
allowedMessages: [],
allowedQueries: [],
Comment on lines +33 to +34
Copy link
Member

Choose a reason for hiding this comment

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

Are you planning to use these for generating Orchestration Account facets? Regardless, looking forward to seeing the approach for that in the next iteration.

stakingTokens: [{ denom: 'uatom' }],
},
celestia: {
chainId: 'celestia',
connections: {},
icaEnabled: true,
icqEnabled: true,
pfmEnabled: true,
ibcHooksEnabled: true,
allowedMessages: [],
allowedQueries: [],
stakingTokens: [{ denom: 'utia' }],
},
osmosis: {
chainId: 'osmosis-1',
connections: {},
icaEnabled: true,
icqEnabled: true,
pfmEnabled: true,
ibcHooksEnabled: true,
allowedMessages: [],
allowedQueries: [],
stakingTokens: [{ denom: 'uosmo' }],
},
})
);
64 changes: 0 additions & 64 deletions packages/orchestration/src/chain-info.ts

This file was deleted.

17 changes: 17 additions & 0 deletions packages/orchestration/src/cosmos-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ export type CosmosChainInfo = {
*/
allowedMessages: TypeUrl[];
allowedQueries: TypeUrl[];

/**
* cf https://github.com/cosmos/chain-registry/blob/master/chain.schema.json#L117
*/
stakingTokens?: Array<{ denom: string }>;
};

export interface StakingAccountQueries {
Expand Down Expand Up @@ -219,3 +224,15 @@ export type IBCMsgTransferOptions = {
timeoutTimestamp?: MsgTransfer['timeoutTimestamp'];
memo?: string;
};

export type CosmosChainAccountMethods<CCI extends CosmosChainInfo> =
(CCI extends {
icaEnabled: true;
}
? IcaAccount
: {}) &
CCI extends {
stakingTokens: {};
Copy link
Member

Choose a reason for hiding this comment

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

does it matter that stakingTokens is an Array? should this be...

Suggested change
stakingTokens: {};
stakingTokens: [];

Copy link
Member

Choose a reason for hiding this comment

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

Is an array accurate? I know this is how chain-registry has it modeled, but I am skeptical. The bond_denom field in x/staking params seems to indicate just a single entry: https://buf.build/cosmos/cosmos-sdk/docs/main:cosmos.staking.v1beta1#cosmos.staking.v1beta1.Params

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, it is curious. https://github.com/search?q=repo%3Acosmology-tech%2Fchain-registry+stakingTokens shows only examples of a single element in the array.

I consider this out of scope that will be resolved in already scheduled issues.

}
? StakingAccountActions
: {};
108 changes: 72 additions & 36 deletions packages/orchestration/src/facade.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
/** @file Orchestration service */

import { makeScalarBigMapStore } from '@agoric/vat-data';
import { E } from '@endo/far';
import { M } from '@endo/patterns';
import { wellKnownChainInfo } from './chain-info.js';
import { prepareCosmosOrchestrationAccount } from './exos/cosmosOrchestrationAccount.js';
import { CosmosChainInfoShape } from './typeGuards.js';

/**
* @import {Zone} from '@agoric/zone';
* @import {TimerService} from '@agoric/time';
* @import {LocalChain} from '@agoric/vats/src/localchain.js';
* @import {Remote} from '@agoric/internal';
* @import {OrchestrationService} from './service.js';
* @import {Chain, ChainInfo, CosmosChainInfo, KnownChains, OrchestrationAccount, Orchestrator} from './types.js';
* @import {Chain, ChainInfo, CosmosChainInfo, OrchestrationAccount, Orchestrator} from './types.js';
*/

/** @type {any} */
const anyVal = null;

// FIXME should be configurable
// FIXME look up real values
// UNTIL https://github.com/Agoric/agoric-sdk/issues/9063
const mockLocalChainInfo = {
Copy link
Member

Choose a reason for hiding this comment

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

mockX looks like test code, not src code.

Copy link
Member Author

Choose a reason for hiding this comment

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

it's not test code either; it's an incomplete implementation. just like all the "'fixme'" strings we've had to date

Copy link
Member Author

@turadg turadg Jun 5, 2024

Choose a reason for hiding this comment

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

I've put issues at all the fixmes to be sure they'll be addressed

allegedName: 'agoric',
allowedMessages: [],
Expand All @@ -39,36 +44,41 @@ const makeLocalChainFacade = localchain => {
return mockLocalChainInfo;
},

// @ts-expect-error FIXME promise resolution through membrane
async makeAccount() {
const account = await E(localchain).makeAccount();

return {
deposit(payment) {
async deposit(payment) {
Comment on lines -47 to +51
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: In asyncFlow discussion yesterday, somebody said the facade methods can't be async.

console.log('deposit got', payment);
return E(account).deposit(payment);
await E(account).deposit(payment);
},
async getAddress() {
const addressStr = await E(account).getAddress();
getAddress() {
const addressStr = account.getAddress();
return {
address: addressStr,
chainId: mockLocalChainInfo.chainId,
addressEncoding: 'bech32',
};
},
getBalance(_denom) {
// FIXME map denom to Brand
const brand = /** @type {any} */ (null);
return E(account).getBalance(brand);
async getBalance(denomArg) {
// FIXME look up real values
// UNTIL https://github.com/Agoric/agoric-sdk/issues/9211
const [brand, denom] =
typeof denomArg === 'string'
? [/** @type {any} */ (null), denomArg]
: [denomArg, 'FIXME'];

const natAmount = await account.getBalance(brand);
return harden({ denom, value: natAmount.value });
},
getBalances() {
throw new Error('not yet implemented');
},
send(toAccount, amount) {
async send(toAccount, amount) {
// FIXME implement
console.log('send got', toAccount, amount);
},
transfer(amount, destination, opts) {
async transfer(amount, destination, opts) {
// FIXME implement
console.log('transfer got', amount, destination, opts);
},
Expand All @@ -82,27 +92,21 @@ const makeLocalChainFacade = localchain => {
};

/**
* @template {string} C
* @param {C} name
* @template {CosmosChainInfo} CCI
* @param {CCI} chainInfo
Comment on lines +95 to +96
Copy link
Member

Choose a reason for hiding this comment

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

funky.

Copy link
Member Author

Choose a reason for hiding this comment

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

request?

Copy link
Member

Choose a reason for hiding this comment

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

sorry; no... it just hand't occurred to me that a type could be parameterized by a whole structure, and not just a primitive value

* @param {object} io
* @param {Remote<OrchestrationService>} io.orchestration
* @param {Remote<TimerService>} io.timer
* @param {ZCF} io.zcf
* @param {Zone} io.zone
* @returns {Chain<C>}
* @returns {Chain<CCI>}
*/
const makeRemoteChainFacade = (name, { orchestration, timer, zcf, zone }) => {
const chainInfo = /** @type {CosmosChainInfo} */ ({
allegedName: name,
chainId: 'fixme',
connections: {},
icaEnabled: true,
icqEnabled: true,
pfmEnabled: true,
ibcHooksEnabled: true,
allowedMessages: [],
allowedQueries: [],
});
const makeRemoteChainFacade = (
chainInfo,
{ orchestration, timer, zcf, zone },
) => {
const name = chainInfo.chainId;

const makeRecorderKit = () => anyVal;
const makeCosmosOrchestrationAccount = prepareCosmosOrchestrationAccount(
zone.subZone(name),
Expand All @@ -112,11 +116,10 @@ const makeRemoteChainFacade = (name, { orchestration, timer, zcf, zone }) => {

return {
getChainInfo: async () => chainInfo,
/** @returns {Promise<OrchestrationAccount<C>>} */
/** @returns {Promise<OrchestrationAccount<CCI>>} */
makeAccount: async () => {
console.log('makeAccount for', name);

// FIXME look up real values
// UNTIL https://github.com/Agoric/agoric-sdk/issues/9063
const hostConnectionId = 'connection-1';
const controllerConnectionId = 'connection-2';

Expand All @@ -127,8 +130,13 @@ const makeRemoteChainFacade = (name, { orchestration, timer, zcf, zone }) => {

const address = await E(icaAccount).getAddress();

// FIXME look up real values
const bondDenom = name;
const [{ denom: bondDenom }] = chainInfo.stakingTokens || [
{
denom: null,
},
];
assert(bondDenom, 'missing bondDenom');
Comment on lines +133 to +138
Copy link
Member

Choose a reason for hiding this comment

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

Mentioned here - but i don't expect we'll see an array of staking staking tokens for anyone using cosmos.staking.v1beta1

// @ts-expect-error XXX dynamic method availability
return makeCosmosOrchestrationAccount(address, bondDenom, {
account: icaAccount,
storageNode: anyVal,
Expand Down Expand Up @@ -165,12 +173,33 @@ export const makeOrchestrationFacade = ({
orchestrationService,
});

const chainInfos = makeScalarBigMapStore('chainInfos', {
keyShape: M.string(),
valueShape: CosmosChainInfoShape,
});

return {
/**
* Register a new chain in a heap store. The name will override a name in
* well known chain names.
*
* This registration will not surve a reincarnation of the vat so if the
* chain is not yet in the well known names at that point, it will have to
* be registered again. In an unchanged contract `start` the call will
* happen again naturally.
*
* @param {string} name
* @param {ChainInfo} chainInfo
*/
registerChain(name, chainInfo) {
chainInfos.init(name, chainInfo);
},
/**
* @template Context
* @template {any[]} Args
* @param {string} durableName
* @param {Context} ctx
* @param {string} durableName - the orchestration flow identity in the zone
* (to resume across upgrades)
* @param {Context} ctx - values to pass through the async flow membrane
* @param {(orc: Orchestrator, ctx2: Context, ...args: Args) => object} fn
* @returns {(...args: Args) => Promise<unknown>}
*/
Expand All @@ -182,7 +211,14 @@ export const makeOrchestrationFacade = ({
return makeLocalChainFacade(localchain);
}

return makeRemoteChainFacade(name, {
// TODO look up well known realistically https://github.com/Agoric/agoric-sdk/issues/9063
const chainInfo = chainInfos.has(name)
? chainInfos.get(name)
: // @ts-expect-error may be undefined
wellKnownChainInfo[name];
Copy link
Member

Choose a reason for hiding this comment

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

well known chain should come from agoricNames, yes?

Copy link
Member Author

Choose a reason for hiding this comment

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

eventually, yes. that's #9063. I'll add a TODO

assert(chainInfo, `unknown chain ${name}`);

return makeRemoteChainFacade(chainInfo, {
orchestration: orchestrationService,
timer: timerService,
zcf,
Expand Down
Loading
Loading