diff --git a/packages/deployment/package.json b/packages/deployment/package.json index f30db2efbad8..f0d20e1f1308 100644 --- a/packages/deployment/package.json +++ b/packages/deployment/package.json @@ -22,6 +22,7 @@ "@agoric/assert": "^0.6.0", "@endo/init": "^0.5.57", "@endo/marshal": "^0.8.6", + "better-sqlite3": "^8.2.0", "chalk": "^5.2.0", "deterministic-json": "^1.0.5", "inquirer": "^8.2.2", diff --git a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/actions.sh b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/actions.sh index c12c5ad44573..144b9a1d220e 100644 --- a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/actions.sh +++ b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/actions.sh @@ -3,7 +3,63 @@ . ./upgrade-test-scripts/env_setup.sh # CWD is agoric-sdk -here=./upgrade-test-scripts/agoric-upgrade-11 +upgrade11=./upgrade-test-scripts/agoric-upgrade-11 -# run zoe thru "null upgrade" -$here/zoe-upgrade/zoe-upgrade-driver.sh +# Pre-steps: +# * fill Wallets +# * build and install bundles +# * create instance of prober contract and run expecting no atomicRearrange +# +# Action: +# * upgrade Zoe and ZCF +# +# Finish +# * create instance of prober contract and run expecting to see atomicRearrange + +yarn --silent bundle-source --cache-json /tmp packages/zoe/src/contractFacet/vatRoot.js Zcf-upgrade +yarn --silent bundle-source --cache-json /tmp packages/vats/src/vat-zoe.js Zoe-upgrade +yarn --silent bundle-source --cache-json /tmp packages/vats/test/bootstrapTests/zcfProbe.js prober-contract + +echo +++ checking Zoe/Zcf hashes +++ +ZCF_HASH=`jq -r .endoZipBase64Sha512 /tmp/bundle-Zcf-upgrade.json` +ZOE_HASH=`jq -r .endoZipBase64Sha512 /tmp/bundle-Zoe-upgrade.json` +echo bundle-Zcf-upgrade.json $ZCF_HASH +grep $ZCF_HASH $upgrade11/zoe-full-upgrade/zcf-upgrade-script.js || exit 1 +echo bundle-Zoe-upgrade.json $ZOE_HASH +grep $ZOE_HASH $upgrade11/zoe-full-upgrade/zcf-upgrade-script.js || exit 1 + +echo +++ prober hash +++ +PROBER_HASH=`jq -r .endoZipBase64Sha512 /tmp/bundle-prober-contract.json` +echo bundle-prober-contract.json $PROBER_HASH +grep $PROBER_HASH $upgrade11/zoe-full-upgrade/run-prober-script.js || exit 1 + +echo +++++ fill wallet +++++ +agd tx bank send validator $GOV1ADDR 12340000000${ATOM_DENOM} --from validator --chain-id agoriclocal --keyring-backend test --yes +agops vaults open --wantMinted 10000 --giveCollateral 2000 > wantIST +agops perf satisfaction --executeOffer wantIST --from gov1 --keyring-backend test + + +echo +++++ install bundles +++++ +for f in /tmp/bundle-{Z*-upgrade,prober-contract}.json; do + echo installing $f + agd tx swingset install-bundle "@$f" \ + --from gov1 --keyring-backend=test --gas=auto \ + --chain-id=agoriclocal -bblock --yes +done + + +echo +++++ Run prober first time +++++ +$upgrade11/zoe-full-upgrade/run-prober.sh +test_val "$(agd query vstorage data published.prober-asid9a -o jsonlines | jq -r '.value' | jq -r '.values[0]')" "false" "Prober calling zcf.atomicReallocate()" + + +# upgrade zoe to a version that can change which ZCF is installed; tell Zoe to +# use a new version of ZCF. THIS MATCHES THE UPGRADE OF THE LIVE CHAIN +echo +++++ upgrade Zoe and ZCF +++++ +$upgrade11/zoe-full-upgrade/zcf-upgrade-driver.sh + + +echo +++++ Run prober second time +++++ +# Re-run prober test and expect internal atomicRearrange. +$upgrade11/zoe-full-upgrade/run-prober.sh +test_val "$(agd query vstorage data published.prober-asid9a -o jsonlines | jq -r '.value' | jq -r '.values[0]')" "true" "Prober called zcf.atomicReallocate()" diff --git a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/pre_test.sh b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/pre_test.sh index ba0560844fef..509b91d387cf 100755 --- a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/pre_test.sh +++ b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/pre_test.sh @@ -6,7 +6,7 @@ echo Wait for upgrade to settle waitForBlock 5 # CWD is agoric-sdk -here=./upgrade-test-scripts/agoric-upgrade-11 +upgradeScripts=packages/deployment/upgrade-test/upgrade-test-scripts # zoe vat is at incarnation 0 -test_val "$(yarn --silent node $here/zoe-upgrade/vat-status.mjs zoe)" "0" "zoe vat incarnation" +test_val "$(yarn --silent node $upgradeScripts/vat-status.mjs zoe)" "0" "zoe vat incarnation" diff --git a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/test.sh b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/test.sh index 7c6032c55865..e994151ba507 100755 --- a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/test.sh +++ b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/test.sh @@ -6,7 +6,7 @@ echo Wait for actions to settle waitForBlock 2 # CWD is agoric-sdk -here=./upgrade-test-scripts/agoric-upgrade-11 +upgradeScripts=packages/deployment/upgrade-test/upgrade-test-scripts # zoe vat is at incarnation 1 -test_val "$(yarn --silent node $here/zoe-upgrade/vat-status.mjs zoe)" "1" "zoe vat incarnation" +test_val "$(yarn --silent node $upgradeScripts/vat-status.mjs zoe)" "1" "zoe vat incarnation" diff --git a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade/run-prober-script.js b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade/run-prober-script.js new file mode 100644 index 000000000000..883b49399f5c --- /dev/null +++ b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade/run-prober-script.js @@ -0,0 +1,96 @@ +// @ts-no-check +/* global E */ + +// to turn on ts-check: +// Xmport { E } from '@endo/far'; + +const PROBER_BUNDLE_ID = + 'b1-4487fd5e18a225a77ca882890d8faae905ca46fda617877f6e1f969e624db3edf0a4f490d735963f025eb3d772840caec157986f4367c0f66385d919f3f5a56c'; + +console.info('running zcf prober'); + +const sub = (a, v) => { + return { brand: a.brand, value: a.value - v }; +}; + +const probeReallocation = async ( + value, + payment, + creatorFacet, + zoe, + ducatIssuer, +) => { + const stagingInv = await E(creatorFacet).makeProbeStagingInvitation(); + + const stagingSeat = await E(zoe).offer( + stagingInv, + { give: { Ducats: value } }, + { Ducats: payment }, + ); + const helperPayments = await E(stagingSeat).getPayouts(); + + const helperInv = await E(creatorFacet).makeProbeHelperInvitation(); + const helperSeat = await E(zoe).offer( + helperInv, + { give: { Ducats: sub(value, 1n) } }, + { Ducats: helperPayments.Ducats }, + ); + const internalPayments = await E(helperSeat).getPayouts(); + const ducatAmount = await E(ducatIssuer).getAmountOf(internalPayments.Ducats); + + const internalInv = await E(creatorFacet).makeProbeInternalInvitation(); + const internalSeat = await E(zoe).offer( + internalInv, + { give: { Ducats: ducatAmount } }, + { Ducats: internalPayments.Ducats }, + ); + const leftoverPayments = await E(internalSeat).getPayouts(); + + return { + stagingResult: await E(stagingSeat).getOfferResult(), + helperResult: await E(helperSeat).getOfferResult(), + internalResult: await E(internalSeat).getOfferResult(), + leftoverPayments, + }; +}; + +/* + * Test a full upgrade of Zoe and ZCF. + * This will include a change to Zoe's code, and a call to Zoe to change the ZCF + * code that will get used for new and upgraded contracts. + */ +const runProber = async powers => { + console.info('install prober'); + const { + consume: { zoe, chainStorage }, + } = powers; + + const installation = await E(zoe).installBundleID(PROBER_BUNDLE_ID); + const storageNode = await E(chainStorage).makeChildNode('prober-asid9a'); + + const { instance, creatorFacet } = await E(zoe).startInstance( + installation, + undefined, + undefined, + { storageNode }, + 'probe', + ); + + const issuers = await E(zoe).getIssuers(instance); + + const faucetInv = await E(creatorFacet).makeFaucetInvitation(); + const seat = await E(zoe).offer(faucetInv); + const payoutDucats = await E(seat).getPayout('Ducats'); + const faucetAmount = await E(issuers.Ducats).getAmountOf(payoutDucats); + + const result1 = await probeReallocation( + faucetAmount, + payoutDucats, + creatorFacet, + zoe, + issuers.Ducats, + ); + console.info('PROBE results', result1); +}; + +runProber; diff --git a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-upgrade/zoe-upgrade-driver.sh b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade/run-prober.sh similarity index 67% rename from packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-upgrade/zoe-upgrade-driver.sh rename to packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade/run-prober.sh index 8f09f7b6c880..02eaa8b51ac3 100755 --- a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-upgrade/zoe-upgrade-driver.sh +++ b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade/run-prober.sh @@ -4,12 +4,12 @@ set -euo pipefail -here='upgrade-test-scripts/agoric-upgrade-11/zoe-upgrade' +here='upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade' agd --chain-id=agoriclocal \ tx gov submit-proposal swingset-core-eval \ - ${here}/zoe-upgrade-permit.json ${here}/zoe-upgrade-script.js \ - --title="Zoe Upgrade" --description="zoe upgrade test" \ + ${here}/zcf-upgrade-permit.json ${here}/run-prober-script.js \ + --title="Run Prober" --description="run prober" \ --deposit=10000000ubld \ --gas=auto --gas-adjustment=1.2 \ --yes -o json --from=validator --keyring-backend=test -b block @@ -18,5 +18,3 @@ agd --chain-id=agoriclocal query gov proposals --output json | \ jq -c '.proposals[] | [.proposal_id,.voting_end_time,.status]'; voteLatestProposalAndWait - -# then tes some stuff??? diff --git a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade/zcf-upgrade-driver.sh b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade/zcf-upgrade-driver.sh new file mode 100755 index 000000000000..023b130f92e9 --- /dev/null +++ b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade/zcf-upgrade-driver.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +. ./upgrade-test-scripts/env_setup.sh + +set -euo pipefail + +# This shows how to upgrade Zoe and ZCF on a running chain. It presumes that +# the bundles for Zoe and ZCF have been installed, and their hashes updated in +# zcf-upgrade-script.js. Instructions for updating the bundles are available +# in ../actions.sh + +here='upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade' + +agd --chain-id=agoriclocal \ + tx gov submit-proposal swingset-core-eval \ + ${here}/zcf-upgrade-permit.json ${here}/zcf-upgrade-script.js \ + --title="Zoe Upgrade" --description="zoe upgrade test" \ + --deposit=10000000ubld \ + --gas=auto --gas-adjustment=1.2 \ + --yes -o json --from=validator --keyring-backend=test -b block + +agd --chain-id=agoriclocal query gov proposals --output json | \ + jq -c '.proposals[] | [.proposal_id,.voting_end_time,.status]'; + +voteLatestProposalAndWait diff --git a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade/zcf-upgrade-permit.json b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade/zcf-upgrade-permit.json new file mode 100644 index 000000000000..b0c4f125baed --- /dev/null +++ b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade/zcf-upgrade-permit.json @@ -0,0 +1,8 @@ +{ + "consume": { + "vatStore": true, + "vatAdminSvc": true, + "zoe": true, + "chainStorage": true + } +} diff --git a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade/zcf-upgrade-script.js b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade/zcf-upgrade-script.js new file mode 100644 index 000000000000..f43bf739516c --- /dev/null +++ b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-full-upgrade/zcf-upgrade-script.js @@ -0,0 +1,33 @@ +// to turn on ts-check: +/* global E */ + +// import { E } from "@endo/far"; + +const ZCF_BUNDLE_ID = + 'b1-102c585d2efe825e0ff17441dcdfc28c1cd83c866ad6497230446d19d0021de88f49f6786b225693ccca1ec913d86309e83094e5a0b0b0da42bc6684d3d7f808'; +const ZOE_BUNDLE_ID = + 'b1-9b02c49613fc09ec8ae9138d6345fa589739c86d7d71044a002080dcc5450583b39b3d4d814924f654474398e23ff459af51f850890fabc109a3106d577732a1'; + +console.info('zoe upgrade: evaluating script'); + +/* + * Test a full upgrade of Zoe and ZCF. + * This will include a change to Zoe's code, and a call to Zoe to change the ZCF + * code that will get used for new and upgraded contracts. + */ +const upgradeZoeAndZcf = async powers => { + console.info('upgradeZoeAndZcf'); + const { + consume: { vatStore, vatAdminSvc }, + } = powers; + + const newZoeBundleCap = await E(vatAdminSvc).getBundleCap(ZOE_BUNDLE_ID); + const { adminNode, root: zoeRoot } = await E(vatStore).get('zoe'); + + await E(adminNode).upgrade(newZoeBundleCap, {}); + + const zoeConfigFacet = await E(zoeRoot).getZoeConfigFacet(); + await E(zoeConfigFacet).updateZcfBundleId(ZCF_BUNDLE_ID); +}; + +upgradeZoeAndZcf; diff --git a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-upgrade/zoe-upgrade-permit.json b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-upgrade/zoe-upgrade-permit.json deleted file mode 100644 index f3bed44c8955..000000000000 --- a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-upgrade/zoe-upgrade-permit.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "consume": { - "vatStore": true, - "vatAdminSvc": true - } -} diff --git a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-upgrade/zoe-upgrade-script.js b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-upgrade/zoe-upgrade-script.js deleted file mode 100644 index 969a1fab8b9f..000000000000 --- a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-upgrade/zoe-upgrade-script.js +++ /dev/null @@ -1,32 +0,0 @@ -// @ts-no-check -/* global E */ - -// to turn on ts-check: -// Xmport { E } from '@endo/far'; - -console.info('zoe upgrade: evaluating script'); - -/** - * Test "upgrading" zoe. - * It's a so-called "null" upgrade, since we don't mean to change the code. - * This (re-)uses the code originally bundled at swingset bootstrap. - * - * @param { BootstrapPowers } powers - */ -const restartZoe = async powers => { - console.info('restartZoe()'); - const { - consume: { vatStore, vatAdminSvc }, - } = powers; - console.info('restartZoe - destructured powers'); - - const bundleName = 'zoe'; - const bundleCap = await E(vatAdminSvc).getNamedBundleCap(bundleName); - const { adminNode } = await E(vatStore).get('zoe'); - console.info('restartZoe', { bundleName, bundleCap, adminNode }); - - const result = await E(adminNode).upgrade(bundleCap, {}); - console.info('restartZoe', { result }); -}; - -restartZoe; diff --git a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-upgrade/vat-status.mjs b/packages/deployment/upgrade-test/upgrade-test-scripts/vat-status.mjs similarity index 100% rename from packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/zoe-upgrade/vat-status.mjs rename to packages/deployment/upgrade-test/upgrade-test-scripts/vat-status.mjs diff --git a/packages/vats/test/bootstrapTests/drivers.js b/packages/vats/test/bootstrapTests/drivers.js index 4cede9cc2263..cfa032deeaa4 100644 --- a/packages/vats/test/bootstrapTests/drivers.js +++ b/packages/vats/test/bootstrapTests/drivers.js @@ -341,6 +341,7 @@ export const makeGovernanceDriver = async ( }; }; +/** @param {SwingsetTestKit} testKit */ export const makeZoeDriver = async testKit => { const { EV } = testKit.runUtils; const zoe = await EV.vat('bootstrap').consumeItem('zoe'); diff --git a/packages/vats/test/bootstrapTests/test-zcf-upgrade.js b/packages/vats/test/bootstrapTests/test-zcf-upgrade.js index bfea74c94525..b2eddd7fa046 100644 --- a/packages/vats/test/bootstrapTests/test-zcf-upgrade.js +++ b/packages/vats/test/bootstrapTests/test-zcf-upgrade.js @@ -92,6 +92,7 @@ const test = anyTest; test.before(async t => { t.context = await makeZoeTestContext(t); }); + test.after.always(t => t.context.shutdown?.()); test('run restart-vats proposal', async t => { @@ -121,7 +122,6 @@ test('run restart-vats proposal', async t => { await EV(coreEvalBridgeHandler).fromBridge(bridgeMessage); }; const source = `${dirname}/${ZCF_PROBE_SRC}`; - const zcfProbeBundle = await bundleSource(source); await controller.validateAndInstallBundle(zcfProbeBundle); // This test self-sufficiently builds all the artifacts it needs. The test in diff --git a/packages/vats/test/bootstrapTests/zcfProbe.js b/packages/vats/test/bootstrapTests/zcfProbe.js index 04d47bb2866b..16ab4fd1fa9f 100644 --- a/packages/vats/test/bootstrapTests/zcfProbe.js +++ b/packages/vats/test/bootstrapTests/zcfProbe.js @@ -53,7 +53,16 @@ export const start = async (zcf, privateArgs, baggage) => { let result; try { atomicRearrange(zcf, harden([[seat, stashSeat, { Ducats: one }]])); - result = true; + + // the helper can fail silently if the most recent version of the + // library calls zcf.atomicRearrange() directly while running with a + // zcf that doesn't yet have atomicRearrange. This can happen when + // the prober bundle is built in a later version and run under + // docker in an earlier version. + result = !AmountMath.isEqual( + originalAlloc, + stashSeat.getCurrentAllocation().Ducats, + ); } catch (e) { result = false; }