Skip to content

Commit 2b6df45

Browse files
Merge pull request #27 from agoric-labs/fix-upgradability
fix: upgradability
2 parents f8d6197 + 4a03f15 commit 2b6df45

File tree

3 files changed

+126
-118
lines changed

3 files changed

+126
-118
lines changed

agoric/contract/src/index.js

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import { makeRatio } from '@agoric/zoe/src/contractSupport/ratio.js';
1010
import { InvitationShape } from '@agoric/zoe/src/typeGuards.js';
1111
import { handleParamGovernance } from '@agoric/governance';
1212

13-
import { prepareKreadKit } from './kreadKit.js';
13+
import { prepareKreadKit, provideKreadKitRecorderKits } from './kreadKit.js';
14+
import { provide } from '@agoric/vat-data';
15+
import { provideRecorderKits } from './utils.js';
1416

1517
/**
1618
* This contract handles the mint of KREAd characters,
@@ -78,22 +80,6 @@ export const start = async (zcf, privateArgs, baggage) => {
7880
// TODO: move to proposal
7981
const assetNames = terms.assetNames;
8082

81-
const storageNodePaths = {
82-
infoKit: 'info',
83-
characterKit: 'character',
84-
itemKit: 'item',
85-
marketCharacterKit: 'market-characters',
86-
marketItemKit: 'market-items',
87-
marketCharacterMetricsKit: 'market-metrics-character',
88-
marketItemMetricsKit: 'market-metrics-item',
89-
};
90-
91-
const { makeDurableGovernorFacet } = await handleParamGovernance(
92-
zcf,
93-
privateArgs.initialPoserInvitation,
94-
{},
95-
);
96-
9783
// Setting up the mint capabilities here in the prepare function, as discussed with Turadg
9884
// durability is not a concern with these, and defining them here, passing on what's needed
9985
// ensures that the capabilities are where they need to be
@@ -125,6 +111,12 @@ export const start = async (zcf, privateArgs, baggage) => {
125111
powers.marshaller,
126112
);
127113

114+
const recorderKits = await provideKreadKitRecorderKits(
115+
baggage,
116+
powers.storageNode,
117+
makeRecorderKit,
118+
);
119+
128120
assert(paymentBrand, 'missing paymentBrand');
129121
const mintFeeAmount = AmountMath.make(paymentBrand, mintFee);
130122

@@ -136,33 +128,39 @@ export const start = async (zcf, privateArgs, baggage) => {
136128
const royaltyRateRatio = objectToRatio(paymentBrand, royaltyRate);
137129
const platformFeeRatio = objectToRatio(paymentBrand, platformFeeRate);
138130

139-
const kreadKit = await harden(
140-
prepareKreadKit(
141-
baggage,
142-
zcf,
143-
{
144-
seed,
145-
mintFeeAmount,
146-
royaltyRate: royaltyRateRatio,
147-
platformFeeRate: platformFeeRatio,
148-
mintRoyaltyRate: mintRoyaltyRateRatio,
149-
mintPlatformFeeRate: mintPlatformFeeRatio,
150-
royaltyDepositFacet,
151-
platformFeeDepositFacet,
152-
paymentBrand,
153-
minUncommonRating,
154-
},
155-
harden({
156-
characterIssuerRecord,
157-
characterMint,
158-
itemIssuerRecord,
159-
itemMint,
160-
clock,
161-
storageNode: powers.storageNode,
162-
makeRecorderKit,
163-
storageNodePaths,
164-
}),
165-
),
131+
const makeKreadKit = prepareKreadKit(
132+
baggage,
133+
zcf,
134+
{
135+
seed,
136+
mintFeeAmount,
137+
royaltyRate: royaltyRateRatio,
138+
platformFeeRate: platformFeeRatio,
139+
mintRoyaltyRate: mintRoyaltyRateRatio,
140+
mintPlatformFeeRate: mintPlatformFeeRatio,
141+
royaltyDepositFacet,
142+
platformFeeDepositFacet,
143+
paymentBrand,
144+
minUncommonRating,
145+
},
146+
harden({
147+
recorderKits,
148+
characterMint,
149+
characterIssuerRecord,
150+
itemIssuerRecord,
151+
itemMint,
152+
clock,
153+
storageNode: powers.storageNode,
154+
makeRecorderKit,
155+
}),
156+
);
157+
158+
const kreadKit = provide(baggage, 'kitSingleton', () => makeKreadKit());
159+
160+
const { makeDurableGovernorFacet } = handleParamGovernance(
161+
zcf,
162+
privateArgs.initialPoserInvitation,
163+
{},
166164
);
167165

168166
const { governorFacet } = makeDurableGovernorFacet(

agoric/contract/src/kreadKit.js

Lines changed: 56 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import { E } from '@endo/eventual-send';
1111
import { errors } from './errors.js';
1212
import {
1313
makeCharacterNftObjs,
14-
makeStorageNodeRecorderKits,
1514
makeCopyBagAmountShape,
1615
addAllToMap,
16+
provideRecorderKits,
1717
} from './utils.js';
1818

1919
import { text } from './text.js';
@@ -28,14 +28,14 @@ import {
2828
CharacterGuardBagShape,
2929
ItemGuard,
3030
ItemGuardBagShape,
31-
CharacterRecorderGuard,
3231
ItemRecorderGuard,
3332
MarketRecorderGuard,
3433
MarketMetricsGuard,
3534
RarityGuard,
3635
BaseCharacterGuard,
3736
MarketEntryGuard,
3837
CharacterEntryGuard,
38+
CharacterRecorderGuard,
3939
} from './type-guards.js';
4040
import { atomicRearrange } from '@agoric/zoe/src/contractSupport/index.js';
4141
import { multiplyBy } from '@agoric/zoe/src/contractSupport/ratio.js';
@@ -68,12 +68,18 @@ import '@agoric/zoe/exported.js';
6868
* itemIssuerRecord: IssuerRecord<"copyBag">
6969
* itemMint: ZCFMint<"copyBag">
7070
* clock: import('@agoric/time/src/types.js').Clock
71-
* storageNode: StorageNode
72-
* makeRecorderKit: import('@agoric/zoe/src/contractSupport').MakeRecorderKit
73-
* storageNodePaths: Object
71+
* makeRecorderKit: import('@agoric/zoe/src/contractSupport').MakeRecorderKit,
72+
* recorderKits: {
73+
* characterKit: import('@agoric/zoe/src/contractSupport/recorder.js').RecorderKit<unknown>;
74+
* itemKit: import('@agoric/zoe/src/contractSupport/recorder.js').RecorderKit<unknown>;
75+
* marketCharacterKit: import('@agoric/zoe/src/contractSupport/recorder.js').RecorderKit<unknown>;
76+
* marketItemKit: import('@agoric/zoe/src/contractSupport/recorder.js').RecorderKit<unknown>;
77+
* marketCharacterMetricsKit: import('@agoric/zoe/src/contractSupport/recorder.js').RecorderKit<unknown>;
78+
* marketItemMetricsKit: import('@agoric/zoe/src/contractSupport/recorder.js').RecorderKit<unknown>;
79+
* };
7480
* }} powers
7581
*/
76-
export const prepareKreadKit = async (
82+
export const prepareKreadKit = (
7783
baggage,
7884
zcf,
7985
{
@@ -94,34 +100,20 @@ export const prepareKreadKit = async (
94100
itemIssuerRecord,
95101
itemMint,
96102
clock,
97-
storageNode,
98103
makeRecorderKit,
99-
storageNodePaths,
104+
recorderKits: {
105+
characterKit,
106+
itemKit,
107+
marketCharacterKit,
108+
marketCharacterMetricsKit,
109+
marketItemKit,
110+
marketItemMetricsKit,
111+
},
100112
},
101113
) => {
102114
const { brand: characterBrand } = characterIssuerRecord;
103115
const { brand: itemBrand } = itemIssuerRecord;
104116

105-
const {
106-
characterKit,
107-
itemKit,
108-
marketCharacterKit,
109-
marketItemKit,
110-
marketCharacterMetricsKit,
111-
marketItemMetricsKit,
112-
} = await makeStorageNodeRecorderKits(
113-
storageNode,
114-
makeRecorderKit,
115-
storageNodePaths,
116-
{
117-
characterKit: CharacterRecorderGuard,
118-
itemKit: ItemRecorderGuard,
119-
marketCharacterKit: M.arrayOf(MarketRecorderGuard),
120-
marketItemKit: M.arrayOf(MarketRecorderGuard),
121-
marketCharacterMetricsKit: MarketMetricsGuard,
122-
marketItemMetricsKit: MarketMetricsGuard,
123-
},
124-
);
125117
const marketItemNode = marketItemKit.recorder.getStorageNode();
126118
const marketCharacterNode = marketCharacterKit.recorder.getStorageNode();
127119

@@ -133,7 +125,7 @@ export const prepareKreadKit = async (
133125
);
134126
const itemShape = makeCopyBagAmountShape(itemBrand, ItemGuardBagShape);
135127

136-
const makeKreadKitInternal = prepareExoClassKit(
128+
return prepareExoClassKit(
137129
baggage,
138130
'KreadKit',
139131
{
@@ -1793,11 +1785,41 @@ export const prepareKreadKit = async (
17931785
},
17941786
},
17951787
);
1796-
const facets = makeKreadKitInternal();
1797-
return harden({
1798-
public: facets.public,
1799-
creator: facets.creator,
1800-
});
18011788
};
18021789

18031790
harden(prepareKreadKit);
1791+
1792+
/**
1793+
*
1794+
* @param {import('@agoric/vat-data').Baggage} baggage
1795+
* @param {StorageNode} storageNode
1796+
* @param {import('@agoric/zoe/src/contractSupport/recorder.js').MakeRecorderKit} makeRecorderKit
1797+
* @returns
1798+
*/
1799+
export const provideKreadKitRecorderKits = (
1800+
baggage,
1801+
storageNode,
1802+
makeRecorderKit,
1803+
) =>
1804+
provideRecorderKits(
1805+
baggage,
1806+
storageNode,
1807+
makeRecorderKit,
1808+
{
1809+
infoKit: 'info',
1810+
characterKit: 'character',
1811+
itemKit: 'item',
1812+
marketCharacterKit: 'market-characters',
1813+
marketItemKit: 'market-items',
1814+
marketCharacterMetricsKit: 'market-metrics-character',
1815+
marketItemMetricsKit: 'market-metrics-item',
1816+
},
1817+
{
1818+
characterKit: CharacterRecorderGuard,
1819+
itemKit: ItemRecorderGuard,
1820+
marketCharacterKit: M.arrayOf(MarketRecorderGuard),
1821+
marketItemKit: M.arrayOf(MarketRecorderGuard),
1822+
marketCharacterMetricsKit: MarketMetricsGuard,
1823+
marketItemMetricsKit: MarketMetricsGuard,
1824+
},
1825+
);

agoric/contract/src/utils.js

Lines changed: 28 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// @ts-check
2+
import { allValues, objectMap } from '@agoric/internal';
23
import { E } from '@endo/eventual-send';
34
import { M, matches, getCopyMapEntries } from '@endo/patterns';
45

@@ -33,57 +34,44 @@ export const makeCharacterNftObjs = (
3334
};
3435

3536
/**
36-
* @template T
37-
* @typedef {object} RecorderKit<T>
38-
* @property {Publisher<T>} publisher
39-
* @property {StoredSubscriber<T>} subscriber
40-
*/
41-
42-
/**
43-
* @template T
44-
* @param {ERef<StorageNode>} storageNode
45-
* @param {import('@agoric/zoe/src/contractSupport').MakeRecorderKit} makeRecorderKit
46-
* @param {string} path
47-
* @param {Pattern} typeMatcher
48-
* @returns {Promise<import('@agoric/zoe/src/contractSupport').RecorderKit<T>>}
49-
*/
50-
export const makeStorageNodeRecorderKit = async (
51-
storageNode,
52-
makeRecorderKit,
53-
path,
54-
typeMatcher,
55-
) => {
56-
const node = await E(storageNode).makeChildNode(path);
57-
return makeRecorderKit(node, typeMatcher);
58-
};
59-
60-
/**
37+
* @param {import('@agoric/vat-data').Baggage} baggage
6138
* @param {ERef<StorageNode>} storageNode
6239
* @param {import('@agoric/zoe/src/contractSupport').MakeRecorderKit} makeRecorderKit
6340
* @param {{[key: string]: string}} paths
6441
* @param {{[key: string]: Pattern}} typeMatchers
65-
* @returns {Promise<{[key: string]: import('@agoric/zoe/src/contractSupport').RecorderKit<T>}>}
42+
* @returns {Promise<{[key: string]: import('@agoric/zoe/src/contractSupport').RecorderKit<unknown>}>}
6643
*/
67-
export const makeStorageNodeRecorderKits = async (
44+
export const provideRecorderKits = async (
45+
baggage,
6846
storageNode,
6947
makeRecorderKit,
7048
paths,
7149
typeMatchers,
7250
) => {
73-
const recorderMap = {};
74-
await Promise.all(
75-
Object.keys(paths).map(async (key) => {
76-
const recorderKit = await makeStorageNodeRecorderKit(
77-
storageNode,
78-
makeRecorderKit,
79-
paths[key],
80-
typeMatchers[key],
81-
);
82-
recorderMap[key] = recorderKit;
83-
}),
84-
);
51+
console.log('provideRecorderKits', paths, typeMatchers);
52+
const keys = Object.keys(paths);
53+
// assume if any keys are defined they all are
54+
const inBaggage = baggage.has(keys[0]);
55+
if (inBaggage) {
56+
const obj = objectMap(
57+
paths,
58+
/** @type {(value: any, key: string) => any} */
59+
(_, k) => baggage.get(k),
60+
);
61+
return Promise.resolve(harden(obj));
62+
}
63+
64+
const keyedPromises = objectMap(paths, async (_path, key) => {
65+
const node = await E(storageNode).makeChildNode(paths[key]);
66+
return makeRecorderKit(node, typeMatchers[key]);
67+
});
8568

86-
return recorderMap;
69+
return allValues(keyedPromises).then((keyedVals) => {
70+
for (const [k, v] of Object.entries(keyedVals)) {
71+
baggage.init(k, v);
72+
}
73+
return keyedVals;
74+
});
8775
};
8876

8977
/**

0 commit comments

Comments
 (0)