@agoric/zoe 0.26.3-dev-8baf0aa.0 → 0.26.3-dev-cc54325.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +2 -2
  2. package/bundles/bundle-contractFacet-js-meta.json +88 -80
  3. package/bundles/bundle-contractFacet.js +1 -1
  4. package/package.json +11 -10
  5. package/src/contractFacet/reallocate.d.ts +3 -0
  6. package/src/contractFacet/reallocate.d.ts.map +1 -0
  7. package/src/contractFacet/reallocate.js +94 -0
  8. package/src/contractFacet/types.d.ts +16 -1
  9. package/src/contractFacet/types.d.ts.map +1 -1
  10. package/src/contractFacet/types.js +20 -0
  11. package/src/contractFacet/zcfSeat.d.ts.map +1 -1
  12. package/src/contractFacet/zcfSeat.js +104 -3
  13. package/src/contractFacet/zcfZygote.d.ts.map +1 -1
  14. package/src/contractFacet/zcfZygote.js +31 -22
  15. package/src/contractSupport/atomicTransfer.d.ts +0 -6
  16. package/src/contractSupport/atomicTransfer.d.ts.map +1 -1
  17. package/src/contractSupport/atomicTransfer.js +5 -90
  18. package/src/contractSupport/zoeHelpers.d.ts.map +1 -1
  19. package/src/contractSupport/zoeHelpers.js +3 -10
  20. package/src/contracts/auction/firstPriceLogic.d.ts.map +1 -1
  21. package/src/contracts/auction/firstPriceLogic.js +1 -3
  22. package/src/contracts/auction/secondPriceLogic.d.ts.map +1 -1
  23. package/src/contracts/auction/secondPriceLogic.js +1 -3
  24. package/src/contracts/autoswap.d.ts.map +1 -1
  25. package/src/contracts/autoswap.js +3 -7
  26. package/src/contracts/barterExchange.d.ts.map +1 -1
  27. package/src/contracts/barterExchange.js +2 -3
  28. package/src/contracts/callSpread/fundedCallSpread.d.ts.map +1 -1
  29. package/src/contracts/callSpread/fundedCallSpread.js +1 -3
  30. package/src/contracts/callSpread/pricedCallSpread.d.ts.map +1 -1
  31. package/src/contracts/callSpread/pricedCallSpread.js +1 -3
  32. package/src/contracts/loan/borrow.d.ts.map +1 -1
  33. package/src/contracts/loan/borrow.js +1 -3
  34. package/src/contracts/loan/close.d.ts.map +1 -1
  35. package/src/contracts/loan/close.js +2 -6
  36. package/src/contracts/scaledPriceAuthority.d.ts +10 -1
  37. package/src/contracts/scaledPriceAuthority.d.ts.map +1 -1
  38. package/src/contracts/scaledPriceAuthority.js +8 -1
  39. package/src/contracts/sellItems.d.ts.map +1 -1
  40. package/src/contracts/sellItems.js +1 -3
  41. package/src/internal-types.d.ts +1 -1
  42. package/src/internal-types.d.ts.map +1 -1
  43. package/src/internal-types.js +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/zoe",
3
- "version": "0.26.3-dev-8baf0aa.0+8baf0aa",
3
+ "version": "0.26.3-dev-cc54325.0+cc54325",
4
4
  "description": "Zoe: the Smart Contract Framework for Offer Enforcement",
5
5
  "type": "module",
6
6
  "main": "./src/zoeService/zoe.js",
@@ -43,14 +43,14 @@
43
43
  },
44
44
  "homepage": "https://github.com/Agoric/agoric-sdk#readme",
45
45
  "dependencies": {
46
- "@agoric/assert": "0.6.1-dev-8baf0aa.0+8baf0aa",
47
- "@agoric/ertp": "0.16.3-dev-8baf0aa.0+8baf0aa",
48
- "@agoric/internal": "0.3.3-dev-8baf0aa.0+8baf0aa",
49
- "@agoric/notifier": "0.6.3-dev-8baf0aa.0+8baf0aa",
50
- "@agoric/store": "0.9.3-dev-8baf0aa.0+8baf0aa",
51
- "@agoric/swingset-vat": "0.32.3-dev-8baf0aa.0+8baf0aa",
52
- "@agoric/time": "0.3.3-dev-8baf0aa.0+8baf0aa",
53
- "@agoric/vat-data": "0.5.3-dev-8baf0aa.0+8baf0aa",
46
+ "@agoric/assert": "0.6.1-dev-cc54325.0+cc54325",
47
+ "@agoric/ertp": "0.16.3-dev-cc54325.0+cc54325",
48
+ "@agoric/internal": "0.3.3-dev-cc54325.0+cc54325",
49
+ "@agoric/notifier": "0.6.3-dev-cc54325.0+cc54325",
50
+ "@agoric/store": "0.9.3-dev-cc54325.0+cc54325",
51
+ "@agoric/swingset-vat": "0.32.3-dev-cc54325.0+cc54325",
52
+ "@agoric/time": "0.3.3-dev-cc54325.0+cc54325",
53
+ "@agoric/vat-data": "0.5.3-dev-cc54325.0+cc54325",
54
54
  "@endo/bundle-source": "^2.5.2",
55
55
  "@endo/captp": "^3.1.2",
56
56
  "@endo/eventual-send": "^0.17.3",
@@ -104,6 +104,7 @@
104
104
  "test/unitTests/zcf/test-reallocate-empty.js",
105
105
  "test/unitTests/zcf/test-zoeHelpersWZcf.js",
106
106
  "test/unitTests/zcf/test-reallocateForZCFMint.js",
107
+ "test/unitTests/zcf/test-atomicRearrange.js",
107
108
  "test/unitTests/zcf/test-zcf.js",
108
109
  "test/unitTests/zcf/test-allStagedSeatsUsed.js",
109
110
  "# ManualTimer.setWakeup: no function",
@@ -127,5 +128,5 @@
127
128
  "publishConfig": {
128
129
  "access": "public"
129
130
  },
130
- "gitHead": "8baf0aabe3cadeb1cd07fd30641d11baf3e68eaf"
131
+ "gitHead": "cc543255026eb4aa3c8e0ad97ef7b572871063cd"
131
132
  }
