@agoric/client-utils 0.1.1-dev-fb2d05c.0 → 0.1.1-dev-0fa2d27.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 (2) hide show
  1. package/package.json +7 -7
  2. package/src/sync-tools.js +99 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/client-utils",
3
- "version": "0.1.1-dev-fb2d05c.0+fb2d05c",
3
+ "version": "0.1.1-dev-0fa2d27.0+0fa2d27",
4
4
  "description": "Utilities for building Agoric clients",
5
5
  "license": "Apache-2.0",
6
6
  "publishConfig": {
@@ -27,11 +27,11 @@
27
27
  "ts-blank-space": "^0.4.1"
28
28
  },
29
29
  "dependencies": {
30
- "@agoric/casting": "0.4.3-dev-fb2d05c.0+fb2d05c",
31
- "@agoric/ertp": "0.16.3-dev-fb2d05c.0+fb2d05c",
32
- "@agoric/internal": "0.3.3-dev-fb2d05c.0+fb2d05c",
33
- "@agoric/smart-wallet": "0.5.4-dev-fb2d05c.0+fb2d05c",
34
- "@agoric/vats": "0.15.2-dev-fb2d05c.0+fb2d05c",
30
+ "@agoric/casting": "0.4.3-dev-0fa2d27.0+0fa2d27",
31
+ "@agoric/ertp": "0.16.3-dev-0fa2d27.0+0fa2d27",
32
+ "@agoric/internal": "0.3.3-dev-0fa2d27.0+0fa2d27",
33
+ "@agoric/smart-wallet": "0.5.4-dev-0fa2d27.0+0fa2d27",
34
+ "@agoric/vats": "0.15.2-dev-0fa2d27.0+0fa2d27",
35
35
  "@cosmjs/stargate": "^0.32.3",
36
36
  "@cosmjs/tendermint-rpc": "^0.32.3",
37
37
  "@endo/common": "^1.2.7",
@@ -58,5 +58,5 @@
58
58
  ],
59
59
  "timeout": "20m"
60
60
  },
61
- "gitHead": "fb2d05c0d755e1ad68aed1ae1112ea4973aad92e"
61
+ "gitHead": "0fa2d279335cd43d4d3d1a1f53fd080075d6e1be"
62
62
  }
package/src/sync-tools.js CHANGED
@@ -10,7 +10,7 @@
10
10
  * - condition: dest account has a balance >= sent token
11
11
  * - Making sure an offer resulted successfully
12
12
  * - Making sure an offer was exited successfully
13
- *
13
+ * - Make sure an election held by a given committee (see @agoric/governance) turned out as expected
14
14
  */
15
15
 
16
16
  /**
@@ -98,7 +98,7 @@ export const retryUntilCondition = async (
98
98
  }
99
99
  } catch (error) {
100
100
  if (error instanceof Error) {
101
- log(`Error: ${error.message}`);
101
+ log(`Error: ${error.message}: ${error.stack}`);
102
102
  } else {
103
103
  log(`Unknown error: ${String(error)}`);
104
104
  }
@@ -325,3 +325,100 @@ export const waitUntilOfferExited = async (addr, offerId, io, options) => {
325
325
  { setTimeout, ...resolvedOptions },
326
326
  );
327
327
  };
328
+
329
+ /// ////////// Make sure an election held by a given committee //////////
330
+ /// ////////// (see @agoric/governance) turned out as expected //////////
331
+
332
+ /**
333
+ * @typedef {{
334
+ * latestOutcome: {
335
+ * outcome: string;
336
+ * question: import('@endo/marshal').RemotableObject
337
+ * },
338
+ * latestQuestion: {
339
+ * closingRule: { deadline: bigint },
340
+ * questionHandle: import('@endo/marshal').RemotableObject
341
+ * }
342
+ * }} ElectionResult
343
+ */
344
+
345
+ /**
346
+ * @param {string} basePath
347
+ * @param {import('./vstorage-kit').VstorageKit} vstorage
348
+ * @returns {Promise<ElectionResult>}
349
+ */
350
+ const fetchLatestEcQuestion = async (basePath, vstorage) => {
351
+ const pathOutcome = `${basePath}.latestOutcome`;
352
+ const pathQuestion = `${basePath}.latestQuestion`;
353
+
354
+ const [latestOutcome, latestQuestion] = await Promise.all([
355
+ /** @type {Promise<ElectionResult["latestOutcome"]>} */ (
356
+ vstorage.readLatestHead(pathOutcome)
357
+ ),
358
+ /** @type {Promise<ElectionResult["latestQuestion"]>} */ (
359
+ vstorage.readLatestHead(pathQuestion)
360
+ ),
361
+ ]);
362
+
363
+ return { latestOutcome, latestQuestion };
364
+ };
365
+
366
+ /**
367
+ *
368
+ * @param {ElectionResult} electionResult
369
+ * @param {{ outcome: string; deadline: bigint }} expectedResult
370
+ * @returns {boolean}
371
+ */
372
+ const checkCommitteeElectionResult = (electionResult, expectedResult) => {
373
+ const {
374
+ latestOutcome: { outcome, question },
375
+ latestQuestion: {
376
+ closingRule: { deadline },
377
+ questionHandle,
378
+ },
379
+ } = electionResult;
380
+ const { outcome: expectedOutcome, deadline: expectedDeadline } =
381
+ expectedResult;
382
+
383
+ return (
384
+ expectedOutcome === outcome &&
385
+ deadline === expectedDeadline &&
386
+ question === questionHandle
387
+ );
388
+ };
389
+
390
+ /**
391
+ * Depends on "@agoric/governance" package's committee implementation where for a given committee
392
+ * there's two child nodes in vstorage named "latestOutcome" and "latestQuestion" respectively.
393
+ *
394
+ * @param {string} committeePathBase
395
+ * @param {{
396
+ * outcome: string;
397
+ * deadline: bigint;
398
+ * }} expectedResult
399
+ * @param {{
400
+ * vstorage: import('./vstorage-kit').VstorageKit;
401
+ * log: typeof console.log,
402
+ * setTimeout: typeof global.setTimeout
403
+ * }} io
404
+ * @param {WaitUntilOptions} options
405
+ */
406
+ export const waitUntilElectionResult = (
407
+ committeePathBase,
408
+ expectedResult,
409
+ io,
410
+ options,
411
+ ) => {
412
+ const { vstorage, log, setTimeout } = io;
413
+
414
+ const { maxRetries, retryIntervalMs, errorMessage } =
415
+ overrideDefaultOptions(options);
416
+
417
+ return retryUntilCondition(
418
+ () => fetchLatestEcQuestion(committeePathBase, vstorage),
419
+ electionResult =>
420
+ checkCommitteeElectionResult(electionResult, expectedResult),
421
+ errorMessage,
422
+ { maxRetries, retryIntervalMs, log, setTimeout },
423
+ );
424
+ };