diff --git a/a3p-integration/proposals/a:upgrade-next/package.json b/a3p-integration/proposals/a:upgrade-next/package.json index 10ff0918e7fb..d8257ef815fa 100644 --- a/a3p-integration/proposals/a:upgrade-next/package.json +++ b/a3p-integration/proposals/a:upgrade-next/package.json @@ -14,7 +14,8 @@ "license": "Apache-2.0", "dependencies": { "@agoric/synthetic-chain": "^0.0.5-3", - "ava": "^5.3.1" + "ava": "^5.3.1", + "tmp": "0.2.1" }, "scripts": { "agops": "yarn --cwd /usr/src/agoric-sdk/ --silent agops" diff --git a/a3p-integration/proposals/a:upgrade-next/post.test.js b/a3p-integration/proposals/a:upgrade-next/post.test.js index 75e763f5b8f2..c9fe7516c154 100644 --- a/a3p-integration/proposals/a:upgrade-next/post.test.js +++ b/a3p-integration/proposals/a:upgrade-next/post.test.js @@ -1,6 +1,74 @@ +// @ts-check + import test from 'ava'; +import { createRequire } from 'module'; +import { execFileSync } from 'child_process'; +import tmp from 'tmp'; +import { readFile as readFileAmbient, writeFile } from 'fs/promises'; import { getIncarnation } from '@agoric/synthetic-chain/src/lib/vat-status.js'; +import { voteLatestProposalAndWait, waitForBlock } from '@agoric/synthetic-chain/src/lib/commonUpgradeHelpers.js'; +import { agoric } from '@agoric/synthetic-chain/src/lib/cliHelper.js'; +import { makeAgd } from '@agoric/synthetic-chain/src/lib/agd-lib.js'; +import * as env from '@agoric/synthetic-chain/src/lib/constants.js'; + +const nodeRequire = createRequire(import.meta.url); +const asset = { + sendScript: nodeRequire.resolve('./send-script.js'), +}; + +// #region copy-pasta from @agoric/synthetic-chain + +// XXX import from '@agoric/synthetic-chain/src/lib/core-eval-support.js'; + +/** + * @param { Record} record - e.g. { color: 'blue' } + * @returns {string[]} e.g. ['--color', 'blue'] + */ +export const flags = record => { + return Object.entries(record) + .map(([k, v]) => [`--${k}`, v]) + .flat(); +}; + +export const txAbbr = tx => { + const { txhash, code, height, gas_used } = tx; + return { txhash, code, height, gas_used }; +}; + +// XXX overlaps with passCoreEvalProposal from synthetic chain +const passCoreEvalProposal = async (t, opts) => { + const { + agd, + script, + permit, + title, + chainId, + description = 'run some code', + from = 'validator', + deposit = '10000000ubld', + } = opts; + const result = await agd.tx( + [ + 'gov', + 'submit-proposal', + 'swingset-core-eval', + permit, + script, + ...flags({ title, description, deposit }), + ...flags({ gas: 'auto', 'gas-adjustment': '1.2' }), + ], + { from, chainId, yes: true }, + ); + console.log(txAbbr(result)); + t.is(result.code, 0); + + const detail = await voteLatestProposalAndWait(); + console.log(detail.proposal_id, detail.voting_end_time, detail.status); + t.is(detail.status, 'PROPOSAL_STATUS_PASSED'); +}; + +// #endregion test(`Ensure Network Vat was installed`, async t => { const incarnation = await getIncarnation('network'); @@ -19,3 +87,54 @@ test(`Zoe vat was upgraded`, async t => { t.is(incarnation, 1); }); +test.before(async t => { + const readAsset = name => readFileAmbient(asset[name], 'utf-8'); + + const saveToTemp = text => + new Promise((resolve, reject) => + tmp.tmpName((err, path) => { + if (err != null) return reject(err); + return writeFile(path, text).then(() => resolve(path)); + }), + ); + + const agd = makeAgd({ execFileSync }).withOpts({ + keyringBackend: 'test', + }); + + t.context = { env, readAsset, agd, saveToTemp, agoric }; +}); + +test(`provisioning vat was upgraded`, async t => { + const incarnation = await getIncarnation('provisioning'); + + t.is(incarnation, 1); +}); + +test(`send invitation via namesByAddress`, async t => { + const io = t.context; + const template = await io.readAsset('sendScript'); + const addr = io.env.GOV1ADDR; + const code = template.replace('{{ADDRESS}}', addr); + const script = await io.saveToTemp(code); + const permit = await io.saveToTemp('true'); + + const title = `send Add Collateral invitation to ${addr}`; + t.log('proposal:', title); + await passCoreEvalProposal(t, { + agd: io.agd, + script, + permit, + title, + chainId: env.CHAINID, + }); + + await waitForBlock(2); // enough time for invitation to arrive? + const update = await agoric.follow('-lF', `:published.wallet.${addr}`); + t.is(update.updated, 'balance'); + t.notDeepEqual(update.currentAmount.value, []); + t.log('balance value', update.currentAmount.value); + t.log('balance brand', update.currentAmount.brand); + // XXX agoric follow returns brands as strings + t.regex(update.currentAmount.brand, /Invitation/); +}); diff --git a/a3p-integration/proposals/a:upgrade-next/send-script.js b/a3p-integration/proposals/a:upgrade-next/send-script.js new file mode 100644 index 000000000000..f8aaa8822125 --- /dev/null +++ b/a3p-integration/proposals/a:upgrade-next/send-script.js @@ -0,0 +1,25 @@ +// @ts-nocheck +/* global E */ + +/** + * Send a payment by looking up deposit facet via namesByAddress. + * + * see ./post.test.js + * + * @param {BootstrapPowers} powers + */ +const sendIt = async powers => { + const addr = '{{ADDRESS}}'; + const { + consume: { namesByAddress, zoe }, + instance: { + consume: { reserve }, + }, + } = powers; + const pf = E(zoe).getPublicFacet(reserve); + const anInvitation = await E(pf).makeAddCollateralInvitation(); + const addressDepositFacet = E(namesByAddress).lookup(addr, 'depositFacet'); + await E(addressDepositFacet).receive(anInvitation); +}; + +sendIt; diff --git a/a3p-integration/proposals/a:upgrade-next/yarn.lock b/a3p-integration/proposals/a:upgrade-next/yarn.lock index 61b874ddcd80..fd2eb73e3528 100644 --- a/a3p-integration/proposals/a:upgrade-next/yarn.lock +++ b/a3p-integration/proposals/a:upgrade-next/yarn.lock @@ -491,6 +491,16 @@ __metadata: languageName: node linkType: hard +"brace-expansion@npm:^1.1.7": + version: 1.1.11 + resolution: "brace-expansion@npm:1.1.11" + dependencies: + balanced-match: "npm:^1.0.0" + concat-map: "npm:0.0.1" + checksum: 695a56cd058096a7cb71fb09d9d6a7070113c7be516699ed361317aca2ec169f618e28b8af352e02ab4233fb54eb0168460a40dc320bab0034b36ab59aaad668 + languageName: node + linkType: hard + "brace-expansion@npm:^2.0.1": version: 2.0.1 resolution: "brace-expansion@npm:2.0.1" @@ -699,6 +709,13 @@ __metadata: languageName: node linkType: hard +"concat-map@npm:0.0.1": + version: 0.0.1 + resolution: "concat-map@npm:0.0.1" + checksum: c996b1cfdf95b6c90fee4dae37e332c8b6eb7d106430c17d538034c0ad9a1630cb194d2ab37293b1bdd4d779494beee7786d586a50bd9376fd6f7bcc2bd4c98f + languageName: node + linkType: hard + "concordance@npm:^5.0.4": version: 5.0.4 resolution: "concordance@npm:5.0.4" @@ -1101,6 +1118,13 @@ __metadata: languageName: node linkType: hard +"fs.realpath@npm:^1.0.0": + version: 1.0.0 + resolution: "fs.realpath@npm:1.0.0" + checksum: 444cf1291d997165dfd4c0d58b69f0e4782bfd9149fd72faa4fe299e68e0e93d6db941660b37dd29153bf7186672ececa3b50b7e7249477b03fdf850f287c948 + languageName: node + linkType: hard + "fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": version: 2.3.3 resolution: "fsevents@npm:2.3.3" @@ -1174,6 +1198,20 @@ __metadata: languageName: node linkType: hard +"glob@npm:^7.1.3": + version: 7.2.3 + resolution: "glob@npm:7.2.3" + dependencies: + fs.realpath: "npm:^1.0.0" + inflight: "npm:^1.0.4" + inherits: "npm:2" + minimatch: "npm:^3.1.1" + once: "npm:^1.3.0" + path-is-absolute: "npm:^1.0.0" + checksum: 65676153e2b0c9095100fe7f25a778bf45608eeb32c6048cf307f579649bcc30353277b3b898a3792602c65764e5baa4f643714dfbdfd64ea271d210c7a425fe + languageName: node + linkType: hard + "globby@npm:^13.1.4": version: 13.2.2 resolution: "globby@npm:13.2.2" @@ -1279,7 +1317,17 @@ __metadata: languageName: node linkType: hard -"inherits@npm:^2.0.3, inherits@npm:^2.0.4": +"inflight@npm:^1.0.4": + version: 1.0.6 + resolution: "inflight@npm:1.0.6" + dependencies: + once: "npm:^1.3.0" + wrappy: "npm:1" + checksum: 7faca22584600a9dc5b9fca2cd5feb7135ac8c935449837b315676b4c90aa4f391ec4f42240178244b5a34e8bede1948627fda392ca3191522fc46b34e985ab2 + languageName: node + linkType: hard + +"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 @@ -1574,6 +1622,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^3.1.1": + version: 3.1.2 + resolution: "minimatch@npm:3.1.2" + dependencies: + brace-expansion: "npm:^1.1.7" + checksum: 0262810a8fc2e72cca45d6fd86bd349eee435eb95ac6aa45c9ea2180e7ee875ef44c32b55b5973ceabe95ea12682f6e3725cbb63d7a2d1da3ae1163c8b210311 + languageName: node + linkType: hard + "minimatch@npm:^9.0.1": version: 9.0.3 resolution: "minimatch@npm:9.0.3" @@ -1781,7 +1838,7 @@ __metadata: languageName: node linkType: hard -"once@npm:^1.3.1, once@npm:^1.4.0": +"once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0": version: 1.4.0 resolution: "once@npm:1.4.0" dependencies: @@ -1872,6 +1929,13 @@ __metadata: languageName: node linkType: hard +"path-is-absolute@npm:^1.0.0": + version: 1.0.1 + resolution: "path-is-absolute@npm:1.0.1" + checksum: 127da03c82172a2a50099cddbf02510c1791fc2cc5f7713ddb613a56838db1e8168b121a920079d052e0936c23005562059756d653b7c544c53185efe53be078 + languageName: node + linkType: hard + "path-key@npm:^3.1.0": version: 3.1.1 resolution: "path-key@npm:3.1.1" @@ -2072,12 +2136,24 @@ __metadata: languageName: node linkType: hard +"rimraf@npm:^3.0.0": + version: 3.0.2 + resolution: "rimraf@npm:3.0.2" + dependencies: + glob: "npm:^7.1.3" + bin: + rimraf: bin.js + checksum: 9cb7757acb489bd83757ba1a274ab545eafd75598a9d817e0c3f8b164238dd90eba50d6b848bd4dcc5f3040912e882dc7ba71653e35af660d77b25c381d402e8 + languageName: node + linkType: hard + "root-workspace-0b6124@workspace:.": version: 0.0.0-use.local resolution: "root-workspace-0b6124@workspace:." dependencies: "@agoric/synthetic-chain": "npm:^0.0.5-3" ava: "npm:^5.3.1" + tmp: "npm:0.2.1" languageName: unknown linkType: soft @@ -2380,6 +2456,15 @@ __metadata: languageName: node linkType: hard +"tmp@npm:0.2.1": + version: 0.2.1 + resolution: "tmp@npm:0.2.1" + dependencies: + rimraf: "npm:^3.0.0" + checksum: 67607aa012059c9ce697bee820ee51bc0f39b29a8766def4f92d3f764d67c7cf9205d537d24e0cb1ce9685c40d4c628ead010910118ea18348666b5c46ed9123 + languageName: node + linkType: hard + "to-regex-range@npm:^5.0.1": version: 5.0.1 resolution: "to-regex-range@npm:5.0.1" diff --git a/golang/cosmos/app/app.go b/golang/cosmos/app/app.go index a6eab02691e7..1e03970889ef 100644 --- a/golang/cosmos/app/app.go +++ b/golang/cosmos/app/app.go @@ -849,6 +849,8 @@ func unreleasedUpgradeHandler(app *GaiaApp, targetUpgrade string) func(sdk.Conte vm.CoreProposalStepForModules("@agoric/builders/scripts/smart-wallet/build-wallet-factory2-upgrade.js"), // Then, upgrade Zoe and ZCF vm.CoreProposalStepForModules("@agoric/builders/scripts/vats/replace-zoe.js"), + // Then, upgrade the provisioning vat + vm.CoreProposalStepForModules("@agoric/builders/scripts/vats/replace-provisioning.js"), // vm.CoreProposalStepForModules("@agoric/builders/scripts/vats/init-network.js"), }