@@ -0,0 +1,3 @@
1
+ export function makeAllocationMap(transfers: Array<TransferPart>): [ZCFSeat, AmountKeywordRecord][];
2
+ export type TransactionList = Array<AmountKeywordRecord>;
3
+ //# sourceMappingURL=reallocate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reallocate.d.ts","sourceRoot":"","sources":["reallocate.js"],"names":[],"mappings":"AAiBO,6CAHI,mBAAmB,GACjB,CAAC,OAAO,EAAE,mBAAmB,CAAC,EAAE,CA8E5C;8BAtFa,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,94 @@
1
+ import { makeScalarMapStore } from '@agoric/vat-data';
2
+
3
+ import { assertRightsConserved } from './rightsConservation.js';
4
+ import { addToAllocation, subtractFromAllocation } from './allocationMath.js';
5
+
6
+ const { Fail } = assert;
7
+
8
+ /** @typedef {Array<AmountKeywordRecord>} TransactionList */
9
+
10
+ /**
11
+ * Convert from a list of transfer descriptions ([fromSeat, toSeat, fromAmount,
12
+ * toAmount], with many parts optional) to a list of resulting allocations for
13
+ * each of the seats mentioned.
14
+ *
15
+ * @param {Array<TransferPart>} transfers
16
+ * @returns {[ZCFSeat, AmountKeywordRecord][]}
17
+ */
18
+ export const makeAllocationMap = transfers => {
19
+ /** @type {MapStore<ZCFSeat, [TransactionList, TransactionList]>} */
20
+ const allocations = makeScalarMapStore();
21
+
22
+ const getAllocations = seat => {
23
+ if (allocations.has(seat)) {
24
+ return allocations.get(seat);
25
+ }
26
+
27
+ /** @type {[TransactionList, TransactionList]} */
28
+ const pair = [[], []];
29
+ allocations.init(seat, pair);
30
+ return pair;
31
+ };
32
+
33
+ const decrementAllocation = (seat, decrement) => {
34
+ const [incr, decr] = getAllocations(seat);
35
+
36
+ const newDecr = [...decr, decrement];
37
+ allocations.set(seat, [incr, newDecr]);
38
+ };
39
+
40
+ const incrementAllocation = (seat, increment) => {
41
+ const [incr, decr] = getAllocations(seat);
42
+
43
+ const newIncr = [...incr, increment];
44
+ allocations.set(seat, [newIncr, decr]);
45
+ };
46
+
47
+ for (const [fromSeat, toSeat, fromAmounts, toAmounts] of transfers) {
48
+ if (fromSeat) {
49
+ if (!fromAmounts) {
50
+ throw Fail`Transfer from ${fromSeat} must say how much`;
51
+ }
52
+ decrementAllocation(fromSeat, fromAmounts);
53
+ if (toSeat) {
54
+ // Conserved transfer between seats
55
+ if (toAmounts) {
56
+ // distinct amounts, so we check conservation.
57
+ assertRightsConserved(
58
+ Object.values(fromAmounts),
59
+ Object.values(toAmounts),
60
+ );
61
+ incrementAllocation(toSeat, toAmounts);
62
+ } else {
63
+ // fromAmounts will be used for toAmounts as well
64
+ incrementAllocation(toSeat, fromAmounts);
65
+ }
66
+ } else {
67
+ // Transfer only from fromSeat
68
+ !toAmounts ||
69
+ Fail`Transfer without toSeat cannot have toAmounts ${toAmounts}`;
70
+ }
71
+ } else {
72
+ toSeat || Fail`Transfer must have at least one of fromSeat or toSeat`;
73
+ // Transfer only to toSeat
74
+ !fromAmounts ||
75
+ Fail`Transfer without fromSeat cannot have fromAmounts ${fromAmounts}`;
76
+ toAmounts || Fail`Transfer to ${toSeat} must say how much`;
77
+ incrementAllocation(toSeat, toAmounts);
78
+ }
79
+ }
80
+
81
+ /** @type {[ZCFSeat,AmountKeywordRecord][]} */
82
+ const resultingAllocations = [];
83
+ for (const [seat, [incrList, decrList]] of allocations.entries()) {
84
+ let newAlloc = seat.getCurrentAllocation();
85
+ for (const incr of incrList) {
86
+ newAlloc = addToAllocation(newAlloc, incr);
87
+ }
88
+ for (const decr of decrList) {
89
+ newAlloc = subtractFromAllocation(newAlloc, decr);
90
+ }
91
+ resultingAllocations.push([seat, newAlloc]);
92
+ }
93
+ return resultingAllocations;
94
+ };
@@ -14,6 +14,10 @@ type ZCFMakeEmptySeatKit = (exit?: ExitRule | undefined) => ZcfSeatKit;
14
14
  * in code as zcf.
