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

chore(acceptance): upgrade pp's governor #10817

Merged
merged 4 commits into from
Jan 14, 2025
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
42 changes: 29 additions & 13 deletions a3p-integration/proposals/p:upgrade-19/provisionPool.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
* 6c. Try to open a vault WITHOUT provisioning the newly introduced account
* 6d. Observe the new account's address under `published.wallet`
* 7. Same as step 2. Checks manual provision works after null upgrade
*
* Note: We are also upgrading provisionPool's governor to meet https://github.com/Agoric/agoric-sdk/issues/10411.
* The governor's behavior is tested at https://github.com/Agoric/agoric-sdk/blob/master/a3p-integration/proposals/z%3Aacceptance/governance.test.js
*/

import '@endo/init';
Expand All @@ -31,7 +34,6 @@ import {
agd as agdAmbient,
agoric,
getISTBalance,
getDetailsMatchingVats,
GOV1ADDR,
openVault,
ATOM_DENOM,
Expand All @@ -48,6 +50,7 @@ import {
introduceAndProvision,
provision,
} from './test-lib/provision-helpers.js';
import { getIncarnationFromDetails } from './test-lib/utils.js';

const PROVISIONING_POOL_ADDR = 'agoric1megzytg65cyrgzs6fvzxgrcqvwwl7ugpt62346';

Expand All @@ -65,28 +68,41 @@ const ambientAuthority = {
log: console.log,
};

const upgradedVats = ['provisionPool', 'provisionPool-governor'];

test.before(async t => {
const vstorageKit = await makeVstorageKit(
{ fetch },
{ rpcAddrs: ['http://localhost:26657'], chainName: 'agoriclocal' },
);

const currentVatIncarnations = {};
for await (const vatName of upgradedVats) {
currentVatIncarnations[vatName] = await getIncarnationFromDetails(vatName);
}

t.context = {
vstorageKit,
currentVatIncarnations,
};
});

test.serial('upgrade provisionPool', async t => {
// @ts-expect-error casting
const { currentVatIncarnations } = t.context;
console.log(currentVatIncarnations);
await evalBundles(UPGRADE_PP_DIR);

const vatDetailsAfter = await getDetailsMatchingVats('provisionPool');
const { incarnation } = vatDetailsAfter.find(vat =>
vat.vatName.endsWith('provisionPool'),
);
for await (const vatName of upgradedVats) {
const incarnationAfterUpgrade = await getIncarnationFromDetails(vatName);
const previousIncarnation = currentVatIncarnations[vatName];

t.log(vatDetailsAfter);
t.is(incarnation, 1, 'incorrect incarnation');
t.pass();
t.is(
incarnationAfterUpgrade,
previousIncarnation + 1,
`${vatName} does not meet the expected incarnation number`,
);
}
});

test.serial(
Expand Down Expand Up @@ -142,14 +158,14 @@ test.serial(
);

test.serial('null upgrade', async t => {
const incarnationBefore = await getIncarnationFromDetails('provisionPool');

await evalBundles(NULL_UPGRADE_PP_DIR);

const vatDetailsAfter = await getDetailsMatchingVats('provisionPool');
const { incarnation } = vatDetailsAfter.find(vat => vat.vatID === 'v28'); // provisionPool is v28
const incarnationAfter = await getIncarnationFromDetails('provisionPool');

t.log(vatDetailsAfter);
t.is(incarnation, 2, 'incorrect incarnation');
t.pass();
t.log({ incarnationBefore, incarnationAfter });
t.is(incarnationAfter, incarnationBefore + 1, 'incorrect incarnation');
});

test.serial('auto provision', async t => {
Expand Down
16 changes: 16 additions & 0 deletions a3p-integration/proposals/p:upgrade-19/test-lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-env node */
import { makeStargateClient, makeVstorageKit } from '@agoric/client-utils';
import { readFile, writeFile } from 'node:fs/promises';
import { getDetailsMatchingVats } from '@agoric/synthetic-chain';
import { networkConfig } from './index.js';

export const stargateClientP = makeStargateClient(networkConfig, { fetch });
Expand Down Expand Up @@ -64,3 +65,18 @@ export const listVaults = async (addr, { getCurrentWalletRecord }) => {

return vaultStoragePaths;
};

/**
* Copy from https://github.com/Agoric/agoric-sdk/blob/d7031902b5666ba2aec5d049b051a15c5f2ef59b/a3p-integration/proposals/z%3Aacceptance/test-lib/utils.js#L106
* @param {string} vatName
* @returns {Promise<number>}
*/
export const getIncarnationFromDetails = async vatName => {
const matchingVats = await getDetailsMatchingVats(vatName);
const expectedVat = matchingVats.find(
/** @param {{ vatName: string }} vat */
vat => vat.vatName.endsWith(vatName),
);
assert(expectedVat, `No matching Vat was found for ${vatName}`);
return expectedVat.incarnation;
};
123 changes: 52 additions & 71 deletions a3p-integration/proposals/z:acceptance/governance.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
import test from 'ava';

import { GOV1ADDR, GOV2ADDR } from '@agoric/synthetic-chain';
import { makeGovernanceDriver } from './test-lib/governance.js';
import {
makeGovernanceDriver,
runCommitteeElectionParamChange,
} from './test-lib/governance.js';
import { agdWalletUtils } from './test-lib/index.js';
import { upgradeContract } from './test-lib/utils.js';
import { networkConfig } from './test-lib/rpc.js';
Expand All @@ -20,42 +23,14 @@ test.serial(
const params = {
ChargingPeriod: 400n,
};
const path = { paramPath: { key: 'governedParams' } };
t.log('Proposing param change', { params, path });
const instanceName = 'VaultFactory';

await governanceDriver.proposeParamChange(
governanceAddresses[0],
params,
path,
instanceName,
30,
await runCommitteeElectionParamChange(
t,
governanceDriver,
{ instanceName, duration: 30, governanceAddresses, params },
{ getLastUpdate },
);

const questionUpdate = await getLastUpdate(governanceAddresses[0]);
t.log(questionUpdate);
t.like(questionUpdate, {
status: { numWantsSatisfied: 1 },
});

t.log('Voting on param change');
for (const address of governanceAddresses) {
const committeeInvitationForVoter =
await governanceDriver.getCommitteeInvitation(address);

await governanceDriver.voteOnProposedChanges(
address,
committeeInvitationForVoter[0],
);

const voteUpdate = await getLastUpdate(address);
t.log(`${address} voted`);
t.like(voteUpdate, {
status: { numWantsSatisfied: 1 },
});
}

await governanceDriver.waitForElection();
},
);

Expand All @@ -78,7 +53,7 @@ test.serial(
'vaultFactory ChargingPeriod parameter value is not the expected ',
);

await upgradeContract('upgrade-vaultFactory', 'zcf-b1-6c08a-vaultFactory');
await upgradeContract('upgrade-vaultFactory', 'vaultFactory');

const vaultFactoryParamsAfter = await readLatestHead(
'published.vaultFactory.governance',
Expand All @@ -102,38 +77,14 @@ test.serial(
const params = {
PerAccountInitialAmount: { brand: brands.IST, value: 100_000n },
};
const path = { paramPath: { key: 'governedParams' } };
const instanceName = 'provisionPool';

await governanceDriver.proposeParamChange(
governanceAddresses[0],
params,
path,
instanceName,
30,
await runCommitteeElectionParamChange(
t,
governanceDriver,
{ instanceName, duration: 30, governanceAddresses, params },
{ getLastUpdate },
);

const questionUpdate = await getLastUpdate(governanceAddresses[0]);
t.like(questionUpdate, {
status: { numWantsSatisfied: 1 },
});

for (const address of governanceAddresses) {
const committeeInvitationForVoter =
await governanceDriver.getCommitteeInvitation(address);

await governanceDriver.voteOnProposedChanges(
address,
committeeInvitationForVoter[0],
);

const voteUpdate = await getLastUpdate(address);
t.like(voteUpdate, {
status: { numWantsSatisfied: 1 },
});
}

await governanceDriver.waitForElection();
},
);

Expand All @@ -146,20 +97,17 @@ test.serial(
);

/*
* At the previous test ('economic committee can make governance proposal and vote on it')
* The value of ChargingPeriod was updated to 400
* The 'published.vaultFactory.governance' node should reflect that change.
* At the previous test('economic committee can make governance proposal for ProvisionPool')
* The value of PerAccountInitialAmount was updated to 100
* The 'published.provisionPool.governance' node should reflect that change.
*/
t.is(
provisionPoolParamsBefore.current.PerAccountInitialAmount.value.value,
100_000n,
'provisionPool PerAccountInitialAmount parameter value is not the expected ',
);

await upgradeContract(
'upgrade-provisionPool',
'zcf-b1-db93f-provisionPool',
);
await upgradeContract('upgrade-provisionPool', 'provisionPool');

/** @type {any} */
const provisionPoolParamsAfter = await readLatestHead(
Expand All @@ -174,6 +122,38 @@ test.serial(
},
);

test.serial(
'make sure provisionPool governance works after governor upgrade',
async t => {
/** @type {any} */
const brand = await readLatestHead(`published.agoricNames.brand`);
const brands = Object.fromEntries(brand);

const params = {
PerAccountInitialAmount: { brand: brands.IST, value: 300_000n },
};
const instanceName = 'provisionPool';

await runCommitteeElectionParamChange(
t,
governanceDriver,
{ instanceName, duration: 30, governanceAddresses, params },
{ getLastUpdate },
);

/** @type {any} */
const provisionPoolParams = await readLatestHead(
'published.provisionPool.governance',
);

t.is(
provisionPoolParams.current.PerAccountInitialAmount.value.value,
300_000n,
'provisionPool PerAccountInitialAmount parameter value is not as expected after governor upgrade',
);
},
);

test.serial('Governance proposals history is visible', async t => {
/*
* List ordered from most recent to earliest of Economic Committee
Expand All @@ -183,6 +163,7 @@ test.serial('Governance proposals history is visible', async t => {
* the acceptance tests scalability
*/
const expectedParametersChanges = [
['PerAccountInitialAmount'], // z:acceptance/governance.test.js
['PerAccountInitialAmount'], // z:acceptance/governance.test.js
['ChargingPeriod'], // z:acceptance/governance.test.js
['DebtLimit'], // z:acceptance/vaults.test.js
Expand Down
53 changes: 53 additions & 0 deletions a3p-integration/proposals/z:acceptance/test-lib/governance.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,56 @@ export const makeGovernanceDriver = async (fetch, networkConfig) => {
getLatestQuestionHistory,
};
};

/**
*
* @param {import('ava').ExecutionContext} t
* @param {Awaited<ReturnType<makeGovernanceDriver>>} governanceDriver
* @param {{
* instanceName: string;
* duration: number;
* governanceAddresses: string[];
* params: object
* }} electionParams
* @param {{ getLastUpdate: (addr: string) => Promise<import('@agoric/smart-wallet/src/smartWallet.js').UpdateRecord>}} io
*/
export const runCommitteeElectionParamChange = async (
t,
governanceDriver,
{ instanceName, duration, governanceAddresses, params },
{ getLastUpdate },
) => {
const path = { paramPath: { key: 'governedParams' } };
await governanceDriver.proposeParamChange(
governanceAddresses[0],
params,
path,
instanceName,
duration,
);

const questionUpdate = await getLastUpdate(governanceAddresses[0]);
t.log(questionUpdate);
t.like(questionUpdate, {
status: { numWantsSatisfied: 1 },
});

t.log('Voting on param change');
for (const address of governanceAddresses) {
const committeeInvitationForVoter =
await governanceDriver.getCommitteeInvitation(address);

await governanceDriver.voteOnProposedChanges(
address,
committeeInvitationForVoter[0],
);

const voteUpdate = await getLastUpdate(address);
t.log(`${address} voted`);
t.like(voteUpdate, {
status: { numWantsSatisfied: 1 },
});
}

await governanceDriver.waitForElection();
};
5 changes: 4 additions & 1 deletion a3p-integration/proposals/z:acceptance/test-lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ export const makeTimerUtils = ({ setTimeout }) => {
*/
const getIncarnationFromDetails = async vatName => {
const matchingVats = await getDetailsMatchingVats(vatName);
const expectedVat = matchingVats.find(vat => vat.vatName === vatName);
const expectedVat = matchingVats.find(
/** @param {{ vatName: string }} vat */
vat => vat.vatName.endsWith(vatName),
);
assert(expectedVat, `No matching Vat was found for ${vatName}`);
return expectedVat.incarnation;
};
Expand Down
Loading
Loading