-
Notifications
You must be signed in to change notification settings - Fork 212
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
9281 durable orchestrator #9532
Changes from all commits
984fc9a
bcb1e89
29649ad
783f520
5ce13fd
1ca9a00
772039c
0636745
bec2253
62bdb8a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,67 @@ | ||||||
/** @file ChainAccount exo */ | ||||||
import { V } from '@agoric/vow/vat.js'; | ||||||
|
||||||
import { ChainFacadeI } from '../typeGuards.js'; | ||||||
|
||||||
/** | ||||||
* @import {Zone} from '@agoric/base-zone'; | ||||||
* @import {TimerService} from '@agoric/time'; | ||||||
* @import {Remote} from '@agoric/internal'; | ||||||
* @import {LocalChain} from '@agoric/vats/src/localchain.js'; | ||||||
* @import {OrchestrationService} from '../service.js'; | ||||||
* @import {MakeLocalOrchestrationAccountKit} from './local-orchestration-account.js'; | ||||||
* @import {ChainInfo, CosmosChainInfo, IBCConnectionInfo, OrchestrationAccount} from '../types.js'; | ||||||
*/ | ||||||
|
||||||
/** | ||||||
* @param {Zone} zone | ||||||
* @param {{ | ||||||
* makeLocalOrchestrationAccountKit: MakeLocalOrchestrationAccountKit; | ||||||
* orchestration: Remote<OrchestrationService>; | ||||||
* storageNode: Remote<StorageNode>; | ||||||
* timer: Remote<TimerService>; | ||||||
* localchain: Remote<LocalChain>; | ||||||
* }} powers | ||||||
*/ | ||||||
export const prepareLocalChainFacade = ( | ||||||
zone, | ||||||
{ makeLocalOrchestrationAccountKit, localchain, storageNode }, | ||||||
) => | ||||||
zone.exoClass( | ||||||
'LocalChainFacade', | ||||||
ChainFacadeI, | ||||||
/** | ||||||
* @param {CosmosChainInfo} localChainInfo | ||||||
*/ | ||||||
localChainInfo => { | ||||||
return { localChainInfo }; | ||||||
}, | ||||||
{ | ||||||
async getChainInfo() { | ||||||
return this.state.localChainInfo; | ||||||
}, | ||||||
|
||||||
// FIXME parameterize on the remoteChainInfo to make() | ||||||
// That used to work but got lost in the migration to Exo | ||||||
/** @returns {Promise<OrchestrationAccount<ChainInfo>>} */ | ||||||
async makeAccount() { | ||||||
const { localChainInfo } = this.state; | ||||||
const lcaP = V(localchain).makeAccount(); | ||||||
const [lca, address] = await Promise.all([lcaP, V(lcaP).getAddress()]); | ||||||
const { holder: account } = makeLocalOrchestrationAccountKit({ | ||||||
account: lca, | ||||||
address: harden({ | ||||||
address, | ||||||
chainId: localChainInfo.chainId, | ||||||
addressEncoding: 'bech32', | ||||||
}), | ||||||
// FIXME storage path | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What ticket capture this? Maybe vstorage logging ?
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for looking these up. I expect we'll get to them soon so I'll let this merge as is to save the CI time. Maybe include the links on a next PR. |
||||||
storageNode, | ||||||
}); | ||||||
|
||||||
return account; | ||||||
}, | ||||||
}, | ||||||
); | ||||||
harden(prepareLocalChainFacade); | ||||||
/** @typedef {ReturnType<typeof prepareLocalChainFacade>} MakeLocalChainFacade */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,27 @@ | ||
/** @file Use-object for the owner of a localchain account */ | ||
import { NonNullish } from '@agoric/assert'; | ||
import { typedJson } from '@agoric/cosmic-proto/vatsafe'; | ||
import { AmountShape, PaymentShape } from '@agoric/ertp'; | ||
import { makeTracer } from '@agoric/internal'; | ||
import { M } from '@agoric/vat-data'; | ||
import { V } from '@agoric/vow/vat.js'; | ||
import { TopicsRecordShape } from '@agoric/zoe/src/contractSupport/index.js'; | ||
import { InvitationShape } from '@agoric/zoe/src/typeGuards.js'; | ||
import { V } from '@agoric/vow/vat.js'; | ||
import { E } from '@endo/far'; | ||
import { | ||
AmountArgShape, | ||
ChainAddressShape, | ||
IBCTransferOptionsShape, | ||
} from '../typeGuards.js'; | ||
import { maxClockSkew } from '../utils/cosmos.js'; | ||
import { orchestrationAccountMethods } from '../utils/orchestrationAccount.js'; | ||
import { dateInSeconds, makeTimestampHelper } from '../utils/time.js'; | ||
|
||
/** | ||
* @import {LocalChainAccount} from '@agoric/vats/src/localchain.js'; | ||
* @import {AmountArg, ChainAddress, DenomAmount, IBCMsgTransferOptions, CosmosChainInfo} from '@agoric/orchestration'; | ||
* @import {AmountArg, ChainAddress, DenomAmount, IBCMsgTransferOptions, OrchestrationAccount, OrchestrationAccountI} from '@agoric/orchestration'; | ||
* @import {RecorderKit, MakeRecorderKit} from '@agoric/zoe/src/contractSupport/recorder.js'. | ||
* @import {Zone} from '@agoric/zone'; | ||
* @import {Remote} from '@agoric/internal'; | ||
* @import {TimerService, TimerBrand} from '@agoric/time'; | ||
* @import {ChainHub} from '../utils/chainHub.js'; | ||
*/ | ||
|
||
const trace = makeTracer('LCAH'); | ||
const trace = makeTracer('LOA'); | ||
|
||
const { Fail } = assert; | ||
/** | ||
|
@@ -38,20 +33,16 @@ const { Fail } = assert; | |
* @typedef {{ | ||
* topicKit: RecorderKit<LocalChainAccountNotification>; | ||
* account: LocalChainAccount; | ||
* address: ChainAddress['address']; | ||
* address: ChainAddress; | ||
* }} State | ||
*/ | ||
|
||
const HolderI = M.interface('holder', { | ||
...orchestrationAccountMethods, | ||
getPublicTopics: M.call().returns(TopicsRecordShape), | ||
delegate: M.call(M.string(), AmountShape).returns(M.promise()), | ||
undelegate: M.call(M.string(), AmountShape).returns(M.promise()), | ||
deposit: M.callWhen(PaymentShape).optional(AmountShape).returns(AmountShape), | ||
withdraw: M.callWhen(AmountShape).returns(PaymentShape), | ||
transfer: M.call(AmountArgShape, ChainAddressShape) | ||
.optional(IBCTransferOptionsShape) | ||
.returns(M.promise()), | ||
getAddress: M.call().returns(M.string()), | ||
executeTx: M.callWhen(M.arrayOf(M.record())).returns(M.arrayOf(M.record())), | ||
}); | ||
|
||
|
@@ -67,18 +58,18 @@ const PUBLIC_TOPICS = { | |
* @param {Remote<TimerService>} timerService | ||
* @param {ChainHub} chainHub | ||
*/ | ||
export const prepareLocalChainAccountKit = ( | ||
export const prepareLocalOrchestrationAccountKit = ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice rename 👏 |
||
zone, | ||
makeRecorderKit, | ||
zcf, | ||
timerService, | ||
chainHub, | ||
) => { | ||
const timestampHelper = makeTimestampHelper(timerService); | ||
// TODO: rename to makeLocalOrchestrationAccount or the like to distinguish from lca | ||
|
||
/** Make an object wrapping an LCA with Zoe interfaces. */ | ||
const makeLocalChainAccountKit = zone.exoClassKit( | ||
'LCA Kit', | ||
const makeLocalOrchestrationAccountKit = zone.exoClassKit( | ||
'Local Orchestration Account Kit', | ||
{ | ||
holder: HolderI, | ||
invitationMakers: M.interface('invitationMakers', { | ||
|
@@ -92,16 +83,15 @@ export const prepareLocalChainAccountKit = ( | |
/** | ||
* @param {object} initState | ||
* @param {LocalChainAccount} initState.account | ||
* @param {ChainAddress['address']} initState.address | ||
* @param {StorageNode} initState.storageNode | ||
* @param {ChainAddress} initState.address | ||
* @param {Remote<StorageNode>} initState.storageNode | ||
* @returns {State} | ||
*/ | ||
({ account, address, storageNode }) => { | ||
// must be the fully synchronous maker because the kit is held in durable state | ||
// @ts-expect-error XXX Patterns | ||
const topicKit = makeRecorderKit(storageNode, PUBLIC_TOPICS.account[1]); | ||
|
||
// #9162 use ChainAddress object instead of `address` string | ||
return { account, address, topicKit }; | ||
}, | ||
{ | ||
|
@@ -138,6 +128,24 @@ export const prepareLocalChainAccountKit = ( | |
}, | ||
}, | ||
holder: { | ||
/** @type {OrchestrationAccount<any>['getBalance']} */ | ||
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 V.when( | ||
E(this.state.account).getBalance(brand), | ||
); | ||
return harden({ denom, value: natAmount.value }); | ||
}, | ||
getBalances() { | ||
throw new Error('not yet implemented'); | ||
}, | ||
|
||
getPublicTopics() { | ||
const { topicKit } = this.state; | ||
return harden({ | ||
|
@@ -207,9 +215,9 @@ export const prepareLocalChainAccountKit = ( | |
* updater will get a special notification that the account is being | ||
* transferred. | ||
*/ | ||
/** @type {LocalChainAccount['deposit']} */ | ||
async deposit(payment, optAmountShape) { | ||
return V(this.state.account).deposit(payment, optAmountShape); | ||
/** @type {OrchestrationAccount<any>['deposit']} */ | ||
async deposit(payment) { | ||
await V(this.state.account).deposit(payment); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In a future PR we might consider updating Tangentially - with the revised implementation plan for #9193 only |
||
}, | ||
/** @type {LocalChainAccount['withdraw']} */ | ||
async withdraw(amount) { | ||
|
@@ -220,9 +228,13 @@ export const prepareLocalChainAccountKit = ( | |
// @ts-expect-error subtype | ||
return V(this.state.account).executeTx(messages); | ||
}, | ||
/** @returns {ChainAddress['address']} */ | ||
/** @returns {ChainAddress} */ | ||
getAddress() { | ||
return NonNullish(this.state.address, 'Chain address not available.'); | ||
return this.state.address; | ||
}, | ||
async send(toAccount, amount) { | ||
// FIXME implement | ||
console.log('send got', toAccount, amount); | ||
}, | ||
/** | ||
* @param {AmountArg} amount an ERTP {@link Amount} or a | ||
|
@@ -261,7 +273,7 @@ export const prepareLocalChainAccountKit = ( | |
amount: String(amount.value), | ||
denom: amount.denom, | ||
}, | ||
sender: this.state.address, | ||
sender: this.state.address.address, | ||
receiver: destination.address, | ||
timeoutHeight: opts?.timeoutHeight ?? { | ||
revisionHeight: 0n, | ||
|
@@ -273,10 +285,15 @@ export const prepareLocalChainAccountKit = ( | |
]); | ||
trace('MsgTransfer result', result); | ||
}, | ||
/** @type {OrchestrationAccount<any>['transferSteps']} */ | ||
transferSteps(amount, msg) { | ||
console.log('transferSteps got', amount, msg); | ||
return Promise.resolve(); | ||
}, | ||
}, | ||
}, | ||
); | ||
return makeLocalChainAccountKit; | ||
return makeLocalOrchestrationAccountKit; | ||
}; | ||
/** @typedef {ReturnType<typeof prepareLocalChainAccountKit>} MakeLocalChainAccountKit */ | ||
/** @typedef {ReturnType<MakeLocalChainAccountKit>} LocalChainAccountKit */ | ||
/** @typedef {ReturnType<typeof prepareLocalOrchestrationAccountKit>} MakeLocalOrchestrationAccountKit */ | ||
/** @typedef {ReturnType<MakeLocalOrchestrationAccountKit>} LocalOrchestrationAccountKit */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.