15
15
  */
16
16
  type ZCF<CT extends unknown = Record<string, unknown>> = {
17
+ /**
18
+ * - atomically reallocate amounts among seats.
19
+ */
20
+ atomicRearrange: (transfers: TransferPart[]) => void;
17
21
  /**
18
22
  * - reallocate amounts among seats.
19
23
  * Deprecated: Use atomicRearrange instead.
@@ -71,6 +75,12 @@ type ZCF<CT extends unknown = Record<string, unknown>> = {
71
75
  * effect offer safety for seats whose allocations change.
72
76
  */
73
77
  type Reallocate = (seat1: ZCFSeat, seat2: ZCFSeat, ...seatRest: Array<ZCFSeat>) => void;
78
+ type TransferPart = [
79
+ fromSeat?: ZCFSeat,
80
+ toSeat?: ZCFSeat,
81
+ fromAmounts?: AmountKeywordRecord,
82
+ toAmounts?: AmountKeywordRecord
83
+ ];
74
84
  /**
75
85
  * Informs Zoe about an issuer and returns a promise for acknowledging
76
86
  * when the issuer is added and ready.
@@ -175,12 +185,17 @@ type HandleOffer<OR extends unknown> = (seat: ZCFSeat, offerArgs?: object) => OR
175
185
  type OfferHandler<OR extends unknown = unknown> = HandleOffer<OR> | {
176
186
  handle: HandleOffer<OR>;
177
187
  };
188
+ type ContractMeta = {
189
+ customTermsShape?: CopyRecord<any> | undefined;
190
+ privateArgsShape?: CopyRecord<any> | undefined;
191
+ upgradability?: "canBeUpgraded" | "canUpgrade" | undefined;
192
+ };
178
193
  /**
179
194
  * API for a contract start function.
180
195
  *
181
196
  * CAVEAT: assumes synchronous
182
197
  */
183
- type ContractStartFn<PF extends unknown = any, CF extends unknown = any, CT extends unknown = any, PA extends unknown = any> = (zcf: ZCF<CT>, privateArgs: PA) => ContractStartFnResult<PF, CF>;
198
+ type ContractStartFn<PF extends unknown = any, CF extends unknown = any, CT extends unknown = any, PA extends unknown = any> = (zcf: ZCF<CT>, privateArgs: PA, baggage?: MapStore<any, any> | undefined) => ContractStartFnResult<PF, CF>;
184
199
  type ContractStartFnResult<PF, CF> = {
185
200
  publicFacet: PF;
186
201
  creatorFacet: CF;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.js"],"names":[],"mappings":"2BAIc,OAAO,cAAc,EAAE,mBAAmB;;;;kBAI3C,GAAG;4DAOH,UAAU;;;;;;;;;;;;;;;gBAaT,UAAU;;;;;;mCAEA,OAAO,KAAK,IAAI;;;;;;gBAG1B,UAAU;oBAGV,cAAc;2BACD,UAAU,KAAK,IAAI;yBAChC,mBAAmB;mBACnB,MAAM,KAAK,UAAU,CAAC;yBACtB,MAAM,OAAO,KAAK,CAAC;cACnB,MAAM,aAAa,GAAG,EAAE;;;kBAGxB,mBAAmB;0DAEnB,OAAO,6CAEF,qBAAqB,YACzB,mBAAmB;qBAEpB,kBAAkB;sBAClB,mBAAmB;gBACnB,UAAU;yBACV,MAAM,QAAQ,IAAI,CAAC;8BACT,MAAM,MAAM,CAAC,KAAK,QAAQ,IAAI,CAAC;oBACzC,MAAM,QAAQ,MAAM,MAAM,CAAC,CAAC;iBAC5B,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;0BAIP,OAAO,SAAS,OAAO,eAC3C,MAAQ,OAAO,CAAC,KAAK,IAAI;;;;;4BA6Bf,KAAK,MAAM,CAAC,WACZ,OAAO,KACL,QAAQ,iBAAe,CAAC;;;;;;;;;;;gFAMnB,MAAM,kBACH,MAAM,kBACN,OAAO;oCAgBjB,OAAO,wBACP,aAAa,KAEX,QAAQ,QAAQ,KAAK,CAAC,CAAC;;;;;;;;;;;;;;;2BAkBzB,MAAM,OAAO,MAAM,EAAE,OAAO,CAAC,KAC3B,IAAI;;qBAMH,MAAM,aAAa,CAAC,CAAC;;;;;;;;;;;;uBACb,mBAAmB,YAAY,OAAO,KAAK,OAAO;;;;;;;;;yBAWjD,mBAAmB,WAClB,OAAO,KACZ,IAAI;;;;;;4BAcZ,OAAO,KACL,KAAK;;;;;uCAOP,OAAO,2CAEL,OAAO,GAAG,CAAC;;wBAKI,UAAU,KAAK,IAAI;UACjC,WAAW;mBACX,MAAM,QAAQ,WAAW,UAAU,CAAC,CAAC;eACrC,MAAM,OAAO;iBACb,MAAM,cAAc;wBACpB,qBAAqB;0BACrB,MAAM,UAAU;;;;yBAChB,MAAM,UAAU;;;;yBAEhB,MAAM,OAAO;iCAEG,UAAU,KAAK,OAAO;;;;uCAChB,mBAAmB,KAAK,mBAAmB;;;;uCAE3C,mBAAmB,KAAK,mBAAmB;;;;WAEjE,MAAM,IAAI;;kBAKX;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,KAAK,QAAQ,CAAC,CAAA;CAAC;8CAKtC,OAAO,cAAc,MAAM,KAAK,EAAE;kDAKzC,YAAY,EAAE,CAAC,GAAG;IAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAA;CAAE;;;;;;qIAe/C,IAAI,EAAE,CAAC,eACP,EAAE,KACA,sBAAsB,EAAE,EAAE,EAAE,CAAC;;iBAO5B,EAAE;kBACF,EAAE;;;qBAMH,OAAO,qBAAqB,EAAE,UAAU,CAAC,CAAC,CAAC;kBAI3C,OAAO,qBAAqB,EAAE,UAAU"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.js"],"names":[],"mappings":"2BAIc,OAAO,cAAc,EAAE,mBAAmB;;;;kBAI3C,GAAG;4DAOH,UAAU;;;;;;;;;;;;;;iCAaG,cAAc,KAAK,IAAI;;;;;gBACnC,UAAU;;;;;;mCAEA,OAAO,KAAK,IAAI;;;;;;gBAG1B,UAAU;oBAGV,cAAc;2BACD,UAAU,KAAK,IAAI;yBAChC,mBAAmB;mBACnB,MAAM,KAAK,UAAU,CAAC;yBACtB,MAAM,OAAO,KAAK,CAAC;cACnB,MAAM,aAAa,GAAG,EAAE;;;kBAGxB,mBAAmB;0DAEnB,OAAO,6CAEF,qBAAqB,YACzB,mBAAmB;qBAEpB,kBAAkB;sBAClB,mBAAmB;gBACnB,UAAU;yBACV,MAAM,QAAQ,IAAI,CAAC;8BACT,MAAM,MAAM,CAAC,KAAK,QAAQ,IAAI,CAAC;oBACzC,MAAM,QAAQ,MAAM,MAAM,CAAC,CAAC;iBAC5B,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;0BAMP,OAAO,SAAS,OAAO,eAC3C,MAAQ,OAAO,CAAC,KAAK,IAAI;oBAwBb;IACZ,QAAY,CAAC,EAAE,OAAO;IACtB,MAAU,CAAC,EAAE,OAAO;IACpB,WAAe,CAAC,EAAE,mBAAmB;IACrC,SAAa,CAAC,EAAE,mBAAmB;CAChC;;;;;4BASO,KAAK,MAAM,CAAC,WACZ,OAAO,KACL,QAAQ,iBAAe,CAAC;;;;;;;;;;;gFAMnB,MAAM,kBACH,MAAM,kBACN,OAAO;oCAgBjB,OAAO,wBACP,aAAa,KAEX,QAAQ,QAAQ,KAAK,CAAC,CAAC;;;;;;;;;;;;;;;2BAkBzB,MAAM,OAAO,MAAM,EAAE,OAAO,CAAC,KAC3B,IAAI;;qBAMH,MAAM,aAAa,CAAC,CAAC;;;;;;;;;;;;uBACb,mBAAmB,YAAY,OAAO,KAAK,OAAO;;;;;;;;;yBAWjD,mBAAmB,WAClB,OAAO,KACZ,IAAI;;;;;;4BAcZ,OAAO,KACL,KAAK;;;;;uCAOP,OAAO,2CAEL,OAAO,GAAG,CAAC;;wBAKI,UAAU,KAAK,IAAI;UACjC,WAAW;mBACX,MAAM,QAAQ,WAAW,UAAU,CAAC,CAAC;eACrC,MAAM,OAAO;iBACb,MAAM,cAAc;wBACpB,qBAAqB;0BACrB,MAAM,UAAU;;;;yBAChB,MAAM,UAAU;;;;yBAEhB,MAAM,OAAO;iCAEG,UAAU,KAAK,OAAO;;;;uCAChB,mBAAmB,KAAK,mBAAmB;;;;uCAE3C,mBAAmB,KAAK,mBAAmB;;;;WAEjE,MAAM,IAAI;;kBAKX;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,KAAK,QAAQ,CAAC,CAAA;CAAC;8CAKtC,OAAO,cAAc,MAAM,KAAK,EAAE;kDAKzC,YAAY,EAAE,CAAC,GAAG;IAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAA;CAAE;;;;;;;;;;;qIAsB/C,IAAI,EAAE,CAAC,eACP,EAAE,+CAEA,sBAAsB,EAAE,EAAE,EAAE,CAAC;;iBAO5B,EAAE;kBACF,EAAE;;;qBAMH,OAAO,qBAAqB,EAAE,UAAU,CAAC,CAAC,CAAC;kBAI3C,OAAO,qBAAqB,EAAE,UAAU"}
