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(a3p): test mintHolder functionalities after contract null upgrade #10617

Merged
merged 4 commits into from
Dec 12, 2024
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 a3p-integration/proposals/p:upgrade-19/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ addUsdOlives/
upgradeProvisionPool/
upgradeAgoricNames/
publishTestInfo/
upgrade-mintHolder/
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
true
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* global E */

/// <reference types="@agoric/vats/src/core/core-eval-env"/>
/// <reference types="@agoric/vats/src/core/types-ambient"/>

/**
* The primary purpose of this script is to mint a payment of a certain
* bankAsset and deposit in an user wallet.
*
* The receiverAddress and label placeholders should be replaced with
* the desired address and asset name during the execution of each test case.
*
* See z:acceptance/mintHolder.test.js
*
* @param {BootstrapPowers} powers
*/
const sendBankAsset = async powers => {
const {
consume: { namesByAddress, contractKits: contractKitsP },
} = powers;

const receiverAddress = '{{ADDRESS}}';
const label = '{{LABEL}}';
const valueStr = '{{VALUE}}';
const value = BigInt(valueStr)

console.log(`Start sendBankAsset for ${label}`);

const contractKits = await contractKitsP;
const mintHolderKit = Array.from(contractKits.values()).filter(
kit => kit.label && kit.label === label,
);

const { creatorFacet: mint, publicFacet: issuer } = mintHolderKit[0];

/*
* Ensure that publicFacet holds an issuer by verifying that has
* the makeEmptyPurse method.
*/
await E(issuer).makeEmptyPurse()

const brand = await E(issuer).getBrand();
const amount = harden({ value, brand });
const payment = await E(mint).mintPayment(amount);

const receiverDepositFacet = E(namesByAddress).lookup(
receiverAddress,
'depositFacet',
);

await E(receiverDepositFacet).receive(payment);

console.log(`Finished sendBankAsset for ${label}`);
};

sendBankAsset;
28 changes: 28 additions & 0 deletions a3p-integration/proposals/p:upgrade-19/mintHolder.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* eslint-env node */

import '@endo/init';
import test from 'ava';
import { addUser, provisionSmartWallet } from '@agoric/synthetic-chain';
import {
mintPayment,
getAssetList,
swap,
getPSMChildren,
upgradeMintHolder,
} from './test-lib/mintHolder-helpers.js';
import { networkConfig } from './test-lib/index.js';

