From a289edc1b32e3224b601aad712ce4bab396b02f2 Mon Sep 17 00:00:00 2001 From: Ikenna Omekam Date: Thu, 13 Jul 2023 12:19:03 -0400 Subject: [PATCH] fix! vault factory takes auctioneerPublicFacet from private args instead of terms --- .../auctioneer-upgrade-driver.sh | 51 ++++++ .../gov-switch-auctioneer-permit.json | 29 ++++ .../gov-switch-auctioneer.js | 148 ++++++++++++++++++ .../agoric-upgrade-11/mint-ist.sh | 6 + .../src/proposals/econ-behaviors.js | 2 +- .../inter-protocol/src/vaultFactory/params.js | 8 +- .../src/vaultFactory/vaultDirector.js | 15 +- .../src/vaultFactory/vaultFactory.js | 7 +- 8 files changed, 257 insertions(+), 9 deletions(-) create mode 100755 packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/auctioneer-upgrade-driver.sh create mode 100644 packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/gov-switch-auctioneer-permit.json create mode 100644 packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/gov-switch-auctioneer.js create mode 100755 packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/mint-ist.sh diff --git a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/auctioneer-upgrade-driver.sh b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/auctioneer-upgrade-driver.sh new file mode 100755 index 00000000000..237e7e3ee9e --- /dev/null +++ b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/auctioneer-upgrade-driver.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +. ./upgrade-test-scripts/env_setup.sh + +set -euo pipefail +# set -x + +here='upgrade-test-scripts/agoric-upgrade-11' + +bundle_auctioneer_filepath='/tmp/bundle-auctioneer.json' +bundle_vault_filepath='/tmp/bundle-vaultFactory.json' + +alias bundle-source="yarn run --silent bundle-source" +# TODO: for now, we're bundling vaultFactory outside the container. but before we finish: +# bundle-source --cache-json /tmp packages/inter-protocol/src/vaultFactory/vaultFactory.js vaultFactory +VAULT_HASH=`jq -r .endoZipBase64Sha512 ${bundle_vault_filepath}` + +echo checking that hashes match ${here}/gov-switch-auctioneer.js +echo ${VAULT_HASH} +grep ${VAULT_HASH} ${here}/gov-switch-auctioneer.js || exit 1 + +bundle-source --cache-json /tmp packages/inter-protocol/src/auction/auctioneer.js auctioneer +AUCTIONEER_HASH=`jq -r .endoZipBase64Sha512 ${bundle_auctioneer_filepath}` +grep ${AUCTIONEER_HASH} ${here}/gov-switch-auctioneer.js || exit 1 + +# TODO: make sure this consistently works +agd tx swingset install-bundle @${bundle_vault_filepath} \ + --from gov1 --keyring-backend=test --gas=auto \ + --chain-id=agoriclocal -b block --yes +agoric follow -lF :bundles + +agd tx swingset install-bundle @${bundle_auctioneer_filepath} \ + --from gov1 --keyring-backend=test --gas=auto \ + --chain-id=agoriclocal -b block --yes +agoric follow -lF :bundles + +agd --chain-id=agoriclocal \ + tx gov submit-proposal swingset-core-eval \ + ${here}/gov-switch-auctioneer-permit.json ${here}/gov-switch-auctioneer.js \ + --title="Auctioneer Upgrade" --description="auctioneer 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 + +# then tes some stuff??? +# 3129800000uist \ No newline at end of file diff --git a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/gov-switch-auctioneer-permit.json b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/gov-switch-auctioneer-permit.json new file mode 100644 index 00000000000..e9b698f6666 --- /dev/null +++ b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/gov-switch-auctioneer-permit.json @@ -0,0 +1,29 @@ +{ + "consume": { + "auctioneerKit": true, + "chainTimerService": true, + "priceAuthority": true, + "startGovernedUpgradable": true, + "vaultFactoryKit": true, + "zoe": true, + "chainStorage": true, + "board": true, + "reserveKit": true + }, + "produce": { + "auctioneerKit": true + }, + "instance": { + "produce": { + "auctioneer": true + }, + "consume": { + "reserve": true + } + }, + "issuer": { + "consume": { + "IST": true + } + } +} \ No newline at end of file diff --git a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/gov-switch-auctioneer.js b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/gov-switch-auctioneer.js new file mode 100644 index 00000000000..e5fc9a57112 --- /dev/null +++ b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/gov-switch-auctioneer.js @@ -0,0 +1,148 @@ +// @ts-nocheck +// xxport { E } from '@endo/far'; +/* global E */ + +console.log('started switch-auctioneer script'); + +// TODO: set these bundle-ids to the revised code +const bundleIDs = { + vaultFactory: + 'b1-4755fb5c079fc2a17e6ea5a887d27787cd6d48df179e046466c4dbf4b9e78ac7dceee183a395de3d6a09c5f162415e12f42685269b84c64b58c5f65eab6b0de1', + auctioneer: + 'b1-e85289898e66e0423d7ec1c402ac2ced21573f93cf599d593a0533a1e2355ace624cc95c8c8c18c66d44a921511642e87837accd0e728427c269936b040bb886', +}; + +const STORAGE_PATH = 'auction'; + +const { fromEntries, keys, values } = Object; + +/** @type {(xs: X[], ys: Y[]) => [X, Y][]} */ +const zip = (xs, ys) => harden(xs.map((x, i) => [x, ys[+i]])); + +/** + * @type {>>( + * obj: T, + * ) => Promise<{ [K in keyof T]: Awaited }>} + */ +const allValues = async obj => { + const resolved = await Promise.all(values(obj)); + // @ts-expect-error cast + return harden(fromEntries(zip(keys(obj), resolved))); +}; + +// /** @param {xxport('../../src/proposals/econ-behaviors').EconomyBootstrapPowers} permittedPowers */ +const switchAuctioneer = async permittedPowers => { + console.log('switchAuctioneer: extracting permitted powers...'); + // see gov-switch-auctioneer-permit.json + const { + consume: { + auctioneerKit: auctioneerKitP, + chainTimerService: timerService, + priceAuthority, + startGovernedUpgradable, + vaultFactoryKit, + zoe, + chainStorage, + board, + reserveKit, + }, + produce: { auctioneerKit }, + instance: { + produce: { auctioneer: auctionInstance }, + consume: { reserve: reserveInstance }, + }, + issuer: { + consume: { IST: stableIssuerP }, + }, + } = permittedPowers; + + /** install, start governed instance, publish results */ + const startNewAuctioneer = async () => { + console.log('startNewAuctioneer: installBundleID etc.'); + const { + // @ts-expect-error cast XXX missing from type + // auctioneerKit: { privateArgs }, // TODO, this doesn't work. Find a way to pass in valid private args + governedParamsOrig, + installation, + reservePublicFacet, + stableIssuer, + storageNode, + marshaller, + } = await allValues({ + auctioneerKit: auctioneerKitP, + installation: E(zoe).installBundleID(bundleIDs.auctioneer, 'auctioneer'), + reservePublicFacet: E(zoe).getPublicFacet(reserveInstance), + stableIssuer: stableIssuerP, + governedParamsOrig: E( + E.get(auctioneerKitP).publicFacet, + ).getGovernedParams(), + storageNode: E(chainStorage).makeChildNode(STORAGE_PATH), + marshaller: E(board).getReadonlyMarshaller(), + }); + + const privateArgs = { + storageNode, + marshaller, + }; + + const { Electorate: _, ...governedParams } = governedParamsOrig; + + const terms = { + priceAuthority, + reservePublicFacet, + timerService, + governedParams: governedParamsOrig, + }; + + console.log('startNewAuctioneer: startGovernedUpgradable'); + const kit = await E(startGovernedUpgradable)({ + label: 'auctioneer', + installation, + issuerKeywordRecord: { Bid: stableIssuer }, + terms, + governedParams, + privateArgs, + }); + + auctioneerKit.reset(); + auctioneerKit.resolve(kit); + // TODO: test that auctioneer in agoricNames.instance gets updated + auctionInstance.reset(); + auctionInstance.resolve(kit.instance); + + return kit; + }; + + const newAuctionKit = await startNewAuctioneer(); + + // TODO: shut down old auctioneer? + + // upgrade the vaultFactory + const upgradeVaultFactory = async () => { + console.log('upgradeVaultFactory...'); + const kit = await vaultFactoryKit; + // @ts-expect-error cast XXX privateArgs missing from type + const { privateArgs } = kit; + + /** @type {xxport('../../src/vaultFactory/vaultFactory').VaultFactoryContract['privateArgs']} */ + const newPrivateArgs = harden({ + ...privateArgs, + auctioneerPublicFacet: newAuctionKit.publicFacet, + }); + const upgradeResult = await E(kit.adminFacet).upgradeContract( + bundleIDs.vaultFactory, + newPrivateArgs, + ); + + const shortfallInvitation = await E( + E.get(reserveKit).creatorFacet, + ).makeShortfallReportingInvitation(); + + await E(kit.creatorFacet).updateShortfallReporter(shortfallInvitation); + + console.log('upgraded vaultVactory.', upgradeResult); + }; + await upgradeVaultFactory(); +}; + +switchAuctioneer; diff --git a/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/mint-ist.sh b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/mint-ist.sh new file mode 100755 index 00000000000..b79c4ee62d9 --- /dev/null +++ b/packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/mint-ist.sh @@ -0,0 +1,6 @@ +agd tx bank send validator $GOV1ADDR 20123000000ibc/BA313C4A19DFBF943586C0387E6B11286F9E416B4DD27574E6909CABE0E342FA --keyring-backend=test --chain-id=agoriclocal --yes -bblock +agops vaults open --giveCollateral 5000 --wantMinted 20000 > /tmp/offer.json +agops perf satisfaction --executeOffer /tmp/offer.json --from gov1 --keyring-backend=test + + +# ibc/BA313C4A19DFBF943586C0387E6B11286F9E416B4DD27574E6909CABE0E342FA \ No newline at end of file diff --git a/packages/inter-protocol/src/proposals/econ-behaviors.js b/packages/inter-protocol/src/proposals/econ-behaviors.js index 2a9f363934a..357e67a54d1 100644 --- a/packages/inter-protocol/src/proposals/econ-behaviors.js +++ b/packages/inter-protocol/src/proposals/econ-behaviors.js @@ -252,7 +252,6 @@ export const setupVaultFactoryArguments = async ( const vaultFactoryTerms = makeGovernedVFTerms({ priceAuthority, - auctioneerPublicFacet, reservePublicFacet, interestTiming, timer: chainTimerService, @@ -264,6 +263,7 @@ export const setupVaultFactoryArguments = async ( }); const vaultFactoryPrivateArgs = { + auctioneerPublicFacet, feeMintAccess, initialPoserInvitation, initialShortfallInvitation, diff --git a/packages/inter-protocol/src/vaultFactory/params.js b/packages/inter-protocol/src/vaultFactory/params.js index 239a33ce53f..3544a6e5000 100644 --- a/packages/inter-protocol/src/vaultFactory/params.js +++ b/packages/inter-protocol/src/vaultFactory/params.js @@ -126,7 +126,6 @@ export const vaultParamPattern = M.splitRecord( /** * @param {{ - * auctioneerPublicFacet: ERef; * electorateInvitationAmount: Amount<'set'>; * minInitialDebt: Amount<'nat'>; * bootstrapPaymentValue: bigint; @@ -139,7 +138,6 @@ export const vaultParamPattern = M.splitRecord( * }} opts */ export const makeGovernedTerms = ({ - auctioneerPublicFacet, bootstrapPaymentValue, electorateInvitationAmount, interestTiming, @@ -151,7 +149,6 @@ export const makeGovernedTerms = ({ referencedUi = 'NO REFERENCE', }) => { return harden({ - auctioneerPublicFacet, priceAuthority, reservePublicFacet, timerService: timer, @@ -201,7 +198,10 @@ export const provideVaultParamManagers = (baggage, marshaller) => { }; // restore from baggage - [...managerArgs.entries()].map(([brand, args]) => makeManager(brand, args)); + // [...managerArgs.entries()].map(([brand, args]) => makeManager(brand, args)); + for (const [brand, args] of managerArgs.entries()) { + makeManager(brand, args); + } return { /** diff --git a/packages/inter-protocol/src/vaultFactory/vaultDirector.js b/packages/inter-protocol/src/vaultFactory/vaultDirector.js index 1d3d0aeac30..e4a26c15e42 100644 --- a/packages/inter-protocol/src/vaultFactory/vaultDirector.js +++ b/packages/inter-protocol/src/vaultFactory/vaultDirector.js @@ -4,7 +4,10 @@ import '@agoric/zoe/src/contracts/exported.js'; import '@agoric/governance/exported.js'; import { AmountMath, AmountShape, BrandShape, IssuerShape } from '@agoric/ertp'; -import { GovernorFacetShape } from '@agoric/governance/src/typeGuards.js'; +import { + GovernorFacetShape, + InvitationShape, +} from '@agoric/governance/src/typeGuards.js'; import { makeTracer } from '@agoric/internal'; import { M, mustMatch } from '@agoric/store'; import { @@ -143,9 +146,12 @@ const prepareVaultDirector = ( const oldInvitation = baggage.has(shortfallInvitationKey) ? baggage.get(shortfallInvitationKey) : undefined; + console.log('@@@@@ Old Invitation', oldInvitation); + const newInvitation = await directorParamManager.getInternalParamValue( SHORTFALL_INVITATION_KEY, ); + console.log('@@@@@ New Invitation', newInvitation); if (newInvitation === oldInvitation) { shortfallReporter || @@ -294,6 +300,7 @@ const prepareVaultDirector = ( makePriceLockWaker: M.call().returns(M.remotable('TimerWaker')), makeLiquidationWaker: M.call().returns(M.remotable('TimerWaker')), makeReschedulerWaker: M.call().returns(M.remotable('TimerWaker')), + updateShortfallReporter: M.call(InvitationShape).returns(M.promise()), }), public: M.interface('public', { getCollateralManager: M.call(BrandShape).returns(M.remotable()), @@ -437,6 +444,12 @@ const prepareVaultDirector = ( allManagersDo(vm => vm.lockOraclePrices()); }); }, + async updateShortfallReporter(newInvitation) { + const zoe = zcf.getZoeService(); + shortfallReporter = await E( + E(zoe).offer(newInvitation), + ).getOfferResult(); + }, }, public: { /** @param {Brand} brandIn */ diff --git a/packages/inter-protocol/src/vaultFactory/vaultFactory.js b/packages/inter-protocol/src/vaultFactory/vaultFactory.js index 18a6c3e7f50..421eae83dec 100644 --- a/packages/inter-protocol/src/vaultFactory/vaultFactory.js +++ b/packages/inter-protocol/src/vaultFactory/vaultFactory.js @@ -35,8 +35,7 @@ const trace = makeTracer('VF', true); /** * @typedef {ZCF< - * GovernanceTerms & { - * auctioneerPublicFacet: import('../auction/auctioneer.js').AuctioneerPublicFacet; + * GovernanceTerms & { * priceAuthority: ERef; * reservePublicFacet: AssetReservePublicFacet; * timerService: import('@agoric/time').TimerService; @@ -70,6 +69,7 @@ harden(meta); * initialShortfallInvitation: Invitation; * storageNode: ERef; * marshaller: ERef; + * auctioneerPublicFacet: import('../auction/auctioneer.js').AuctioneerPublicFacet; * }} privateArgs * @param {import('@agoric/ertp').Baggage} baggage */ @@ -80,6 +80,7 @@ export const start = async (zcf, privateArgs, baggage) => { initialShortfallInvitation, marshaller, storageNode, + auctioneerPublicFacet, } = privateArgs; trace('awaiting debtMint'); @@ -91,7 +92,7 @@ export const start = async (zcf, privateArgs, baggage) => { mintedIssuerRecord: debtMint.getIssuerRecord(), })); - const { timerService, auctioneerPublicFacet } = zcf.getTerms(); + const { timerService } = zcf.getTerms(); const { makeRecorderKit, makeERecorderKit } = prepareRecorderKitMakers( baggage,