@@ -26,6 +26,7 @@
26
26
  * synchronously from within the contract, and usually is referred to
27
27
  * in code as zcf.
28
28
  *
29
+ * @property {(transfers: TransferPart[]) => void} atomicRearrange - atomically reallocate amounts among seats.
29
30
  * @property {Reallocate} reallocate - reallocate amounts among seats.
30
31
  * Deprecated: Use atomicRearrange instead.
31
32
  * @property {(keyword: Keyword) => void} assertUniqueKeyword - check
@@ -59,6 +60,8 @@
59
60
  */
60
61
 
61
62
  /**
63
+ * @deprecated reallocate(). Use zcf.atomicRearrange() instead
64
+ *
62
65
  * @typedef {(seat1: ZCFSeat, seat2: ZCFSeat, ...seatRest:
63
66
  * Array<ZCFSeat>) => void} Reallocate
64
67
  *
@@ -83,6 +86,15 @@
83
86
  * effect offer safety for seats whose allocations change.
84
87
  */
85
88
 
89
+ /**
90
+ * @typedef {[
91
+ * fromSeat?: ZCFSeat,
92
+ * toSeat?: ZCFSeat,
93
+ * fromAmounts?: AmountKeywordRecord,
94
+ * toAmounts?: AmountKeywordRecord
95
+ * ]} TransferPart
96
+ */
97
+
86
98
  /**
87
99
  * @callback SaveIssuer
88
100
  *
@@ -220,6 +232,13 @@
220
232
  * @typedef {HandleOffer<OR> | { handle: HandleOffer<OR> }} OfferHandler
221
233
  */