test('mintHolder contract is upgraded', async t => {
const receiver = await addUser('receiver');
await provisionSmartWallet(receiver, `20000000ubld`);

let assetList = await getAssetList();
t.log('List of mintHolder vats being upgraded: ', assetList);
await upgradeMintHolder(`upgrade-mintHolder`, assetList);
await mintPayment(t, receiver, assetList, 10);

const psmLabelList = await getPSMChildren(fetch, networkConfig);
assetList = await getAssetList(psmLabelList);
t.log('List of assets being swapped with IST via PSM: ', assetList);
await swap(t, receiver, assetList, 5);
});
5 changes: 3 additions & 2 deletions a3p-integration/proposals/p:upgrade-19/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
"testing/test-upgraded-board.js testUpgradedBoard",
"vats/upgrade-agoricNames.js agoricNamesCoreEvals/upgradeAgoricNames",
"testing/add-USD-OLIVES.js agoricNamesCoreEvals/addUsdOlives",
"testing/publish-test-info.js agoricNamesCoreEvals/publishTestInfo"
"testing/publish-test-info.js agoricNamesCoreEvals/publishTestInfo",
"vats/upgrade-mintHolder.js upgrade-mintHolder A3P_INTEGRATION"
]
},
"type": "module",
"license": "Apache-2.0",
"dependencies": {
"@agoric/client-utils": "0.1.1-dev-02c06c4.0",
"@agoric/client-utils": "dev",
"@agoric/ertp": "dev",
"@agoric/internal": "dev",
"@agoric/synthetic-chain": "^0.4.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/* eslint-env node */

import {
agoric,
evalBundles,
getDetailsMatchingVats,
getISTBalance,
} from '@agoric/synthetic-chain';
import { makeVstorageKit, retryUntilCondition } from '@agoric/client-utils';
import { readFile, writeFile } from 'node:fs/promises';
import { psmSwap, snapshotAgoricNames } from './psm-lib.js';

/**
* @param {string} fileName base file name without .tjs extension
* @param {Record<string, string>} replacements
*/
export const replaceTemplateValuesInFile = async (fileName, replacements) => {
let script = await readFile(`${fileName}.tjs`, 'utf-8');
for (const [template, value] of Object.entries(replacements)) {
script = script.replaceAll(`{{${template}}}`, value);
}
await writeFile(`${fileName}.js`, script);
};

export const getPSMChildren = async (fetch, networkConfig) => {
const {
vstorage: { keys },
} = await makeVstorageKit({ fetch }, networkConfig);

const children = await keys('published.psm.IST');

return children;
};

export const getAssetList = async labelList => {
const assetList = [];
const { vbankAssets } = await snapshotAgoricNames();

// Determine the assets to consider based on labelList
const assetsToConsider =
labelList || Object.values(vbankAssets).map(asset => asset.issuerName);

for (const label of assetsToConsider) {
if (label === 'IST') {
break;
}

const vbankAsset = Object.values(vbankAssets).find(
asset => asset.issuerName === label,
);
assert(vbankAsset, `vbankAsset not found for ${label}`);

const { denom } = vbankAsset;
const mintHolderVat = `zcf-mintHolder-${label}`;

assetList.push({ label, denom, mintHolderVat });
}

return assetList;
};

export const mintPayment = async (t, address, assetList, value) => {
const SUBMISSION_DIR = 'mint-payment';

for (const asset of assetList) {
const { label, denom } = asset;
const scaled = BigInt(parseInt(value, 10) * 1_000_000).toString();

await replaceTemplateValuesInFile(`${SUBMISSION_DIR}/send-script`, {
ADDRESS: address,
LABEL: label,
VALUE: scaled,
});

await evalBundles(SUBMISSION_DIR);

const balance = await getISTBalance(address, denom);

// Add to value the BLD provisioned to smart wallet
if (label === 'BLD') {
value += 10;
}

t.is(
balance,
value,
`receiver ${denom} balance ${balance} is not ${value}`,
);
}
};

export const swap = async (t, address, assetList, want) => {
for (const asset of assetList) {
const { label, denom } = asset;

// TODO: remove condition after fixing issue #10655
if (/^DAI/.test(label)) {
break;
}

const pair = `IST.${label}`;

const istBalanceBefore = await getISTBalance(address, 'uist');
const anchorBalanceBefore = await getISTBalance(address, denom);

const psmSwapIo = {
now: Date.now,
follow: agoric.follow,
setTimeout,
log: console.log,
};

await psmSwap(
address,
['swap', '--pair', pair, '--wantMinted', want],
psmSwapIo,
);

const istBalanceAfter = await getISTBalance(address, 'uist');
const anchorBalanceAfter = await getISTBalance(address, denom);

t.is(istBalanceAfter, istBalanceBefore + want);
t.is(anchorBalanceAfter, anchorBalanceBefore - want);
}
};

const getIncarnationForAllVats = async assetList => {
const vatsIncarnation = {};

for (const asset of assetList) {
const { label, mintHolderVat } = asset;
const matchingVats = await getDetailsMatchingVats(label);
const expectedVat = matchingVats.find(vat => vat.vatName === mintHolderVat);
vatsIncarnation[label] = expectedVat.incarnation;
}
assert(Object.keys(vatsIncarnation).length === assetList.length);

return vatsIncarnation;
};

const checkVatsUpgraded = (before, current) => {
for (const vatLabel in before) {
if (current[vatLabel] !== before[vatLabel] + 1) {
console.log(`${vatLabel} upgrade failed. `);
return false;
}
}
return true;
};

export const upgradeMintHolder = async (submissionPath, assetList) => {
const before = await getIncarnationForAllVats(assetList);

await evalBundles(submissionPath);

return retryUntilCondition(
async () => getIncarnationForAllVats(assetList),
current => checkVatsUpgraded(before, current),
`mintHolder upgrade not processed yet`,
{ setTimeout, retryIntervalMs: 5000, maxRetries: 15 },
);
};
27 changes: 26 additions & 1 deletion a3p-integration/proposals/p:upgrade-19/test-lib/psm-lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@

import { execa } from 'execa';
import { getNetworkConfig } from 'agoric/src/helpers.js';
import { waitUntilOfferResult } from '@agoric/client-utils';
import {
waitUntilOfferResult,
makeFromBoard,
boardSlottingMarshaller,
} from '@agoric/client-utils';
import { deepMapObject } from '@agoric/internal';
import {
agd,
agoric,
agopsLocation,
CHAINID,
executeCommand,
Expand Down Expand Up @@ -285,3 +290,23 @@ export const tryISTBalances = async (t, actualBalance, expectedBalance) => {
const minFeeDebit = 200_000;
t.is(actualBalance + minFeeDebit, expectedBalance);
};

const fromBoard = makeFromBoard();
const marshaller = boardSlottingMarshaller(fromBoard.convertSlotToVal);

/**
* @param {string} path
*/
const objectFromVstorageEntries = async path => {
const rawEntries = await agoric.follow('-lF', `:${path}`, '-o', 'text');
return Object.fromEntries(marshaller.fromCapData(JSON.parse(rawEntries)));
};

export const snapshotAgoricNames = async () => {
const [brands, instances, vbankAssets] = await Promise.all([
objectFromVstorageEntries('published.agoricNames.brand'),
objectFromVstorageEntries('published.agoricNames.instance'),
objectFromVstorageEntries('published.agoricNames.vbankAsset'),
]);
return { brands, instances, vbankAssets };
};
2 changes: 1 addition & 1 deletion a3p-integration/proposals/p:upgrade-19/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

yarn ava replaceFeeDistributor.test.js
yarn ava upgradedBoard.test.js

yarn ava mintHolder.test.js
yarn ava provisionPool.test.js
yarn ava agoricNames.test.js
Loading
Loading