From 95507735155e6078414e8c4bfda2f0001d163125 Mon Sep 17 00:00:00 2001 From: 0xPatrick Date: Wed, 19 Jun 2024 12:29:14 -0700 Subject: [PATCH 1/2] feat(facade): propagate vowTools --- packages/orchestration/src/exos/orchestrator.js | 11 +++++++++-- packages/orchestration/src/facade.js | 3 +++ packages/orchestration/src/utils/start-helper.js | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/orchestration/src/exos/orchestrator.js b/packages/orchestration/src/exos/orchestrator.js index 02087425537..e18505b8e9a 100644 --- a/packages/orchestration/src/exos/orchestrator.js +++ b/packages/orchestration/src/exos/orchestrator.js @@ -15,7 +15,7 @@ import { * @import {Zone} from '@agoric/base-zone'; * @import {ChainHub} from './chain-hub.js'; * @import {AsyncFlowTools} from '@agoric/async-flow'; - * @import {Vow} from '@agoric/vow'; + * @import {Vow, VowTools} from '@agoric/vow'; * @import {TimerService} from '@agoric/time'; * @import {LocalChain} from '@agoric/vats/src/localchain.js'; * @import {RecorderKit, MakeRecorderKit} from '@agoric/zoe/src/contractSupport/recorder.js'. @@ -50,12 +50,19 @@ export const OrchestratorI = M.interface('Orchestrator', { * orchestrationService: Remote; * storageNode: Remote; * timerService: Remote; + * vowTools: VowTools; * zcf: ZCF; * }} powers */ export const prepareOrchestrator = ( zone, - { chainHub, localchain, makeLocalChainFacade, makeRemoteChainFacade }, + { + chainHub, + localchain, + makeLocalChainFacade, + makeRemoteChainFacade, + vowTools: _vowTools, + }, ) => zone.exoClass( 'Orchestrator', diff --git a/packages/orchestration/src/facade.js b/packages/orchestration/src/facade.js index b4f6c97d81c..e52d87c85a4 100644 --- a/packages/orchestration/src/facade.js +++ b/packages/orchestration/src/facade.js @@ -34,6 +34,7 @@ import { prepareOrchestrator } from './exos/orchestrator.js'; * makeCosmosOrchestrationAccount: any; * makeLocalChainFacade: MakeLocalChainFacade; * makeRemoteChainFacade: MakeRemoteChainFacade; + * vowTools: VowTools; * asyncFlowTools: AsyncFlowTools; * }} powers */ @@ -49,6 +50,7 @@ export const makeOrchestrationFacade = ({ makeRecorderKit, makeLocalChainFacade, makeRemoteChainFacade, + vowTools, asyncFlowTools, }) => { (zone && @@ -75,6 +77,7 @@ export const makeOrchestrationFacade = ({ orchestrationService, storageNode, timerService, + vowTools, zcf, }); diff --git a/packages/orchestration/src/utils/start-helper.js b/packages/orchestration/src/utils/start-helper.js index c064bca441b..6b7db2acc96 100644 --- a/packages/orchestration/src/utils/start-helper.js +++ b/packages/orchestration/src/utils/start-helper.js @@ -98,6 +98,7 @@ export const provideOrchestration = ( makeLocalChainFacade, makeRemoteChainFacade, asyncFlowTools, + vowTools, ...remotePowers, }); return { ...facade, chainHub, zone }; From 94d0c3caee70fef1e33bc90c445dfc49eae421f4 Mon Sep 17 00:00:00 2001 From: 0xPatrick Date: Wed, 19 Jun 2024 13:19:47 -0700 Subject: [PATCH 2/2] feat(orchestrator): return unwrapped vows - returning unwrapped vows to ensure tests are passing and functionality is preserved --- .../orchestration/src/exos/orchestrator.js | 92 +++++++++++++------ packages/orchestration/src/facade.js | 7 +- packages/orchestration/src/utils/time.js | 6 +- 3 files changed, 75 insertions(+), 30 deletions(-) diff --git a/packages/orchestration/src/exos/orchestrator.js b/packages/orchestration/src/exos/orchestrator.js index e18505b8e9a..d6982f8bd39 100644 --- a/packages/orchestration/src/exos/orchestrator.js +++ b/packages/orchestration/src/exos/orchestrator.js @@ -1,7 +1,7 @@ /** @file ChainAccount exo */ import { AmountShape } from '@agoric/ertp'; import { makeTracer } from '@agoric/internal'; -import { V } from '@agoric/vow/vat.js'; +import { E } from '@endo/far'; import { M } from '@endo/patterns'; import { ChainInfoShape, @@ -10,6 +10,7 @@ import { BrandInfoShape, DenomAmountShape, } from '../typeGuards.js'; +import { getChainsAndConnection } from './chain-hub.js'; /** * @import {Zone} from '@agoric/base-zone'; @@ -20,6 +21,7 @@ import { * @import {LocalChain} from '@agoric/vats/src/localchain.js'; * @import {RecorderKit, MakeRecorderKit} from '@agoric/zoe/src/contractSupport/recorder.js'. * @import {Remote} from '@agoric/internal'; + * @import {PickFacet} from '@agoric/swingset-liveslots'; * @import {OrchestrationService} from '../service.js'; * @import {MakeLocalOrchestrationAccountKit} from './local-orchestration-account.js'; * @import {MakeLocalChainFacade} from './local-chain-facade.js'; @@ -54,47 +56,85 @@ export const OrchestratorI = M.interface('Orchestrator', { * zcf: ZCF; * }} powers */ -export const prepareOrchestrator = ( +export const prepareOrchestratorKit = ( zone, { chainHub, localchain, makeLocalChainFacade, makeRemoteChainFacade, - vowTools: _vowTools, + vowTools: { watch, when }, }, ) => - zone.exoClass( + zone.exoClassKit( 'Orchestrator', - OrchestratorI, + { + orchestrator: OrchestratorI, + makeLocalChainFacadeWatcher: M.interface('makeLocalChainFacadeWatcher', { + onFulfilled: M.call(M.record()) + .optional(M.arrayOf(M.undefined())) + .returns(M.any()), // FIXME narrow + }), + makeRemoteChainFacadeWatcher: M.interface( + 'makeRemoteChainFacadeWatcher', + { + onFulfilled: M.call(M.arrayOf(M.record())) + .optional(M.arrayOf(M.undefined())) + .returns(M.any()), // FIXME narrow + }, + ), + }, () => { trace('making an Orchestrator'); return {}; }, { - /** @type {Orchestrator['getChain']} */ - getChain: async name => { - const agoricChainInfo = await chainHub.getChainInfo('agoric'); - - if (name === 'agoric') { - // @ts-expect-error XXX chainInfo generic + /** Waits for `chainInfo` and returns a LocalChainFacade */ + makeLocalChainFacadeWatcher: { + /** @param {ChainInfo} agoricChainInfo */ + onFulfilled(agoricChainInfo) { return makeLocalChainFacade(agoricChainInfo); - } - - const remoteChainInfo = await chainHub.getChainInfo(name); - const connectionInfo = await chainHub.getConnectionInfo( - agoricChainInfo.chainId, - remoteChainInfo.chainId, - ); - - // @ts-expect-error XXX chainInfo generic - return makeRemoteChainFacade(remoteChainInfo, connectionInfo); + }, + }, + /** + * Waits for `chainInfo` for `agoric` and a remote chain and returns a + * RemoteChainFacade + */ + makeRemoteChainFacadeWatcher: { + /** + * Waits for `chainInfo` for `agoric` and a remote chain and returns a + * RemoteChainFacade + * + * @param {[ChainInfo, ChainInfo, IBCConnectionInfo]} chainsAndConnection + */ + onFulfilled([_agoricChainInfo, remoteChainInfo, connectionInfo]) { + return makeRemoteChainFacade(remoteChainInfo, connectionInfo); + }, }, - makeLocalAccount() { - return V(localchain).makeAccount(); + orchestrator: { + /** @type {Orchestrator['getChain']} */ + getChain(name) { + if (name === 'agoric') { + return when( + watch( + chainHub.getChainInfo('agoric'), + this.facets.makeLocalChainFacadeWatcher, + ), + ); + } + return when( + watch( + getChainsAndConnection(chainHub, 'agoric', name), + this.facets.makeRemoteChainFacadeWatcher, + ), + ); + }, + makeLocalAccount() { + return when(watch(E(localchain).makeAccount())); + }, + getBrandInfo: () => Fail`not yet implemented`, + asAmount: () => Fail`not yet implemented`, }, - getBrandInfo: () => Fail`not yet implemented`, - asAmount: () => Fail`not yet implemented`, }, ); -harden(prepareOrchestrator); +harden(prepareOrchestratorKit); diff --git a/packages/orchestration/src/facade.js b/packages/orchestration/src/facade.js index e52d87c85a4..35de5e2b4bb 100644 --- a/packages/orchestration/src/facade.js +++ b/packages/orchestration/src/facade.js @@ -1,8 +1,8 @@ /** @file Orchestration service */ import { Fail } from '@agoric/assert'; - -import { prepareOrchestrator } from './exos/orchestrator.js'; +import { pickFacet } from '@agoric/vat-data'; +import { prepareOrchestratorKit } from './exos/orchestrator.js'; /** * @import {AsyncFlowTools} from '@agoric/async-flow'; @@ -67,7 +67,7 @@ export const makeOrchestrationFacade = ({ asyncFlowTools) || Fail`params missing`; - const makeOrchestrator = prepareOrchestrator(zone, { + const makeOrchestratorKit = prepareOrchestratorKit(zone, { asyncFlowTools, chainHub, localchain, @@ -80,6 +80,7 @@ export const makeOrchestrationFacade = ({ vowTools, zcf, }); + const makeOrchestrator = pickFacet(makeOrchestratorKit, 'orchestrator'); return { /** diff --git a/packages/orchestration/src/utils/time.js b/packages/orchestration/src/utils/time.js index a7e63504a12..8e8dc062f6e 100644 --- a/packages/orchestration/src/utils/time.js +++ b/packages/orchestration/src/utils/time.js @@ -9,7 +9,11 @@ import { TimeMath } from '@agoric/time'; export const SECONDS_PER_MINUTE = 60n; export const NANOSECONDS_PER_SECOND = 1_000_000_000n; -/** @param {Remote} timer */ +/** + * XXX should this be durable? resumable? + * + * @param {Remote} timer + */ export function makeTimestampHelper(timer) { /** @type {TimerBrand | undefined} */ let brandCache;