Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: a docker test for the zoe/zcf upgrade #8018

Merged
merged 1 commit into from
Jul 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/deployment/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
4 changes: 4 additions & 0 deletions packages/deployment/upgrade-test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,8 @@ build_test: $(TARGET)
run:
docker run --rm -it -e "DEST=1" -e "TMUX_USE_CC=$(tmuxCC)" -p 26656:26656 -p 26657:26657 -p 1317:1317 --entrypoint "/usr/src/agoric-sdk/upgrade-test-scripts/start_to_to.sh" -v "$${PWD}:/workspace" $(REPOSITORY):$(dockerLabel)

run_bash:
docker run --rm -it -e "DEST=1" -p 26656:26656 -p 26657:26657 -p 1317:1317\
--entrypoint "/bin/bash" -v "$${PWD}:/workspace" $(REPOSITORY):$(dockerLabel)

.PHONY: local_sdk agoric-upgrade-7-2 agoric-upgrade-8 agoric-upgrade-8-1 agoric-upgrade-9 agoric-upgrade-10 agoric-upgrade-11 build build_test run
Original file line number Diff line number Diff line change
Expand Up @@ -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
dckc marked this conversation as resolved.
Show resolved Hide resolved
# Pre-steps:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

helpful docs

# * 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()"
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// @ts-no-check
/* global E */

// to turn on ts-check:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get it. Why disable ts-check if this is all it takes to enable it? Oh, does the import fail at runtime? if that's it then please enable ts-check and do a type-only import.

/** @typedef {import('@endo/far').E} E */

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dckc I'm just cargo-culting here. What's your advice on best practices?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type-only import

TIL. Nifty.

But at runtime, the string import( cannot occur anywhere in the script, even in comments. See rejectImportExpressions

Conservatively reject the source text if it may contain a dynamic
import expression. To reject without parsing, rejectImportExpressions will
also reject some other text as well.

Copy link
Member

@dckc dckc Jul 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh... this import( limitation is another thing that's addressed by the "cadillac method", using writeCoreProposal from @agoric/deploy-script-support:

export const defangEvaluableCode = code =>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// Xmport { E } from '@endo/far';

const PROBER_BUNDLE_ID =
'b1-f4386f80814847369ad2b2135599d28f3658b0edff55cb6acc45a9a5a25b8bdb301b65a3c8fee17d569bcf724008786c55c6ff025c50959ffd1a20088926df8c';

console.info('running zcf prober');

const sub = (a, v) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens if you import AmountMath?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AIUI, imports aren't supported in core-eval proposals.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a mechanism to support imports. You used it in #7969: packages/vats/src/proposals/zcf-proposal.js starts with import { E } from '@endo/far';.

But it's a complex mechanism, and E is in the environment of a core-eval script even without that import. I tend to do a certain amount of copy-and-paste before I go for the whole writeCoreProposal thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend to do a certain amount of copy-and-paste before I go for the whole writeCoreProposal thing.

@dckc I'm not positive how to interpret this. Should I change something here?

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;
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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???
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"consume": {
"vatStore": true,
"vatAdminSvc": true,
"zoe": true,
"chainStorage": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// to turn on ts-check:
/* global E */

// import { E } from "@endo/far";

const ZCF_BUNDLE_ID =
'b1-3781ce16d40590a41588a472795d2487dbdd9c5f055ac9a82ff52a872cf24f1eb35c6f45d248bcbe13c12d2c1356aecaf5e81b73155ab109499f285ef83fdfd9';
const ZOE_BUNDLE_ID =
'b1-51ffc8e388df8dff7d16b670f5c2c5a2de51f23b7a9a411e90eb222c4a673b3845db2bd925bbf5f9e2bff5fb40e65aa2d366f45c186dd81d0f1517d456b8de58';

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;

This file was deleted.

This file was deleted.

1 change: 1 addition & 0 deletions packages/vats/test/bootstrapTests/drivers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
2 changes: 1 addition & 1 deletion packages/vats/test/bootstrapTests/test-zcf-upgrade.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down Expand Up @@ -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
Expand Down
11 changes: 10 additions & 1 deletion packages/vats/test/bootstrapTests/zcfProbe.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Loading