diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index a01d25ebad1..69da019ef01 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -272,7 +272,7 @@ jobs: run: yarn build working-directory: a3p-integration - name: run proposals tests - run: yarn test + run: yarn test -m z:acceptance working-directory: a3p-integration - name: collect all core eval scripts # Core eval scripts will be copied under /tmp/core_eval_scripts directory diff --git a/a3p-integration/proposals/n:upgrade-next/.gitignore b/a3p-integration/proposals/n:upgrade-next/.gitignore index da0da987d7b..10c30e2fde7 100644 --- a/a3p-integration/proposals/n:upgrade-next/.gitignore +++ b/a3p-integration/proposals/n:upgrade-next/.gitignore @@ -4,3 +4,4 @@ add-OLIVES/ upgrade-bank/ upgrade-provisionPool/ upgrade-orch-core/ +replace-electorate/ diff --git a/a3p-integration/proposals/n:upgrade-next/acceptInvites.js b/a3p-integration/proposals/n:upgrade-next/acceptInvites.js new file mode 100644 index 00000000000..9567a56f7a8 --- /dev/null +++ b/a3p-integration/proposals/n:upgrade-next/acceptInvites.js @@ -0,0 +1,12 @@ +#!/usr/bin/env node + +import { agops, GOV1ADDR } from '@agoric/synthetic-chain'; + +await agops.ec('committee', '--send-from', GOV1ADDR); +await agops.ec( + 'charter', + '--send-from', + GOV1ADDR, + '--name', + 'econCommitteeCharter', +); diff --git a/a3p-integration/proposals/n:upgrade-next/agoric-tools.js b/a3p-integration/proposals/n:upgrade-next/agoric-tools.js new file mode 100644 index 00000000000..f18ca816913 --- /dev/null +++ b/a3p-integration/proposals/n:upgrade-next/agoric-tools.js @@ -0,0 +1,31 @@ +import { queryVstorage } from '@agoric/synthetic-chain'; +import { makeMarshal, Remotable } from '@endo/marshal'; + +const slotToRemotable = (_slotId, iface = 'Remotable') => + Remotable(iface, undefined, { + getBoardId: () => _slotId, + }); + +// /** @param {BoardRemote | object} val */ +const boardValToSlot = val => { + if ('getBoardId' in val) { + return val.getBoardId(); + } + throw Error(`unknown obj in boardSlottingMarshaller.valToSlot ${val}`); +}; + +const boardSlottingMarshaller = slotToVal => { + return makeMarshal(boardValToSlot, slotToVal, { + serializeBodyFormat: 'smallcaps', + }); +}; + +export const marshaller = boardSlottingMarshaller(slotToRemotable); + +export const queryVstorageFormatted = async (path, index = -1) => { + const data = await queryVstorage(path); + + const formattedData = JSON.parse(data.value); + const formattedDataAtIndex = JSON.parse(formattedData.values.at(index)); + return marshaller.fromCapData(formattedDataAtIndex); +}; diff --git a/a3p-integration/proposals/n:upgrade-next/package.json b/a3p-integration/proposals/n:upgrade-next/package.json index f88ce460a7e..465160effb6 100644 --- a/a3p-integration/proposals/n:upgrade-next/package.json +++ b/a3p-integration/proposals/n:upgrade-next/package.json @@ -11,7 +11,8 @@ "vats/upgrade-bank.js upgrade-bank", "vats/upgrade-provisionPool.js upgrade-provisionPool", "testing/add-LEMONS.js add-LEMONS", - "testing/add-OLIVES.js add-OLIVES" + "testing/add-OLIVES.js add-OLIVES", + "inter-protocol/replace-electorate-core.js replace-electorate A3P_INTEGRATION" ], "type": "Software Upgrade Proposal" }, @@ -19,6 +20,8 @@ "license": "Apache-2.0", "dependencies": { "@agoric/synthetic-chain": "^0.3.0", + "@endo/init": "^1.1.5", + "@endo/marshal": "^1.5.4", "ava": "^5.3.1", "better-sqlite3": "^9.6.0", "execa": "^9.3.1" diff --git a/a3p-integration/proposals/n:upgrade-next/prepare.sh b/a3p-integration/proposals/n:upgrade-next/prepare.sh index cbf6c4d8fc1..5e3e993fc7c 100755 --- a/a3p-integration/proposals/n:upgrade-next/prepare.sh +++ b/a3p-integration/proposals/n:upgrade-next/prepare.sh @@ -7,3 +7,5 @@ set -uxeo pipefail # actions are executed in the previous chain software, and the effects are # persisted so they can be used in the steps after the upgrade is complete, # such as in the "use" or "test" steps, or further proposal layers. + +echo "FRAZZZZZ" diff --git a/a3p-integration/proposals/n:upgrade-next/replaceElectorate.test.js b/a3p-integration/proposals/n:upgrade-next/replaceElectorate.test.js new file mode 100644 index 00000000000..64e08cc48fc --- /dev/null +++ b/a3p-integration/proposals/n:upgrade-next/replaceElectorate.test.js @@ -0,0 +1,50 @@ +import test from 'ava'; +import '@endo/init'; +import { GOV1ADDR, evalBundles, waitForBlock } from '@agoric/synthetic-chain'; +import { passStyleOf } from '@endo/marshal'; +import { queryVstorageFormatted } from './agoric-tools.js'; + +const UPGRADE_PP_DIR = 'replace-electorate'; + +test.skip('what', async t => { + await evalBundles(UPGRADE_PP_DIR); + await waitForBlock(2); + t.pass(); +}); + +test.serial('should be able to view the new accepted invitations', async t => { + const instance = await queryVstorageFormatted( + `published.agoricNames.instance`, + ); + const instances = Object.fromEntries(instance); + + const wallet = await queryVstorageFormatted( + `published.wallet.${GOV1ADDR}.current`, + ); + const usedInvitations = wallet.offerToUsedInvitation.map(v => v[1]); + + const totalCharterInvitations = usedInvitations.filter( + v => v.value[0].description === 'charter member invitation', + ).length; + + t.is(totalCharterInvitations, 2); + + const totalCommitteeInvitations = usedInvitations.filter(v => + v.value[0].description.startsWith('Voter'), + ).length; + t.is(totalCommitteeInvitations, 2); + + const charterInvitation = usedInvitations.find( + v => + v.value[0].instance.getBoardId() === + instances.econCommitteeCharter.getBoardId(), + ); + t.is(passStyleOf(charterInvitation), 'copyRecord'); + + const committeeInvitation = usedInvitations.find( + v => + v.value[0].instance.getBoardId() === + instances.economicCommittee.getBoardId(), + ); + t.is(passStyleOf(committeeInvitation), 'copyRecord'); +}); diff --git a/a3p-integration/proposals/n:upgrade-next/test.sh b/a3p-integration/proposals/n:upgrade-next/test.sh index 215f30f6aaf..76b660706f7 100755 --- a/a3p-integration/proposals/n:upgrade-next/test.sh +++ b/a3p-integration/proposals/n:upgrade-next/test.sh @@ -5,8 +5,9 @@ GLOBIGNORE=initial.test.js -# test the state right after upgrade -yarn ava initial.test.js +yarn ava ./replaceElectorate.test.js +# # test the state right after upgrade +# yarn ava initial.test.js -# test more, in ways that changes system state -yarn ava ./*.test.js +# # test more, in ways that changes system state +# yarn ava ./*.test.js diff --git a/a3p-integration/proposals/n:upgrade-next/use.sh b/a3p-integration/proposals/n:upgrade-next/use.sh new file mode 100644 index 00000000000..4f58010f31a --- /dev/null +++ b/a3p-integration/proposals/n:upgrade-next/use.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# Exit when any command fails +set -uxeo pipefail + +./acceptInvites.js diff --git a/a3p-integration/proposals/n:upgrade-next/yarn.lock b/a3p-integration/proposals/n:upgrade-next/yarn.lock index 5de3eb1fd07..78dc133a0f9 100644 --- a/a3p-integration/proposals/n:upgrade-next/yarn.lock +++ b/a3p-integration/proposals/n:upgrade-next/yarn.lock @@ -20,6 +20,113 @@ __metadata: languageName: node linkType: hard +"@endo/base64@npm:^1.0.8": + version: 1.0.8 + resolution: "@endo/base64@npm:1.0.8" + checksum: 10c0/3501efbf866acc25b9ad0912ec2383e3b976c890a18dc67b5c6eb128433708db69e8ed1cc57190305266bdcbd132659aa87edfc6d02a9886b711e8b86adc21c0 + languageName: node + linkType: hard + +"@endo/common@npm:^1.2.6": + version: 1.2.6 + resolution: "@endo/common@npm:1.2.6" + dependencies: + "@endo/errors": "npm:^1.2.6" + "@endo/eventual-send": "npm:^1.2.6" + "@endo/promise-kit": "npm:^1.1.6" + checksum: 10c0/7cca372677bd1ab535a0f8fc250eca9bfc202ef7dfd24cac6ff1260003aa4512f8db18419dd632b3e57270a589fec54891496904ff2e8a97047f1e187e3f1401 + languageName: node + linkType: hard + +"@endo/env-options@npm:^1.1.7": + version: 1.1.7 + resolution: "@endo/env-options@npm:1.1.7" + checksum: 10c0/5784bd68790041b08d9ead4f6c29cc7871d2e554c23fc44fff38cb20b6b4e55cdba2f78d844ba5ad4b0818185c32475ff318c1b77890d628690d7c7a6ede9475 + languageName: node + linkType: hard + +"@endo/errors@npm:^1.2.6": + version: 1.2.6 + resolution: "@endo/errors@npm:1.2.6" + dependencies: + ses: "npm:^1.9.0" + checksum: 10c0/cbc541c2d26fbfeb1567dd1cdf0e1f110ee9866430c5a1b91d87270d6f00bc8293cc8512301217c4eda35e60677ce62a941d11eb32c7da1f72d450a011ad2bb5 + languageName: node + linkType: hard + +"@endo/eventual-send@npm:^1.2.6": + version: 1.2.6 + resolution: "@endo/eventual-send@npm:1.2.6" + dependencies: + "@endo/env-options": "npm:^1.1.7" + checksum: 10c0/6983d6b88bf4e99f6c469d4ca037793582b06cc0bfa2da085b5bc7ad67333a1fba6e5e7077b7f279be23ccfba1dff9e06c7f85f9980b09fd002227f89a673c11 + languageName: node + linkType: hard + +"@endo/init@npm:^1.1.5": + version: 1.1.5 + resolution: "@endo/init@npm:1.1.5" + dependencies: + "@endo/base64": "npm:^1.0.8" + "@endo/eventual-send": "npm:^1.2.6" + "@endo/lockdown": "npm:^1.0.11" + "@endo/promise-kit": "npm:^1.1.6" + checksum: 10c0/08abda8a0204450cb39c296270d074189f320cdeb03892e87b27a75f6b98c0b5d9c8471e242c53545843211fe713b01b281eec0eabc1c58ca0760a068b90335c + languageName: node + linkType: hard + +"@endo/lockdown@npm:^1.0.11": + version: 1.0.11 + resolution: "@endo/lockdown@npm:1.0.11" + dependencies: + ses: "npm:^1.9.0" + checksum: 10c0/03bb96f370e7ee69d9d8e26b7b124b6381994d3b28a99dc2bcafe77139283701d7543b40e978226cd49443c149e64610e4dd49c32ada931610ba091809478a11 + languageName: node + linkType: hard + +"@endo/marshal@npm:^1.5.4": + version: 1.5.4 + resolution: "@endo/marshal@npm:1.5.4" + dependencies: + "@endo/common": "npm:^1.2.6" + "@endo/errors": "npm:^1.2.6" + "@endo/eventual-send": "npm:^1.2.6" + "@endo/nat": "npm:^5.0.11" + "@endo/pass-style": "npm:^1.4.4" + "@endo/promise-kit": "npm:^1.1.6" + checksum: 10c0/4668a3678567cfbeefc3a47217912ca3f5d8bdb37e0d5d53339953b4ab83950683505f45c0f5c30b415c989bb9df4fa0859849d23b11f5b1064b0da0a13943ab + languageName: node + linkType: hard + +"@endo/nat@npm:^5.0.11": + version: 5.0.11 + resolution: "@endo/nat@npm:5.0.11" + checksum: 10c0/50cd9033657dd35288f0333a966984f788213f1c836e6772c0d731361d5854d0ce24b8a7d6f351d56618eb40f6b369e130c1ad939c83d5833246c09119b2e777 + languageName: node + linkType: hard + +"@endo/pass-style@npm:^1.4.4": + version: 1.4.4 + resolution: "@endo/pass-style@npm:1.4.4" + dependencies: + "@endo/env-options": "npm:^1.1.7" + "@endo/errors": "npm:^1.2.6" + "@endo/eventual-send": "npm:^1.2.6" + "@endo/promise-kit": "npm:^1.1.6" + "@fast-check/ava": "npm:^1.1.5" + checksum: 10c0/d6c6268b269d4c14541087ce6b2975f9e31847893d01360c0ea92392ae93316d94fbf59cd7299853a0fb5214176ad7ffc4616b9b2581fd720bdb55ef96d0beeb + languageName: node + linkType: hard + +"@endo/promise-kit@npm:^1.1.6": + version: 1.1.6 + resolution: "@endo/promise-kit@npm:1.1.6" + dependencies: + ses: "npm:^1.9.0" + checksum: 10c0/d60de663e58f9de32b6705268c62c63c4721f1874813d3c10cae7846e921e4ea8a60c8622ef8c937741a3387fbc60110076b25304afedf270727af7b0c3fecb3 + languageName: node + linkType: hard + "@endo/zip@npm:^1.0.7": version: 1.0.7 resolution: "@endo/zip@npm:1.0.7" @@ -27,6 +134,17 @@ __metadata: languageName: node linkType: hard +"@fast-check/ava@npm:^1.1.5": + version: 1.2.1 + resolution: "@fast-check/ava@npm:1.2.1" + dependencies: + fast-check: "npm:^3.0.0" + peerDependencies: + ava: ^4 || ^5 || ^6 + checksum: 10c0/3800098fd7e8098102544a2f7a595351d063a7ebaeca18ed4901df5ec2679da2330ba8c0db2c820721d4cbb3e23d817ba22fec6d058957930e229f44fa71a684 + languageName: node + linkType: hard + "@isaacs/cliui@npm:^8.0.2": version: 8.0.2 resolution: "@isaacs/cliui@npm:8.0.2" @@ -119,18 +237,20 @@ __metadata: linkType: hard "acorn-walk@npm:^8.2.0": - version: 8.3.1 - resolution: "acorn-walk@npm:8.3.1" - checksum: 10c0/a23d2f7c6b6cad617f4c77f14dfeb062a239208d61753e9ba808d916c550add92b39535467d2e6028280761ac4f5a904cc9df21530b84d3f834e3edef74ddde5 + version: 8.3.4 + resolution: "acorn-walk@npm:8.3.4" + dependencies: + acorn: "npm:^8.11.0" + checksum: 10c0/76537ac5fb2c37a64560feaf3342023dadc086c46da57da363e64c6148dc21b57d49ace26f949e225063acb6fb441eabffd89f7a3066de5ad37ab3e328927c62 languageName: node linkType: hard -"acorn@npm:^8.8.2": - version: 8.11.2 - resolution: "acorn@npm:8.11.2" +"acorn@npm:^8.11.0, acorn@npm:^8.8.2": + version: 8.13.0 + resolution: "acorn@npm:8.13.0" bin: acorn: bin/acorn - checksum: 10c0/a3ed76c761b75ec54b1ec3068fb7f113a182e95aea7f322f65098c2958d232e3d211cb6dac35ff9c647024b63714bc528a26d54a925d1fef2c25585b4c8e4017 + checksum: 10c0/f35dd53d68177c90699f4c37d0bb205b8abe036d955d0eb011ddb7f14a81e6fd0f18893731c457c1b5bd96754683f4c3d80d9a5585ddecaa53cdf84e0b3d68f7 languageName: node linkType: hard @@ -317,9 +437,9 @@ __metadata: linkType: hard "binary-extensions@npm:^2.0.0": - version: 2.2.0 - resolution: "binary-extensions@npm:2.2.0" - checksum: 10c0/d73d8b897238a2d3ffa5f59c0241870043aa7471335e89ea5e1ff48edb7c2d0bb471517a3e4c5c3f4c043615caa2717b5f80a5e61e07503d51dc85cb848e665d + version: 2.3.0 + resolution: "binary-extensions@npm:2.3.0" + checksum: 10c0/75a59cafc10fb12a11d510e77110c6c7ae3f4ca22463d52487709ca7f18f69d886aa387557cc9864fbdb10153d0bdb4caacabf11541f55e89ed6e18d12ece2b5 languageName: node linkType: hard @@ -359,12 +479,12 @@ __metadata: languageName: node linkType: hard -"braces@npm:^3.0.2, braces@npm:~3.0.2": - version: 3.0.2 - resolution: "braces@npm:3.0.2" +"braces@npm:^3.0.3, braces@npm:~3.0.2": + version: 3.0.3 + resolution: "braces@npm:3.0.3" dependencies: - fill-range: "npm:^7.0.1" - checksum: 10c0/321b4d675791479293264019156ca322163f02dc06e3c4cab33bb15cd43d80b51efef69b0930cfde3acd63d126ebca24cd0544fa6f261e093a0fb41ab9dda381 + fill-range: "npm:^7.1.1" + checksum: 10c0/7c6dfd30c338d2997ba77500539227b9d1f85e388a5f43220865201e407e076783d0881f2d297b9f80951b4c957fcf0b51c1d2d24227631643c3f7c284b0aa04 languageName: node linkType: hard @@ -399,9 +519,9 @@ __metadata: linkType: hard "callsites@npm:^4.0.0": - version: 4.1.0 - resolution: "callsites@npm:4.1.0" - checksum: 10c0/91700844127a6dcd4792d231a12dd8e9ec10525eb9962180a8558417d7e3f443e52a4f14746ad2838eaf14f79431ee1539d13bd188da280f720a06a91bd1157a + version: 4.2.0 + resolution: "callsites@npm:4.2.0" + checksum: 10c0/8f7e269ec09fc0946bb22d838a8bc7932e1909ab4a833b964749f4d0e8bdeaa1f253287c4f911f61781f09620b6925ccd19a5ea4897489c4e59442c660c312a3 languageName: node linkType: hard @@ -422,8 +542,8 @@ __metadata: linkType: hard "chokidar@npm:^3.5.3": - version: 3.5.3 - resolution: "chokidar@npm:3.5.3" + version: 3.6.0 + resolution: "chokidar@npm:3.6.0" dependencies: anymatch: "npm:~3.1.2" braces: "npm:~3.0.2" @@ -436,7 +556,7 @@ __metadata: dependenciesMeta: fsevents: optional: true - checksum: 10c0/1076953093e0707c882a92c66c0f56ba6187831aa51bb4de878c1fec59ae611a3bf02898f190efec8e77a086b8df61c2b2a3ea324642a0558bdf8ee6c5dc9ca1 + checksum: 10c0/8361dcd013f2ddbe260eacb1f3cb2f2c6f2b0ad118708a343a5ed8158941a39cb8fb1d272e0f389712e74ee90ce8ba864eece9e0e62b9705cb468a2f6d917462 languageName: node linkType: hard @@ -662,9 +782,9 @@ __metadata: linkType: hard "emittery@npm:^1.0.1": - version: 1.0.1 - resolution: "emittery@npm:1.0.1" - checksum: 10c0/2587f2f42bb5e004ba1cde61352d2151f4dd4f29eb79ad36f82e200da2faec9742d7bfca1492a024d60396e001e4b07d9b2b9c43be33547ff751ba8ff87c42ce + version: 1.0.3 + resolution: "emittery@npm:1.0.3" + checksum: 10c0/91605d044f3891dd1f8ab731aeb94b520488b21e707f7064dcbcf5303bac3b4e7133dfa23c343ede1fc970340bd78a9b1aed522b805bc15104606bba630dd71e languageName: node linkType: hard @@ -715,9 +835,9 @@ __metadata: linkType: hard "escalade@npm:^3.1.1": - version: 3.1.1 - resolution: "escalade@npm:3.1.1" - checksum: 10c0/afd02e6ca91ffa813e1108b5e7756566173d6bc0d1eb951cb44d6b21702ec17c1cf116cfe75d4a2b02e05acb0b808a7a9387d0d1ca5cf9c04ad03a8445c3e46d + version: 3.2.0 + resolution: "escalade@npm:3.2.0" + checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65 languageName: node linkType: hard @@ -786,6 +906,15 @@ __metadata: languageName: node linkType: hard +"fast-check@npm:^3.0.0": + version: 3.22.0 + resolution: "fast-check@npm:3.22.0" + dependencies: + pure-rand: "npm:^6.1.0" + checksum: 10c0/15c70f83df655f9bdcec4f8ed7e3207a933bf6e22c220a4fafc7ea17a28a009bc5d0a85588689f5726e3514796745cb5b35e7295ce469ac286992548fd55cc1d + languageName: node + linkType: hard + "fast-diff@npm:^1.2.0": version: 1.3.0 resolution: "fast-diff@npm:1.3.0" @@ -807,11 +936,11 @@ __metadata: linkType: hard "fastq@npm:^1.6.0": - version: 1.15.0 - resolution: "fastq@npm:1.15.0" + version: 1.17.1 + resolution: "fastq@npm:1.17.1" dependencies: reusify: "npm:^1.0.4" - checksum: 10c0/5ce4f83afa5f88c9379e67906b4d31bc7694a30826d6cc8d0f0473c966929017fda65c2174b0ec89f064ede6ace6c67f8a4fe04cef42119b6a55b0d465554c24 + checksum: 10c0/1095f16cea45fb3beff558bb3afa74ca7a9250f5a670b65db7ed585f92b4b48381445cd328b3d87323da81e43232b5d5978a8201bde84e0cd514310f1ea6da34 languageName: node linkType: hard @@ -841,12 +970,12 @@ __metadata: languageName: node linkType: hard -"fill-range@npm:^7.0.1": - version: 7.0.1 - resolution: "fill-range@npm:7.0.1" +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" dependencies: to-regex-range: "npm:^5.0.1" - checksum: 10c0/7cdad7d426ffbaadf45aeb5d15ec675bbd77f7597ad5399e3d2766987ed20bda24d5fac64b3ee79d93276f5865608bb22344a26b9b1ae6c4d00bd94bf611623f + checksum: 10c0/b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018 languageName: node linkType: hard @@ -1040,9 +1169,9 @@ __metadata: linkType: hard "ignore@npm:^5.2.4": - version: 5.3.0 - resolution: "ignore@npm:5.3.0" - checksum: 10c0/dc06bea5c23aae65d0725a957a0638b57e235ae4568dda51ca142053ed2c352de7e3bc93a69b2b32ac31966a1952e9a93c5ef2e2ab7c6b06aef9808f6b55b571 + version: 5.3.2 + resolution: "ignore@npm:5.3.2" + checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 languageName: node linkType: hard @@ -1346,12 +1475,12 @@ __metadata: linkType: hard "micromatch@npm:^4.0.4": - version: 4.0.5 - resolution: "micromatch@npm:4.0.5" + version: 4.0.8 + resolution: "micromatch@npm:4.0.8" dependencies: - braces: "npm:^3.0.2" + braces: "npm:^3.0.3" picomatch: "npm:^2.3.1" - checksum: 10c0/3d6505b20f9fa804af5d8c596cb1c5e475b9b0cd05f652c5b56141cf941bd72adaeb7a436fda344235cef93a7f29b7472efc779fcdb83b478eab0867b95cdeff + checksum: 10c0/166fa6eb926b9553f32ef81f5f531d27b4ce7da60e5baf8c021d043b27a388fb95e46a8038d5045877881e673f8134122b59624d5cecbd16eb50a42e7a6b5ca8 languageName: node linkType: hard @@ -1790,6 +1919,13 @@ __metadata: languageName: node linkType: hard +"pure-rand@npm:^6.1.0": + version: 6.1.0 + resolution: "pure-rand@npm:6.1.0" + checksum: 10c0/1abe217897bf74dcb3a0c9aba3555fe975023147b48db540aa2faf507aee91c03bf54f6aef0eb2bf59cc259a16d06b28eca37f0dc426d94f4692aeff02fb0e65 + languageName: node + linkType: hard + "queue-microtask@npm:^1.2.2": version: 1.2.3 resolution: "queue-microtask@npm:1.2.3" @@ -1873,6 +2009,8 @@ __metadata: resolution: "root-workspace-0b6124@workspace:." dependencies: "@agoric/synthetic-chain": "npm:^0.3.0" + "@endo/init": "npm:^1.1.5" + "@endo/marshal": "npm:^1.5.4" ava: "npm:^5.3.1" better-sqlite3: "npm:^9.6.0" execa: "npm:^9.3.1" @@ -1902,7 +2040,16 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.2, semver@npm:^7.3.5": +"semver@npm:^7.3.2": + version: 7.6.3 + resolution: "semver@npm:7.6.3" + bin: + semver: bin/semver.js + checksum: 10c0/88f33e148b210c153873cb08cfe1e281d518aaa9a666d4d148add6560db5cd3c582f3a08ccb91f38d5f379ead256da9931234ed122057f40bb5766e65e58adaf + languageName: node + linkType: hard + +"semver@npm:^7.3.5": version: 7.5.4 resolution: "semver@npm:7.5.4" dependencies: @@ -1922,6 +2069,15 @@ __metadata: languageName: node linkType: hard +"ses@npm:^1.9.0": + version: 1.9.0 + resolution: "ses@npm:1.9.0" + dependencies: + "@endo/env-options": "npm:^1.1.7" + checksum: 10c0/356f9601b04a87f33403a15fc627caf0c649d86d8d7ee1f4b3c75b947ab05c31b254c94c0aa26e9904862787c73950d5a60f3435deebe5dba23017e20c40b0cb + languageName: node + linkType: hard + "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -2323,9 +2479,9 @@ __metadata: linkType: hard "yocto-queue@npm:^1.0.0": - version: 1.0.0 - resolution: "yocto-queue@npm:1.0.0" - checksum: 10c0/856117aa15cf5103d2a2fb173f0ab4acb12b4b4d0ed3ab249fdbbf612e55d1cadfd27a6110940e24746fb0a78cf640b522cc8bca76f30a3b00b66e90cf82abe0 + version: 1.1.1 + resolution: "yocto-queue@npm:1.1.1" + checksum: 10c0/cb287fe5e6acfa82690acb43c283de34e945c571a78a939774f6eaba7c285bacdf6c90fbc16ce530060863984c906d2b4c6ceb069c94d1e0a06d5f2b458e2a92 languageName: node linkType: hard diff --git a/a3p-integration/proposals/z:acceptance/governance.test.js b/a3p-integration/proposals/z:acceptance/governance.test.js new file mode 100644 index 00000000000..ef8754c8dfe --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/governance.test.js @@ -0,0 +1,80 @@ +import test from 'ava'; +import '@endo/init'; +import { GOV1ADDR, GOV2ADDR, GOV3ADDR } from '@agoric/synthetic-chain'; +import { governanceDriver, walletUtils, waitUntil } from './test-lib/index.js'; +import { getLastUpdate } from './test-lib/wallet.js'; + +const governanceAddresses = [GOV1ADDR, GOV2ADDR, GOV3ADDR]; + +test.serial( + 'economic committee can make governance proposal and vote on it', + async t => { + const { readLatestHead } = walletUtils; + + /** @type {any} */ + const instance = await readLatestHead(`published.agoricNames.instance`); + const instances = Object.fromEntries(instance); + + /** @type {any} */ + const wallet = await readLatestHead(`published.wallet.${GOV1ADDR}.current`); + const usedInvitations = wallet.offerToUsedInvitation; + + const charterInvitation = usedInvitations.find( + v => + v[1].value[0].instance.getBoardId() === + instances.econCommitteeCharter.getBoardId(), + ); + + const committeeInvitation = usedInvitations.find( + v => + v[1].value[0].instance.getBoardId() === + instances.economicCommittee.getBoardId(), + ); + + t.log('proposing on param change'); + const params = { + ChargingPeriod: 400n, + }; + const path = { paramPath: { key: 'governedParams' } }; + + await governanceDriver.proposeVaultDirectorParamChange( + GOV1ADDR, + params, + path, + charterInvitation[0], + ); + + const questionUpdate = await getLastUpdate(GOV1ADDR, walletUtils); + t.like(questionUpdate, { + status: { numWantsSatisfied: 1 }, + }); + + t.log('Voting on param change'); + await Promise.all( + governanceAddresses.map(address => + governanceDriver.voteOnProposedChanges(address, committeeInvitation[0]), + ), + ); + + const voteUpdates = await Promise.all( + governanceAddresses.map(address => getLastUpdate(address, walletUtils)), + ); + voteUpdates.forEach(voteUpdate => { + t.like(voteUpdate, { + status: { numWantsSatisfied: 1 }, + }); + }); + + /** @type {any} */ + const latestQuestion = await readLatestHead( + 'published.committees.Economic_Committee.latestQuestion', + ); + await waitUntil(latestQuestion.closingRule.deadline); + + t.log('check if latest outcome is correct'); + const latestOutcome = await readLatestHead( + 'published.committees.Economic_Committee.latestOutcome', + ); + t.like(latestOutcome, { outcome: 'win' }); + }, +); diff --git a/a3p-integration/proposals/z:acceptance/package.json b/a3p-integration/proposals/z:acceptance/package.json index a5910e5ded6..9004540f415 100644 --- a/a3p-integration/proposals/z:acceptance/package.json +++ b/a3p-integration/proposals/z:acceptance/package.json @@ -14,6 +14,7 @@ "@endo/errors": "^1.2.2", "@endo/far": "^1.1.5", "@endo/init": "^1.1.4", + "@endo/marshal": "^1.5.3", "ava": "^6.1.2", "execa": "^9.3.1", "tsx": "^4.17.0" diff --git a/a3p-integration/proposals/z:acceptance/test-lib/governance.js b/a3p-integration/proposals/z:acceptance/test-lib/governance.js new file mode 100644 index 00000000000..4019b617910 --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/test-lib/governance.js @@ -0,0 +1,124 @@ +import { agops, agoric, executeOffer } from '@agoric/synthetic-chain'; +import { makeRpcUtils } from './rpc.js'; + +export const makeGovernanceDriver = async (fetch, networkConfig) => { + const { readLatestHead, marshaller } = await makeRpcUtils( + { fetch }, + networkConfig, + ); + const generateVoteOffer = async previousOfferId => { + const id = `propose-${Date.now()}`; + + /** + * @type {object} + */ + const latestQuestionRecord = await readLatestHead( + 'published.committees.Economic_Committee.latestQuestion', + ); + + const chosenPositions = [latestQuestionRecord.positions[0]]; + const body = { + method: 'executeOffer', + offer: { + id, + invitationSpec: { + invitationMakerName: 'makeVoteInvitation', + previousOffer: previousOfferId, + source: 'continuing', + invitationArgs: harden([ + chosenPositions, + latestQuestionRecord.questionHandle, + ]), + }, + proposal: {}, + }, + }; + + const capData = marshaller.toCapData(harden(body)); + return JSON.stringify(capData); + }; + const voteOnProposedChanges = async (address, committeeAcceptOfferId) => { + await null; + const offerId = + committeeAcceptOfferId || + (await agops.ec( + 'find-continuing-id', + '--for', + 'Voter0', + '--from', + address, + )); + + return executeOffer(address, generateVoteOffer(offerId)); + }; + const generateVaultDirectorParamChange = async ( + previousOfferId, + voteDur, + params, + paramsPath, + ) => { + const voteDurSec = BigInt(voteDur); + const toSec = ms => BigInt(Math.round(ms / 1000)); + + const id = `propose-${Date.now()}`; + const deadline = toSec(Date.now()) + voteDurSec; + + const a = await agoric.follow( + '-lF', + ':published.agoricNames.instance', + '-o', + 'text', + ); + const instance = Object.fromEntries(marshaller.fromCapData(JSON.parse(a))); + assert(instance.VaultFactory); + + const body = { + method: 'executeOffer', + offer: { + id, + invitationSpec: { + invitationMakerName: 'VoteOnParamChange', + previousOffer: previousOfferId, + source: 'continuing', + }, + offerArgs: { + deadline, + instance: instance.VaultFactory, + params, + path: paramsPath, + }, + proposal: {}, + }, + }; + + const capData = marshaller.toCapData(harden(body)); + return JSON.stringify(capData); + }; + const proposeVaultDirectorParamChange = async ( + address, + params, + path, + charterAcceptOfferId, + ) => { + await null; + const offerId = + charterAcceptOfferId || + (await agops.ec( + 'find-continuing-id', + '--for', + `${'charter\\ member\\ invitation'}`, + '--from', + address, + )); + + return executeOffer( + address, + generateVaultDirectorParamChange(offerId, 10, params, path), + ); + }; + + return { + voteOnProposedChanges, + proposeVaultDirectorParamChange, + }; +}; diff --git a/a3p-integration/proposals/z:acceptance/test-lib/index.js b/a3p-integration/proposals/z:acceptance/test-lib/index.js index 0c6fffa980a..0284a5953be 100644 --- a/a3p-integration/proposals/z:acceptance/test-lib/index.js +++ b/a3p-integration/proposals/z:acceptance/test-lib/index.js @@ -1,6 +1,7 @@ /* global fetch setTimeout */ import { execFileSync } from 'child_process'; import { makeWalletUtils } from './wallet.js'; +import { makeGovernanceDriver } from './governance.js'; export const networkConfig = { rpcAddrs: ['http://0.0.0.0:26657'], @@ -20,3 +21,14 @@ export const walletUtils = await makeWalletUtils( { delay, execFileSync, fetch }, networkConfig, ); + +// eslint-disable-next-line @jessie.js/safe-await-separator -- buggy version +export const governanceDriver = await makeGovernanceDriver( + fetch, + networkConfig, +); + +export const waitUntil = async timestamp => { + const timeDelta = Math.floor(Date.now() / 1000) - Number(timestamp); + await delay(timeDelta); +}; diff --git a/a3p-integration/proposals/z:acceptance/test.sh b/a3p-integration/proposals/z:acceptance/test.sh index f9982b31916..6508e033b5c 100755 --- a/a3p-integration/proposals/z:acceptance/test.sh +++ b/a3p-integration/proposals/z:acceptance/test.sh @@ -10,6 +10,9 @@ yarn ava initial.test.js # XXX some of these tests have path dependencies so no globs yarn ava core-eval.test.js +echo ACCEPTANCE TESTING governance +yarn ava governance.test.js + npm install -g tsx scripts/test-vaults.mts diff --git a/a3p-integration/proposals/z:acceptance/yarn.lock b/a3p-integration/proposals/z:acceptance/yarn.lock index 72977f2a884..5cd3b8df234 100644 --- a/a3p-integration/proposals/z:acceptance/yarn.lock +++ b/a3p-integration/proposals/z:acceptance/yarn.lock @@ -2516,6 +2516,7 @@ __metadata: "@endo/errors": "npm:^1.2.2" "@endo/far": "npm:^1.1.5" "@endo/init": "npm:^1.1.4" + "@endo/marshal": "npm:^1.5.3" ava: "npm:^6.1.2" execa: "npm:^9.3.1" tsx: "npm:^4.17.0" diff --git a/golang/cosmos/app/upgrade.go b/golang/cosmos/app/upgrade.go index 12cd6eb4a77..cd56b5a5e3d 100644 --- a/golang/cosmos/app/upgrade.go +++ b/golang/cosmos/app/upgrade.go @@ -92,6 +92,7 @@ func unreleasedUpgradeHandler(app *GaiaApp, targetUpgrade string) func(sdk.Conte // Each CoreProposalStep runs sequentially, and can be constructed from // one or more modules executing in parallel within the step. CoreProposalSteps = []vm.CoreProposalStep{ + vm.CoreProposalStepForModules("@agoric/builders/scripts/inter-protocol/replace-electorate-core.js"), vm.CoreProposalStepForModules( // Upgrade to new liveslots for repaired vow usage. "@agoric/builders/scripts/vats/upgrade-orch-core.js", diff --git a/packages/builders/scripts/inter-protocol/replace-electorate-core.js b/packages/builders/scripts/inter-protocol/replace-electorate-core.js index 1db1ec482fc..60724565d71 100644 --- a/packages/builders/scripts/inter-protocol/replace-electorate-core.js +++ b/packages/builders/scripts/inter-protocol/replace-electorate-core.js @@ -16,25 +16,6 @@ import { makeHelpers } from '@agoric/deploy-script-support'; import { getManifestForReplaceAllElectorates } from '@agoric/inter-protocol/src/proposals/replaceElectorate.js'; -/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */ -export const defaultProposalBuilder = async ({ publishRef, install }, opts) => { - return harden({ - sourceSpec: '@agoric/inter-protocol/src/proposals/replaceElectorate.js', - getManifestCall: [ - getManifestForReplaceAllElectorates.name, - { - ...opts, - economicCommitteeRef: publishRef( - install( - '@agoric/governance/src/committee.js', - '../bundles/bundle-committee.js', - ), - ), - }, - ], - }); -}; - const configurations = { MAINNET: { committeeName: 'Economic Committee', @@ -93,12 +74,35 @@ const configurations = { }, }; +/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */ +export const defaultProposalBuilder = async ({ publishRef, install }, opts) => { + const variant = 'A3P_INTEGRATION'; + const config = configurations[variant]; + console.log('fraz 2'); + return harden({ + sourceSpec: '@agoric/inter-protocol/src/proposals/replaceElectorate.js', + getManifestCall: [ + getManifestForReplaceAllElectorates.name, + { + ...config, + economicCommitteeRef: publishRef( + install( + '@agoric/governance/src/committee.js', + '../bundles/bundle-committee.js', + ), + ), + }, + ], + }); +}; + const { keys } = Object; const Usage = `agoric run replace-electorate-core.js ${keys(configurations).join(' | ')}`; export default async (homeP, endowments) => { const { scriptArgs } = endowments; - const variant = scriptArgs?.[0]; + const variant = 'A3P_INTEGRATION'; const config = configurations[variant]; + console.log('fraz 1'); if (!config) { console.error(Usage); process.exit(1);