222
234
 
235
+ /**
236
+ * @typedef ContractMeta
237
+ * @property {CopyRecord<Pattern>} [customTermsShape]
238
+ * @property {CopyRecord<Pattern>} [privateArgsShape]
239
+ * @property {'canBeUpgraded' | 'canUpgrade'} [upgradability]
240
+ */
241
+
223
242
  /**
224
243
  * API for a contract start function.
225
244
  *
@@ -234,6 +253,7 @@
234
253
  * @callback ContractStartFn
235
254
  * @param {ZCF<CT>} zcf
236
255
  * @param {PA} privateArgs
256
+ * @param {MapStore} [baggage]
237
257
  * @returns {ContractStartFnResult<PF, CF>}
238
258
  */
239
259
 
@@ -1 +1 @@
1
- {"version":3,"file":"zcfSeat.d.ts","sourceRoot":"","sources":["zcfSeat.js"],"names":[],"mappings":"AAwBA,gCAAgC;AAChC,gCADW,iBAAiB,CAsX1B"}
1
+ {"version":3,"file":"zcfSeat.d.ts","sourceRoot":"","sources":["zcfSeat.js"],"names":[],"mappings":"AA0BA,gCAAgC;AAChC,gCADW,iBAAiB,CAyd1B"}
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  makeScalarBigWeakMapStore,
3
- provideDurableMapStore,
4
- provideDurableWeakMapStore,
3
+ prepareExoClass,
5
4
  prepareExoClassKit,
6
5
  provide,
7
- prepareExoClass,
6
+ provideDurableMapStore,
7
+ provideDurableWeakMapStore,
8
8
  } from '@agoric/vat-data';
9
9
  import { E } from '@endo/eventual-send';
10
10
  import { AmountMath } from '@agoric/ertp';
@@ -19,6 +19,8 @@ import {
19
19
  SeatDataShape,
20
20
  SeatShape,
21
21
  } from '../typeGuards.js';
22
+ import { makeAllocationMap } from './reallocate.js';
23
+ import { TransferPartShape } from '../contractSupport/atomicTransfer.js';
22
24
 
23
25
  const { Fail } = assert;
24
26
 
@@ -214,6 +216,10 @@ export const createSeatManager = (
214
216
 
215
217
  return isOfferSafe(state.proposal, reallocation);
216
218
  },
