Skip to content

Commit

Permalink
fix: many typing improvements (#9516)
Browse files Browse the repository at this point in the history
refs: #9441

## Description

Finish adopting `WellKnownVats` in `VatLoader` as proposed by @turadg in #9441

Accommodate `Guarded` types in:
- packages/vats: `Producer<T>.resolve`
- packages/governance

packages/swingset-liveslots: `KindFacet` implies `RemotableBrand`

Cast the return type of `BridgeHandler.register` because it wasn't an `async` function, and there's no way I know using TypeScript to be able to transform the return type of a generic function to `Promise<ReturnType<T>>` without losing `T`'s genericity.
  • Loading branch information
mergify[bot] authored Jun 24, 2024
2 parents 309c7e1 + 777eb21 commit d941b39
Show file tree
Hide file tree
Showing 22 changed files with 130 additions and 105 deletions.
2 changes: 1 addition & 1 deletion packages/governance/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ export {};
* Akin to StartedInstanceKit but designed for the results of starting governed contracts. Used in bootstrap space.
* @property {AdminFacet} adminFacet of the governed contract
* @property {LimitedCF<SF>} creatorFacet creator-like facet within the governed contract (without the powers the governor needs)
* @property {Guarded<GovernorCreatorFacet<SF>>} governorCreatorFacet of the governing contract
* @property {Guarded<GovernorCreatorFacet<SF>> | GovernorCreatorFacet<SF>} governorCreatorFacet of the governing contract
* @property {AdminFacet} governorAdminFacet of the governing contract
* @property {Awaited<ReturnType<SF>>['publicFacet']} publicFacet
* @property {Instance} instance
Expand Down
1 change: 0 additions & 1 deletion packages/inter-protocol/src/proposals/add-auction.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ export const addAuction = async ({
);

newAuctioneerKit.resolve(
// @ts-expect-error XXX governance types
harden({
label: 'auctioneer',
creatorFacet: governedCreatorFacet,
Expand Down
3 changes: 0 additions & 3 deletions packages/inter-protocol/src/proposals/econ-behaviors.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ export const setupReserve = async ({
]);

reserveKit.resolve(
// @ts-expect-error XXX
harden({
label: 'AssetReserve',
instance,
Expand Down Expand Up @@ -349,7 +348,6 @@ export const startVaultFactory = async (
);

vaultFactoryKit.resolve(
// @ts-expect-error XXX
harden({
label: 'VaultFactory',
creatorFacet: vaultFactoryCreator,
Expand Down Expand Up @@ -624,7 +622,6 @@ export const startAuctioneer = async (
]);

auctioneerKit.resolve(
// @ts-expect-error XXX
harden({
label: 'auctioneer',
creatorFacet: governedCreatorFacet,
Expand Down
4 changes: 2 additions & 2 deletions packages/inter-protocol/test/smartWallet/contexts.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { makeHeapZone } from '@agoric/zone';
import { E } from '@endo/far';
import path from 'path';
import { makeScopedBridge } from '@agoric/vats';
import { oracleBrandFeedName } from '../../src/proposals/utils.js';
import { createPriceFeed } from '../../src/proposals/price-feed-proposal.js';
import { withAmountUtils } from '../supports.js';
Expand Down Expand Up @@ -108,9 +109,8 @@ export const makeDefaultTestContext = async (t, makeSpace) => {
* @type {undefined
* | import('@agoric/vats').ScopedBridgeManager<'wallet'>}
*/
// @ts-expect-error XXX EProxy
const walletBridgeManager = await (bridgeManager &&
E(bridgeManager).register(BridgeId.WALLET));
makeScopedBridge(bridgeManager, BridgeId.WALLET));
const walletFactory = await E(zoe).startInstance(
installation,
{},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ export const buildRootObject = async () => {
* @param {any} devices
*/
bootstrap: async (vats, devices) => {
// @ts-expect-error XXX adminNode
vatAdmin = await E(vats.vatAdmin).createVatAdminService(devices.vatAdmin);
({ feeMintAccess, zoeService } = await E(vats.zoe).buildZoe(
vatAdmin,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const trace = makeTracer('CoreEvalOrchestration', true);
/**
* @param {BootstrapPowers & {
* consume: {
* loadCriticalVat: VatLoader<any>;
* portAllocator: PortAllocator;
* };
* produce: {
Expand All @@ -26,10 +25,6 @@ const trace = makeTracer('CoreEvalOrchestration', true);
* };
* }} powers
* @param {{ options: { orchestrationRef: VatSourceRef } }} options
*
* @typedef {{
* orchestration: ERef<OrchestrationVat>;
* }} OrchestrationVats
*/
export const setupOrchestrationVat = async (
{
Expand All @@ -43,7 +38,6 @@ export const setupOrchestrationVat = async (
options,
) => {
const { orchestrationRef } = options.options;
/** @type {OrchestrationVats} */
const vats = {
orchestration: E(loadCriticalVat)('orchestration', orchestrationRef),
};
Expand Down
5 changes: 2 additions & 3 deletions packages/smart-wallet/test/contexts.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { unsafeMakeBundleCache } from '@agoric/swingset-vat/tools/bundleTool.js'
import { makeStorageNodeChild } from '@agoric/internal/src/lib-chainStorage.js';
import { E } from '@endo/far';
import path from 'path';
import { makeScopedBridge } from '@agoric/vats';
import { withAmountUtils } from './supports.js';

/**
Expand Down Expand Up @@ -38,10 +39,8 @@ export const makeDefaultTestContext = async (t, makeSpace) => {
'anyAddress',
);
const bridgeManager = await consume.bridgeManager;
/** @type {import('@agoric/vats').ScopedBridgeManager<'wallet'>} */
// @ts-expect-error XXX generics through EProxy
const walletBridgeManager = await (bridgeManager &&
E(bridgeManager).register(BridgeId.WALLET));
makeScopedBridge(bridgeManager, BridgeId.WALLET));
const walletFactory = await E(zoe).startInstance(
installation,
{},
Expand Down
14 changes: 8 additions & 6 deletions packages/smart-wallet/test/supports.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ export const makeMockTestSpace = async log => {
const space = /** @type {any} */ (makePromiseSpace(log));
/**
* @type {BootstrapPowers & {
* consume: {
* loadVat: (n: 'mints') => MintsVat;
* loadCriticalVat: (n: 'mints') => MintsVat;
* produce: {
* loadVat: Producer<VatLoader>;
* loadCriticalVat: Producer<VatLoader>;
* };
* }}
*/
Expand All @@ -117,13 +117,15 @@ export const makeMockTestSpace = async log => {
produce.zoe.resolve(zoe);
produce.feeMintAccess.resolve(feeMintAccessP);

const vatLoader = name => {
/** @type {VatLoader<'mints' | 'board'>} */
const vatLoader = async name => {
/** @typedef {Awaited<WellKnownVats[typeof name]>} ReturnedVat */
switch (name) {
case 'mints':
return mintsRoot();
return /** @type {ReturnedVat} */ (mintsRoot());
case 'board': {
const baggage = makeScalarBigMapStore('baggage');
return boardRoot({}, {}, baggage);
return /** @type {ReturnedVat} */ (boardRoot({}, {}, baggage));
}
default:
throw Error('unknown loadVat name');
Expand Down
9 changes: 7 additions & 2 deletions packages/swingset-liveslots/src/vatDataTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type {
} from '@agoric/store';
import type { Amplify, IsInstance, ReceivePower, StateShape } from '@endo/exo';
import type { RemotableObject } from '@endo/pass-style';
import type { RemotableBrand } from '@endo/eventual-send';
import type { InterfaceGuard, Pattern } from '@endo/patterns';
import type { makeWatchedPromiseManager } from './watchedPromises.js';

Expand All @@ -38,9 +39,13 @@ type OmitFirstArg<F> = F extends (x: any, ...args: infer P) => infer R
? (...args: P) => R
: never;

export type KindFacet<O> = RemotableObject & {
// The type of a passable local object with methods.
// An internal helper to avoid having to repeat `O`.
type PrimaryRemotable<O> = O & RemotableObject & RemotableBrand<{}, O>;

export type KindFacet<O> = PrimaryRemotable<{
[K in keyof O]: OmitFirstArg<O[K]>; // omit the 'context' parameter
};
}>;

export type KindFacets<B> = {
[FacetKey in keyof B]: KindFacet<B[FacetKey]>;
Expand Down
21 changes: 21 additions & 0 deletions packages/vats/src/bridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,27 @@ import { E } from '@endo/far';

const { Fail, details: X } = assert;

/**
* Helper to type the registered scoped bridge correctly.
*
* FIXME: This is needed because `register` is not an async function, so
* `E(x).register` needs to reconstruct its return value as a Promise, which
* loses the function's genericity. If `register` was async, we could use its
* type directly, and it would remain generic.
*
* @template {import('@agoric/internal').BridgeIdValue} BridgeId
* @param {ERef<import('./types.js').BridgeManager>} bridgeManager
* @param {BridgeId} bridgeIdValue
* @param {import('@agoric/internal').Remote<
* import('./types.js').BridgeHandler
* >} [handler]
* @returns {Promise<import('./types.js').ScopedBridgeManager<BridgeId>>}
*/
export const makeScopedBridge = (bridgeManager, bridgeIdValue, handler) =>
/** @type {Promise<import('./types.js').ScopedBridgeManager<BridgeId>>} */ (
E(bridgeManager).register(bridgeIdValue, handler)
);

export const BridgeHandlerI = M.interface('BridgeHandler', {
fromBridge: M.call(M.any()).returns(M.promise()),
});
Expand Down
32 changes: 12 additions & 20 deletions packages/vats/src/core/basic-behaviors.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Fail, NonNullish } from '@agoric/assert';
import { makeNameHubKit } from '../nameHub.js';
import { PowerFlags } from '../walletFlags.js';
import { feeIssuerConfig, makeMyAddressNameAdminKit } from './utils.js';
import { makeScopedBridge } from '../bridge.js';

/** @import {GovernableStartFn, GovernanceFacetKit} from '@agoric/governance/src/types.js'; */

Expand Down Expand Up @@ -50,10 +51,14 @@ const bootMsgEx = {
*/

/** @typedef {MapStore<string, CreateVatResults>} VatStore */
/** @typedef {ERef<ReturnType<import('../vat-zoe.js').buildRootObject>>} ZoeVat */

/**
* @param {BootstrapPowers & {}} powers
* @param {BootstrapPowers & {
* produce: {
* loadVat: Producer<VatLoader>;
* loadCriticalVat: Producer<VatLoader>;
* };
* }} powers
* @import {CreateVatResults} from '@agoric/swingset-vat'
* as from createVatByName
*/
Expand All @@ -66,7 +71,6 @@ export const makeVatsFromBundles = async ({
// NOTE: we rely on multiple createVatAdminService calls
// to return cooperating services.
const svc = E(vats.vatAdmin).createVatAdminService(devices.vatAdmin);
// @ts-expect-error XXX
vatAdminSvc.resolve(svc);

const durableStore = await vatStore;
Expand All @@ -81,7 +85,6 @@ export const makeVatsFromBundles = async ({
if (bundleName) {
console.info(`createVatByName(${bundleName})`);
/** @type {Promise<CreateVatResults>} */
// @ts-expect-error XXX
const vatInfo = E(svc).createVatByName(bundleName, {
...defaultVatCreationOptions,
name: vatName,
Expand All @@ -92,7 +95,6 @@ export const makeVatsFromBundles = async ({
assert(bundleID);
const bcap = await E(svc).getBundleCap(bundleID);
/** @type {Promise<CreateVatResults>} */
// @ts-expect-error XXX
const vatInfo = E(svc).createVat(bcap, {
...defaultVatCreationOptions,
name: vatName,
Expand Down Expand Up @@ -329,9 +331,7 @@ export const produceStartGovernedUpgradable = async ({
harden(produceStartGovernedUpgradable);

/**
* @param {BootstrapPowers & {
* consume: { loadCriticalVat: ERef<VatLoader<ZoeVat>> };
* }} powers
* @param {BootstrapPowers} powers
*/
export const buildZoe = async ({
consume: { vatAdminSvc, loadCriticalVat, client },
Expand Down Expand Up @@ -360,9 +360,7 @@ export const buildZoe = async ({
harden(buildZoe);

/**
* @param {BootstrapPowers & {
* consume: { loadCriticalVat: ERef<VatLoader<PriceAuthorityVat>> };
* }} powers
* @param {BootstrapPowers} powers
*/
export const startPriceAuthorityRegistry = async ({
consume: { loadCriticalVat, client },
Expand Down Expand Up @@ -418,9 +416,7 @@ harden(produceBoard);

/**
* @deprecated use produceBoard
* @param {BootstrapPowers & {
* consume: { loadCriticalVat: ERef<VatLoader<BoardVat>> };
* }} powers
* @param {BootstrapPowers} powers
*/
export const makeBoard = async ({
consume: { loadCriticalVat, client },
Expand Down Expand Up @@ -607,9 +603,7 @@ harden(mintInitialSupply);
/**
* Add IST (with initialSupply payment), BLD (with mint) to BankManager.
*
* @param {BootstrapSpace & {
* consume: { loadCriticalVat: ERef<VatLoader<BankVat>> };
* }} powers
* @param {BootstrapSpace} powers
*/
export const addBankAssets = async ({
consume: {
Expand Down Expand Up @@ -656,10 +650,8 @@ export const addBankAssets = async ({
const assetAdmin = E(agoricNamesAdmin).lookupAdmin('vbankAsset');

const bridgeManager = await bridgeManagerP;
/** @type {import('../types.js').ScopedBridgeManager<'bank'> | undefined} */
// @ts-expect-error XXX EProxy
const bankBridgeManager =
bridgeManager && E(bridgeManager).register(BridgeId.BANK);
bridgeManager && makeScopedBridge(bridgeManager, BridgeId.BANK);
const bankMgr = await E(E(loadCriticalVat)('bank')).makeBankManager(
bankBridgeManager,
assetAdmin,
Expand Down
Loading

0 comments on commit d941b39

Please sign in to comment.