Skip to content

Commit

Permalink
test: verify purse balances are updated after smartWallet upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris-Hibbert committed Feb 9, 2024
1 parent 0169c7e commit d06b176
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 2 deletions.
12 changes: 12 additions & 0 deletions a3p-integration/proposals/a:upgrade-14/invite-submission/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
This core-eval installs upgrades for the wallet and Zoe. This test verifies that
upgraded wallets that aren't backed by vbanks can still add assets, in this case
an invitation.

sendInvite is a secondary submission, which is included in ./invite-submission.
The wallet in which we want to deposit the invitation is gov1, whose address
isn't known until run-time. When submitting a proposal using agd.tx(), the
proposal is required to be in a file, so we have to edit a template file
(sendInvite.tpl) to produce the .js file that will be submitted.

The core-eval is invoked from the test, which then verifies that the details
were written to vstore.
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,29 @@
// to be replaced before execution
const addr = 'XX_ADDRESS_XX';

// verify that a pre-existing wallet has an invitation purse that is still monitored
const sendInvitation = async powers => {
console.log('sendInvitation start');
// namesByAddress is broken #8113
const {
consume: { namesByAddressAdmin, zoe },
instance: {
consume: { reserve },
},
} = powers;
const pf = E(zoe).getPublicFacet(reserve);
const anInvitation = await E(pf).makeAddCollateralInvitation();

await E(namesByAddressAdmin).reserve(addr);
// don't trigger the namesByAddressAdmin.readonly() bug
const addressAdmin = E(namesByAddressAdmin).lookupAdmin(addr);

await E(addressAdmin).reserve('depositFacet');
const addressHub = E(addressAdmin).readonly();
const addressDepositFacet = E(addressHub).lookup('depositFacet');

await E(addressDepositFacet).receive(anInvitation);
console.log('ADDED an invitation to a purse!');
};

sendInvitation;
4 changes: 4 additions & 0 deletions a3p-integration/proposals/a:upgrade-14/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
source /usr/src/upgrade-test-scripts/env_setup.sh

yarn ava

npm install --global tsx

./testRepairs.ts
99 changes: 99 additions & 0 deletions a3p-integration/proposals/a:upgrade-14/testRepairs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/env tsx

import { execFileSync } from 'child_process';
import { readFile, writeFile } from 'fs/promises';

import { makeAgd } from '@agoric/synthetic-chain/src/lib/agd-lib.js';
import {
getUser,
voteLatestProposalAndWait,
} from '@agoric/synthetic-chain/src/lib/commonUpgradeHelpers.js';
import assert from 'assert';

const SUBMISSION_DIR = 'invite-submission';

const staticConfig = {
deposit: '10000000ubld', // 10 BLD
installer: 'gov1', // as in: agd keys show gov1
proposer: 'validator',
collateralPrice: 6, // conservatively low price. TODO: look up
swingstorePath: '~/.agoric/data/agoric/swingstore.sqlite',
};

/** Provide access to the outside world via context. */
const makeContext = async () => {
const config = {
chainId: 'agoriclocal',
...staticConfig,
};

const agd = makeAgd({ execFileSync }).withOpts({
keyringBackend: 'test',
});

return { agd, config };
};

// XXX vestige of Ava
const step = async (name: string, fn: Function) => {
console.log(name);
await fn();
};

const replaceAddressInFile = async (string, fileName, replacement) => {
const scriptBuffer = await readFile(`${SUBMISSION_DIR}/${fileName}.tpl`);

const newScript = scriptBuffer.toString().replace(string, replacement);
await writeFile(`${SUBMISSION_DIR}/${fileName}.js`, newScript);
};

await step('verify smartWallet repairs', async () => {
const { agd, config } = await makeContext();
const { chainId, deposit, proposer } = config;
const from = agd.lookup(proposer);

const gov1Address = await getUser('gov1');
await replaceAddressInFile('XX_ADDRESS_XX', 'sendInvite', gov1Address);

// agd tx gov submit-proposal swingset-core-eval bar.json foo.js
await agd.tx(
[
'gov',
'submit-proposal',
'swingset-core-eval',
`${SUBMISSION_DIR}/sendInvite-permit.json`,
`${SUBMISSION_DIR}/sendInvite.js`,
'--title=sendInvite',
'--description="send an invitation to verify the purse accepts deposits"',
`--deposit=${deposit}`,
'--gas=auto',
'--gas-adjustment=1.2',
'--keyring-backend=test',
],
{ from, chainId, yes: true },
);
await voteLatestProposalAndWait();

// agd query vstorage data published.wallet.$GOV1ADDR.current -o json \
// |& jq '.value | fromjson | .values[0] | fromjson | .body[1:] \
// | fromjson | .purses '
const walletCurrent = await agd.query([
'vstorage',
'data',
`published.wallet.${gov1Address}.current`,
]);

const body = JSON.parse(JSON.parse(walletCurrent.value).values[0]);
const bodyTruncated = JSON.parse(body.body.substring(1));
const invitePurseBalance = bodyTruncated.purses[0].balance;
assert(invitePurseBalance.value[0], 'expecting a non-empty purse');
const description = invitePurseBalance.value[0].description;

assert.equal(
description,
'Add Collateral',
'invitation purse should not be empty',
);

console.log('✅ invitation purse is not empty');
});
2 changes: 1 addition & 1 deletion a3p-integration/proposals/a:upgrade-14/use.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash

# UNTIl this is upstream https://github.com/Agoric/agoric-3-proposals/issues/40
# UNTIL this is upstream https://github.com/Agoric/agoric-3-proposals/issues/40
# Set to zero so tests don't have to pay gas (we're not testing that)
sed --in-place=.bak s/'minimum-gas-prices = ""'/'minimum-gas-prices = "0ubld,0uist"'/ ~/.agoric/config/app.toml
2 changes: 1 addition & 1 deletion packages/smart-wallet/src/smartWallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ export const prepareSmartWallet = (baggage, shared) => {
const { invitationPurse, address } = state;

const brandToPurses = getBrandToPurses(walletPurses, self);
trace(`Found ${brandToPurses.values()} purse(s) for ${address}`);
trace(`Found purse(s) for ${address}`);
for (const purses of brandToPurses.values()) {
for (const record of purses) {
void helper.watchPurse(record.purse);
Expand Down

0 comments on commit d06b176

Please sign in to comment.