219
+ /**
220
+ * @deprecated switch to zcf.atomicRearrange()
221
+ * @param {AmountKeywordRecord} amountKeywordRecord
222
+ */
217
223
  incrementBy(amountKeywordRecord) {
218
224
  const { self } = this;
219
225
  assertActive(self);
@@ -227,6 +233,10 @@ export const createSeatManager = (
227
233
  );
228
234
  return amountKeywordRecord;
229
235
  },
236
+ /**
237
+ * @deprecated switch to zcf.atomicRearrange()
238
+ * @param {AmountKeywordRecord} amountKeywordRecord
239
+ */
230
240
  decrementBy(amountKeywordRecord) {
231
241
  const { self } = this;
232
242
  assertActive(self);
@@ -265,6 +275,7 @@ export const createSeatManager = (
265
275
  const ZcfSeatManagerIKit = harden({
266
276
  seatManager: M.interface('ZcfSeatManager', {
267
277
  makeZCFSeat: M.call(SeatDataShape).returns(M.remotable('zcfSeat')),
278
+ atomicRearrange: M.call(M.arrayOf(TransferPartShape)).returns(),
268
279
  reallocate: M.call(M.remotable('zcfSeat'), M.remotable('zcfSeat'))
269
280
  .rest(M.arrayOf(M.remotable('zcfSeat')))
270
281
  .returns(),
@@ -289,6 +300,96 @@ export const createSeatManager = (
289
300
  return zcfSeat;
290
301
  },
291
302
 
303
+ /**
304
+ * Rearrange the allocations according to the transfer descriptions.
305
+ * This is a set of changes to allocations that must satisfy several
306
+ * constraints. If these constraints are all met, then the reallocation
307
+ * happens atomically. Otherwise, it does not happen at all.
308
+ *
309
+ * The conditions
310
+ * * All the mentioned seats are still live,
311
+ * * No outstanding stagings for any of the mentioned seats. Stagings
312
+ * have been deprecated in favor or atomicRearrange. To prevent
313
+ * confusion, for each reallocation, it can only be expressed in
314
+ * the old way or the new way, but not a mixture.
315
+ * * Offer safety
316
+ * * Overall conservation
317
+ *
318
+ * The overall transfer is expressed as an array of `TransferPart`. Each
319
+ * individual `TransferPart` is one of
320
+ * - A transfer from a `fromSeat` to a `toSeat`. Specify both toAmount
321
+ * and fromAmount to change keywords, otherwise only fromAmount is required.
322
+ * - A taking from a `fromSeat`'s allocation. See the `fromOnly` helper.
323
+ * - A giving into a `toSeat`'s allocation. See the `toOnly` helper.
324
+ *
325
+ * @param {TransferPart[]} transfers
326
+ */
327
+ atomicRearrange(transfers) {
328
+ const newAllocations = makeAllocationMap(transfers);
329
+
330
+ // ////// All Seats are active /////////////////////////////////
331
+ for (const [seat] of newAllocations) {
332
+ assertActive(seat);
333
+ !seat.hasStagedAllocation() ||
334
+ Fail`Cannot mix atomicRearrange with seat stagings: ${seat}`;
335
+ zcfSeatToSeatHandle.has(seat) ||
336
+ Fail`The seat ${seat} was not recognized`;
337
+ }
338
+
339
+ // ////// Ensure that rights are conserved overall /////////////
340
+
341
+ // convert array of keywordAmountRecords to 1-level array of Amounts
342
+ const flattenAmounts = allocations =>
343
+ allocations.flatMap(Object.values);
344
+ const previousAmounts = flattenAmounts(
345
+ newAllocations.map(([seat]) => seat.getCurrentAllocation()),
346
+ );
347
+ const newAmounts = flattenAmounts(
348
+ newAllocations.map(([_, allocation]) => allocation),
349
+ );
350
+ assertRightsConserved(previousAmounts, newAmounts);
351
+
352
+ // ////// Ensure that offer safety holds ///////////////////////
353
+ for (const [seat, allocation] of newAllocations) {
354
+ isOfferSafe(seat.getProposal(), allocation) ||
355
+ Fail`Offer safety was violated by the proposed allocation: ${allocation}. Proposal was ${seat.getProposal()}`;
356
+ }
357
+
358
+ const seatHandleAllocations = newAllocations.map(
359
+ ([seat, allocation]) => {
360
+ const seatHandle = zcfSeatToSeatHandle.get(seat);
361
+ return { allocation, seatHandle };
362
+ },
363
+ );
364
+ try {
365
+ // No side effects above. All conditions checked which could have
366
+ // caused us to reject this reallocation. Notice that the current
367
+ // allocations are captured in seatHandleAllocations, so there must
368
+ // be no awaits between that assignment and here.
369
+ //
370
+ // COMMIT POINT
371
+ //
372
+ // The effects must succeed atomically. The call to
373
+ // replaceAllocations() will be processed in the order of updates
374
+ // from ZCF to Zoe. Its effects must occur immediately in Zoe on
375
+ // reception, and must not fail.
376
+ //
377
+ // Commit the new allocations (currentAllocation is replaced
378
+ // for each of the seats) and inform Zoe of the new allocation.
379
+
380
+ for (const [seat, allocation] of newAllocations) {
381
+ activeZCFSeats.set(seat, allocation);
382
+ }
383
+
384
+ // we don't wait for the results here. As described in
385
+ // docs/zoe-zcf.md, The initial allocation to a seat originates with
386
+ // Zoe, but *all subsequent updates come from ZCF to Zoe*.
387
+ void E(zoeInstanceAdmin).replaceAllocations(seatHandleAllocations);
388
+ } catch (err) {
389
+ shutdownWithFailure(err);
390
+ throw err;
391
+ }
392
+ },
292
393
  reallocate(/** @type {ZCFSeat[]} */ ...seats) {
293
394
  seats.forEach(assertActive);
294
395
  seats.forEach(assertStagedAllocation);
@@ -1 +1 @@
1
- {"version":3,"file":"zcfZygote.d.ts","sourceRoot":"","sources":["zcfZygote.js"],"names":[],"mappings":"AAiDO,sCARI,SAAS,cACT,KAAK,UAAU,CAAC,oBAChB,OAAO,KAAK,CAAC,iBACb,aAAa,qBACb,SAAS,2CAEP,QAAQ,SAAS,CAAC,CAyZ9B;kCAxaa,OAAO,cAAc,EAAE,mBAAmB"}
1
+ {"version":3,"file":"zcfZygote.d.ts","sourceRoot":"","sources":["zcfZygote.js"],"names":[],"mappings":"AAiDO,sCARI,SAAS,cACT,KAAK,UAAU,CAAC,oBAChB,OAAO,KAAK,CAAC,iBACb,aAAa,qBACb,SAAS,2CAEP,QAAQ,SAAS,CAAC,CAka9B;kCAjba,OAAO,cAAc,EAAE,mBAAmB"}
@@ -210,6 +210,16 @@ export const makeZCFZygote = async (
210
210
  });
211
211
  const handleOfferObj = makeHandleOfferObj(taker);
212
212
 
213
+ /**
214
+ * @type {() => Promise< {
215
+ * buildRootObject: any,
216
+ * start: undefined,
217
+ * meta: undefined,
218
+ * } | {
219
+ * buildRootObject: undefined,
220
+ * start: ContractStartFn,
221
+ * meta?: ContractMeta,
222
+ }>} */
213
223
  const evaluateContract = () => {
214
224
  let bundle;
215
225
  if (passStyleOf(contractBundleCap) === 'remotable') {
@@ -222,22 +232,18 @@ export const makeZCFZygote = async (
222
232
  return evalContractBundle(bundle);
223
233
  };
224
234
  // evaluate the contract (either the first version, or an upgrade)
225
- const {
226
- start,
227
- buildRootObject,
228
- privateArgsShape,
229
- customTermsShape,
230
- prepare,
231
- } = await evaluateContract();
232
-
233
- if (start === undefined && prepare === undefined) {
235
+ const { start, buildRootObject, meta = {} } = await evaluateContract();
236
+
237
+ if (start === undefined) {
234
238
  buildRootObject === undefined ||
235
239
  Fail`Did you provide a vat bundle instead of a contract bundle?`;
236
- Fail`contract exports missing start/prepare`;
240
+ throw Fail`contract exports missing start`;
237
241
  }
238
- !start ||
239
- !prepare ||
240
- Fail`contract must provide exactly one of "start" and "prepare"`;
242
+
243
+ start.length <= 3 || Fail`invalid start parameters`;
244
+ const durabilityRequired = meta.upgradability
245
+ ? ['canBeUpgraded', 'canUpgrade'].includes(meta.upgradability)
246
+ : false;
241
247
 
242
248
  /** @type {ZCF} */
243
249
  // Using Remotable rather than Far because there are too many complications
@@ -245,6 +251,7 @@ export const makeZCFZygote = async (
245
251
  // accept raw functions. assert cannot be a valid passable! (It's a function
246
252
  // and has members.)
247
253
  const zcf = Remotable('Alleged: zcf', undefined, {
254
+ atomicRearrange: transfers => seatManager.atomicRearrange(transfers),
248
255
  reallocate: (...seats) => seatManager.reallocate(...seats),
249
256
  assertUniqueKeyword: kwd => getInstanceRecHolder().assertUniqueKeyword(kwd),
250
257
  saveIssuer: async (issuerP, keyword) => {
@@ -300,6 +307,7 @@ export const makeZCFZygote = async (
300
307
  const terms = getInstanceRecHolder().getTerms();
301
308
 
302
309
  // If the contract provided customTermsShape, validate the customTerms.
310
+ const { customTermsShape } = meta;
303
311
  if (customTermsShape) {
304
312
  const { brands: _b, issuers: _i, ...customTerms } = terms;
305
313
  mustMatch(harden(customTerms), customTermsShape, 'customTerms');
@@ -372,13 +380,13 @@ export const makeZCFZygote = async (
372
380
  instantiateIssuerStorage(issuerStorageFromZoe);
373
381
  zcfBaggage.init('instanceRecHolder', instanceRecHolder);
374
382
 
375
- const startFn = start || prepare;
383
+ const { privateArgsShape } = meta;
376
384
  if (privateArgsShape) {
377
385
  mustMatch(privateArgs, privateArgsShape, 'privateArgs');
378
386
  }
379
387
  // start a contract for the first time
380
388
  return E.when(
381
- startFn(zcf, privateArgs, contractBaggage),
389
+ start(zcf, privateArgs, contractBaggage),
382
390
  ({
383
391
  creatorFacet = undefined,
384
392
  publicFacet = undefined,
@@ -387,18 +395,16 @@ export const makeZCFZygote = async (
387
395
  }) => {
388
396
  const unexpectedKeys = Object.keys(unexpected);
389
397
  unexpectedKeys.length === 0 ||
390
- Fail`contract ${
391
- prepare ? 'prepare' : 'start'
392
- } returned unrecognized properties ${unexpectedKeys}`;
398
+ Fail`contract "start" returned unrecognized properties ${unexpectedKeys}`;
393
399
 
394
400
  const areDurable = objectMap(
395
401
  { creatorFacet, publicFacet, creatorInvitation },
396
402
  canBeDurable,
397
403
  );
398
404
  const allDurable = Object.values(areDurable).every(Boolean);
399
- if (prepare) {
405
+ if (durabilityRequired) {
400
406
  allDurable ||
401
- Fail`values from prepare() must be durable ${areDurable}`;
407
+ Fail`with ${meta.upgradability}, values from start() must be durable ${areDurable}`;
402
408
  }
403
409
 
404
410
  if (allDurable) {
@@ -418,18 +424,21 @@ export const makeZCFZygote = async (
418
424
  },
419
425
 
420
426
  restartContract: async (privateArgs = undefined) => {
421
- prepare || Fail`prepare must be defined to upgrade a contract`;
427
+ if (meta.upgradability) {
428
+ meta.upgradability === 'canUpgrade' || Fail`contract cannot upgrade`;
429
+ }
422
430
  zoeInstanceAdmin = zcfBaggage.get('zcfInstanceAdmin');
423
431
  instanceRecHolder = zcfBaggage.get('instanceRecHolder');
424
432
  initSeatMgrAndMintKind();
425
433
 
434
+ const { privateArgsShape } = meta;
426
435
  if (privateArgsShape) {
427
436
  mustMatch(privateArgs, privateArgsShape, 'privateArgs');
428
437
  }
429
438
 
430
439
  // restart an upgradeable contract
431
440
  return E.when(
432
- prepare(zcf, privateArgs, contractBaggage),
441
+ start(zcf, privateArgs, contractBaggage),
433
442
  ({
434
443
  creatorFacet = undefined,
435
444
  publicFacet = undefined,
@@ -3,10 +3,4 @@ export function atomicRearrange(zcf: ZCF, transfers: TransferPart[]): void;
3
3
  export function fromOnly(fromSeat: ZCFSeat, fromAmounts: AmountKeywordRecord): TransferPart;
4
4
  export function toOnly(toSeat: ZCFSeat, toAmounts: AmountKeywordRecord): TransferPart;
5
5
  export function atomicTransfer(zcf: ZCF, fromSeat?: ZCFSeat | undefined, toSeat?: ZCFSeat | undefined, fromAmounts?: AmountKeywordRecord | undefined, toAmounts?: AmountKeywordRecord | undefined): void;
6
- export type TransferPart = [
7
- fromSeat?: ZCFSeat,
8
- toSeat?: ZCFSeat,
9
- fromAmounts?: AmountKeywordRecord,
10
- toAmounts?: AmountKeywordRecord
11
- ];
12
6
  //# sourceMappingURL=atomicTransfer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"atomicTransfer.d.ts","sourceRoot":"","sources":["atomicTransfer.js"],"names":[],"mappings":"AAMA,iEAGE;AAgDK,qCAHI,GAAG,aACH,cAAc,QA+ExB;AAcM,mCAJI,OAAO,eACP,mBAAmB,gBAIc;AAcrC,+BAJI,OAAO,aACP,mBAAmB,gBAIqB;AAW5C,oCANI,GAAG,kKAYiE;2BAzKlE;IACZ,QAAY,CAAC,EAAE,OAAO;IACtB,MAAU,CAAC,EAAE,OAAO;IACpB,WAAe,CAAC,EAAE,mBAAmB;IACrC,SAAa,CAAC,EAAE,mBAAmB;CAChC"}
1
+ {"version":3,"file":"atomicTransfer.d.ts","sourceRoot":"","sources":["atomicTransfer.js"],"names":[],"mappings":"AAGA,iEAGE;AAyCK,qCAHI,GAAG,aACH,cAAc,QAIxB;AAcM,mCAJI,OAAO,eACP,mBAAmB,gBAIc;AAcrC,+BAJI,OAAO,aACP,mBAAmB,gBAIqB;AAW5C,oCANI,GAAG,kKAYgE"}