Skip to content

Commit

Permalink
refactor: move allValues, zip to internal (#7075)
Browse files Browse the repository at this point in the history
* refactor(internal): split utils between Jessie and extra-Jessie

* refactor: move allValues, zip to internal

 - prune collect.js

* docs: clarify not Jessie

Co-authored-by: Turadg Aleahmad <[email protected]>

---------

Co-authored-by: Turadg Aleahmad <[email protected]>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Feb 25, 2023
1 parent 67b9128 commit b71d61c
Show file tree
Hide file tree
Showing 11 changed files with 144 additions and 142 deletions.
11 changes: 0 additions & 11 deletions packages/inter-protocol/src/collect.js

This file was deleted.

5 changes: 2 additions & 3 deletions packages/inter-protocol/src/proposals/demoIssuers.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
/* eslint-disable @jessie.js/no-nested-await -- demo file */
import { AmountMath, AssetKind } from '@agoric/ertp';
import { objectMap } from '@agoric/internal';
import { allValues, objectMap } from '@agoric/internal';
import {
makeRatio,
natSafeMath,
} from '@agoric/zoe/src/contractSupport/index.js';
import { E, Far } from '@endo/far';
import { Stake, Stable } from '@agoric/vats/src/tokens.js';
import { Nat } from '@endo/nat';
import * as Collect from '../collect.js';

const { Fail, quote: q } = assert;
const { multiply, floorDivide } = natSafeMath;
Expand Down Expand Up @@ -491,7 +490,7 @@ export const fundAMM = async ({

const vats = { mints, priceAuthority: priceAuthorityVat };

const kits = await Collect.allValues(
const kits = await allValues(
objectMap(
fromEntries([Stable.symbol, ...keys(AMMDemoState)].map(n => [n, n])),
async issuerName => {
Expand Down
5 changes: 2 additions & 3 deletions packages/inter-protocol/test/amm/vpool-xyk-amm/setup.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { makeLoopback } from '@endo/captp';
import { E } from '@endo/eventual-send';

import { makeTracer } from '@agoric/internal';
import { allValues, makeTracer } from '@agoric/internal';
import {
makeAgoricNamesAccess,
makePromiseSpace,
Expand All @@ -12,7 +12,6 @@ import { makeZoeKit } from '@agoric/zoe';
import { makeFakeVatAdmin } from '@agoric/zoe/tools/fakeVatAdmin.js';
import buildManualTimer from '@agoric/zoe/tools/manualTimer.js';

import * as Collect from '../../../src/collect.js';
import {
setupAmm,
setupReserve,
Expand Down Expand Up @@ -130,7 +129,7 @@ export const setupAmmServices = async (
]);
await setupReserve(space);

const installs = await Collect.allValues({
const installs = await allValues({
amm: installation.consume.amm,
governor: installation.consume.contractGovernor,
electorate: installation.consume.committee,
Expand Down
2 changes: 1 addition & 1 deletion packages/inter-protocol/test/psm/setupPsm.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { makeScalarMapStore } from '@agoric/vat-data';
import { makeZoeKit } from '@agoric/zoe';
import { makeFakeVatAdmin } from '@agoric/zoe/tools/fakeVatAdmin.js';
import buildManualTimer from '@agoric/zoe/tools/manualTimer.js';
import { allValues } from '@agoric/internal';
import { makeMockChainStorageRoot } from '@agoric/internal/src/storage-test-utils.js';
import { makeIssuerKit } from '@agoric/ertp';

Expand All @@ -21,7 +22,6 @@ import {
} from '../supports.js';
import { startEconomicCommittee } from '../../src/proposals/startEconCommittee.js';
import { startPSM, startEconCharter } from '../../src/proposals/startPSM.js';
import { allValues } from '../../src/collect.js';

const psmRoot = './src/psm/psm.js'; // package relative
const charterRoot = './src/econCommitteeCharter.js'; // package relative
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
import { eventLoopIteration } from '@agoric/zoe/tools/eventLoopIteration.js';
import buildManualTimer from '@agoric/zoe/tools/manualTimer.js';
import { E } from '@endo/far';
import { zip } from '../../src/collect.js';
import { zip } from '@agoric/internal';
import { INVITATION_MAKERS_DESC as EC_INVITATION_MAKERS_DESC } from '../../src/econCommitteeCharter.js';
import { INVITATION_MAKERS_DESC as ORACLE_INVITATION_MAKERS_DESC } from '../../src/price/fluxAggregator.js';
import { ensureOracleBrands } from '../../src/proposals/price-feed-proposal.js';
Expand Down
5 changes: 2 additions & 3 deletions packages/inter-protocol/test/vaultFactory/driver.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import '@agoric/zoe/exported.js';

import { AmountMath, AssetKind, makeIssuerKit } from '@agoric/ertp';
import { makeTracer, objectMap } from '@agoric/internal';
import { allValues, makeTracer, objectMap } from '@agoric/internal';
import { makeNotifierFromSubscriber } from '@agoric/notifier';
import { unsafeMakeBundleCache } from '@agoric/swingset-vat/tools/bundleTool.js';
import {
Expand All @@ -13,7 +13,6 @@ import buildManualTimer from '@agoric/zoe/tools/manualTimer.js';
import { E } from '@endo/eventual-send';
import { deeplyFulfilled } from '@endo/marshal';

import * as Collect from '../../src/collect.js';
import {
setupAmm,
setupReserve,
Expand Down Expand Up @@ -105,7 +104,7 @@ export const makeDriverContext = async () => {

// note that the liquidation might be a different bundle name
// objectMap(contractRoots, (root, k) => loader.load(root, k)),
const bundles = await Collect.allValues({
const bundles = await allValues({
faucet: bundleCache.load(contractRoots.faucet, 'faucet'),
liquidate: bundleCache.load(
contractRoots.liquidate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { test as unknownTest } from '@agoric/zoe/tools/prepare-test-env-ava.js';

import { AmountMath, AssetKind, makeIssuerKit } from '@agoric/ertp';
import { makeParamManagerBuilder } from '@agoric/governance';
import { makeTracer, objectMap } from '@agoric/internal';
import { allValues, makeTracer, objectMap } from '@agoric/internal';
import {
makeNotifierFromAsyncIterable,
makeNotifierFromSubscriber,
Expand All @@ -22,7 +22,6 @@ import buildManualTimer from '@agoric/zoe/tools/manualTimer.js';
import { makeScriptedPriceAuthority } from '@agoric/zoe/tools/scriptedPriceAuthority.js';
import { E } from '@endo/eventual-send';
import { deeplyFulfilled } from '@endo/marshal';
import * as Collect from '../../src/collect.js';
import { calculateCurrentDebt } from '../../src/interest-math.js';
import { SECONDS_PER_YEAR } from '../../src/interest.js';
import {
Expand Down Expand Up @@ -115,7 +114,7 @@ test.before(async t => {

const bundleCache = await unsafeMakeBundleCache('./bundles/'); // package-relative
// note that the liquidation might be a different bundle name
const bundles = await Collect.allValues({
const bundles = await allValues({
faucet: bundleCache.load(contractRoots.faucet, 'faucet'),
liquidate: bundleCache.load(contractRoots.liquidate, 'liquidateMinimum'),
VaultFactory: bundleCache.load(contractRoots.VaultFactory, 'VaultFactory'),
Expand Down
1 change: 1 addition & 0 deletions packages/internal/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
export * from './config.js';
export * from './debug.js';
export * from './utils.js';
export * from './method-tools.js';
109 changes: 109 additions & 0 deletions packages/internal/src/method-tools.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// @ts-check
import { isObject } from '@endo/marshal';

/**
* @file method-tools use dynamic property lookup, which is not Jessie-compatible
*/

const { getPrototypeOf, create, fromEntries, getOwnPropertyDescriptors } =
Object;
const { ownKeys, apply } = Reflect;

/** @typedef {import('@endo/marshal/src/types').Remotable} Remotable */

/**
* Prioritize symbols as earlier than strings.
*
* @param {string|symbol} a
* @param {string|symbol} b
* @returns {-1 | 0 | 1}
*/
const compareStringified = (a, b) => {
if (typeof a === typeof b) {
const left = String(a);
const right = String(b);
// eslint-disable-next-line no-nested-ternary
return left < right ? -1 : left > right ? 1 : 0;
}
if (typeof a === 'symbol') {
assert(typeof b === 'string');
return -1;
}
assert(typeof a === 'string');
assert(typeof b === 'symbol');
return 1;
};

/**
* TODO Consolidate with the `getMethodNames` in `@endo/eventual-send`
*
* @param {any} val
* @returns {(string|symbol)[]}
*/
export const getMethodNames = val => {
let layer = val;
const names = new Set(); // Set to deduplicate
while (layer !== null && layer !== Object.prototype) {
// be tolerant of non-objects
const descs = getOwnPropertyDescriptors(layer);
for (const name of ownKeys(descs)) {
// In case a method is overridden by a non-method,
// test `val[name]` rather than `layer[name]`
if (typeof val[name] === 'function') {
names.add(name);
}
}
if (!isObject(val)) {
break;
}
layer = getPrototypeOf(layer);
}
return harden([...names].sort(compareStringified));
};
harden(getMethodNames);

/**
* TODO This function exists only to ease the
* https://github.com/Agoric/agoric-sdk/pull/5970 transition, from all methods
* being own properties to methods being inherited from a common prototype.
* This transition breaks two patterns used in prior code: autobinding,
* and enumerating methods by enumerating own properties. For both, the
* preferred repairs are
* * autobinding: Replace, for example,
* `foo(obj.method)` with `foo(arg => `obj.method(arg))`. IOW, stop relying
* on expressions like `obj.method` to extract a method still bound to the
* state of `obj` because, for virtual and durable objects,
* they no longer will after #5970.
* * method enumeration: Replace, for example
* `Reflect.ownKeys(obj)` with `getMethodNames(obj)`.
*
* Once all problematic cases have been converted in this manner, this
* `bindAllMethods` hack can and TODO should be deleted. However, we currently
* have no reliable static way to track down and fix all autobinding sites.
* For those objects that have not yet been fully repaired by the above two
* techniques, `bindAllMethods` creates an object that acts much like the
* pre-#5970 objects, with all their methods as instance-bound own properties.
* It does this by making a new object inheriting from `obj` where the new
* object has bound own methods overridding all the methods it would have
* inherited from `obj`.
*
* @param {Remotable} obj
* @returns {Remotable}
*/
export const bindAllMethods = obj =>
harden(
create(
obj,
fromEntries(
getMethodNames(obj).map(name => [
name,
{
value: (/** @type {unknown[]} */ ...args) =>
apply(obj[name], obj, args),
enumerable: true,
},
]),
),
),
);
harden(bindAllMethods);
Loading

0 comments on commit b71d61c

Please sign in to comment.