Skip to content

Commit

Permalink
WIP feat(price): fluxAggregator governance
Browse files Browse the repository at this point in the history
  • Loading branch information
turadg committed Feb 10, 2023
1 parent 2add695 commit 4e15f2f
Show file tree
Hide file tree
Showing 5 changed files with 922 additions and 42 deletions.
12 changes: 12 additions & 0 deletions packages/governance/src/contractGovernor.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { E } from '@endo/eventual-send';
import { Far } from '@endo/marshal';
import { mustMatch } from '@agoric/store';

import { makeTracer } from '@agoric/internal';
import {
CONTRACT_ELECTORATE,
setupParamGovernance,
Expand All @@ -12,6 +13,8 @@ import { ParamChangesQuestionDetailsShape } from './typeGuards.js';

const { Fail } = assert;

const trace = makeTracer('CGov');

/**
* Validate that the question details correspond to a parameter change question
* that the electorate hosts, and that the voteCounter and other details are
Expand Down Expand Up @@ -125,6 +128,8 @@ const validateQuestionFromCounter = async (zoe, electorate, voteCounter) => {
*/

/**
* Start an instance of a governor, governing a "governed" contract specified in terms.
*
* @template {GovernableStartFn} SF Start function of governed contract
* @param {ZCF<{
* timer: import('@agoric/time/src/types').TimerService,
Expand All @@ -139,7 +144,9 @@ const validateQuestionFromCounter = async (zoe, electorate, voteCounter) => {
* }} privateArgs
*/
const start = async (zcf, privateArgs) => {
trace('start');
const zoe = zcf.getZoeService();
trace('getTerms', zcf.getTerms());
const {
timer,
governedContractInstallation,
Expand All @@ -148,6 +155,7 @@ const start = async (zcf, privateArgs) => {
terms: contractTerms,
},
} = zcf.getTerms();
trace('contractTerms', contractTerms);
contractTerms.governedParams[CONTRACT_ELECTORATE] ||
Fail`Contract must declare ${CONTRACT_ELECTORATE} as a governed parameter`;

Expand All @@ -156,6 +164,7 @@ const start = async (zcf, privateArgs) => {
electionManager: zcf.getInstance(),
});

trace('starting governedContractInstallation');
const {
creatorFacet: governedCF,
instance: governedInstance,
Expand Down Expand Up @@ -195,9 +204,11 @@ const start = async (zcf, privateArgs) => {
}
return poserFacet;
};
trace('awaiting getUpdatedPoserFacet');
await getUpdatedPoserFacet();
assert(poserFacet, 'question poser facet must be initialized');

trace('awaiting setupParamGovernance');
// All governed contracts have at least a governed electorate
const { voteOnParamChanges, createdQuestion: createdParamQuestion } =
await setupParamGovernance(
Expand All @@ -208,6 +219,7 @@ const start = async (zcf, privateArgs) => {
getUpdatedPoserFacet,
);

trace('awaiting setupFilterGovernance');
const { voteOnFilter, createdFilterQuestion } = await setupFilterGovernance(
zoe,
governedInstance,
Expand Down
37 changes: 33 additions & 4 deletions packages/inter-protocol/src/price/fluxAggregator.contract.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { AssetKind, makeIssuerKit } from '@agoric/ertp';
import { assertAllDefined } from '@agoric/internal';
import { handleParamGovernance } from '@agoric/governance';
import { assertAllDefined, makeTracer } from '@agoric/internal';
import { E } from '@endo/eventual-send';
import { provideFluxAggregator } from './fluxAggregator.js';

const trace = makeTracer('FluxAgg');
/**
* @typedef {import('@agoric/vat-data').Baggage} Baggage
* @typedef {import('@agoric/time/src/types').TimerService} TimerService
Expand All @@ -20,13 +22,15 @@ import { provideFluxAggregator } from './fluxAggregator.js';
* unitAmountIn?: Amount<'nat'>,
* }>} zcf
* @param {{
* initialPoserInvitation: Invitation,
* marshaller: Marshaller,
* quoteMint?: ERef<Mint<'set'>>,
* storageNode: ERef<StorageNode>,
* }} privateArgs
* @param {Baggage} baggage
*/
export const start = async (zcf, privateArgs, baggage) => {
trace('start');
const { timer: timerP } = zcf.getTerms();

const quoteMintP =
Expand All @@ -40,12 +44,18 @@ export const start = async (zcf, privateArgs, baggage) => {
mint: quoteMint,
};

const { marshaller, storageNode: storageNodeP } = privateArgs;
assertAllDefined({ marshaller, storageNodeP });
const {
initialPoserInvitation,
marshaller,
storageNode: storageNodeP,
} = privateArgs;
assertAllDefined({ initialPoserInvitation, marshaller, storageNodeP });

const timer = await timerP;
const storageNode = await storageNodeP;

trace('awaited args');

const fa = provideFluxAggregator(
baggage,
zcf,
Expand All @@ -54,9 +64,28 @@ export const start = async (zcf, privateArgs, baggage) => {
storageNode,
marshaller,
);
trace('got fa', fa);

const { makeGovernorFacet } = await handleParamGovernance(
// @ts-expect-error FIXME include Governance params
zcf,
initialPoserInvitation,
{
// No governed parameters. Governance just for API methods.
},
storageNode,
marshaller,
);

trace('got param governance');

const governedApis = {
initOracle: fa.creatorFacet.initOracle,
};

const governorFacet = makeGovernorFacet(fa.creatorFacet, governedApis);
return harden({
creatorFacet: fa.creatorFacet,
creatorFacet: governorFacet,
publicFacet: fa.publicFacet,
});
};
Expand Down
91 changes: 66 additions & 25 deletions packages/inter-protocol/src/proposals/price-feed-proposal.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import { deeplyFulfilledObject, makeTracer } from '@agoric/internal';

import { unitAmount } from '@agoric/zoe/src/contractSupport/priceQuote.js';
import { CONTRACT_ELECTORATE, ParamTypes } from '@agoric/governance';
import { reserveThenDeposit, reserveThenGetNames } from './utils.js';

const trace = makeTracer('RunPriceFeed');
Expand Down Expand Up @@ -97,6 +98,7 @@ export const createPriceFeed = async (
chainStorage,
chainTimerService,
client,
economicCommitteeCreatorFacet,
namesByAddressAdmin,
priceAuthority,
priceAuthorityAdmin,
Expand Down Expand Up @@ -130,43 +132,80 @@ export const createPriceFeed = async (
*
* @type {[[Brand<'nat'>, Brand<'nat'>], [Installation<import('@agoric/inter-protocol/src/price/fluxAggregator.contract.js').start>]]}
*/
const [[brandIn, brandOut], [priceAggregator]] = await Promise.all([
reserveThenGetNames(E(agoricNamesAdmin).lookupAdmin('oracleBrand'), [
IN_BRAND_NAME,
OUT_BRAND_NAME,
]),
reserveThenGetNames(E(agoricNamesAdmin).lookupAdmin('installation'), [
'priceAggregator',
]),
]);
const [[brandIn, brandOut], [contractGovernor, priceAggregator]] =
await Promise.all([
reserveThenGetNames(E(agoricNamesAdmin).lookupAdmin('oracleBrand'), [
IN_BRAND_NAME,
OUT_BRAND_NAME,
]),
reserveThenGetNames(E(agoricNamesAdmin).lookupAdmin('installation'), [
'contractGovernor',
'priceAggregator',
]),
]);

trace('getPoserInvitation');
const poserInvitationP = E(
economicCommitteeCreatorFacet,
).getPoserInvitation();
const [initialPoserInvitation, electorateInvitationAmount] =
await Promise.all([
poserInvitationP,
E(E(zoe).getInvitationIssuer()).getAmountOf(poserInvitationP),
]);
trace('got initialPoserInvitation');

const unitAmountIn = await unitAmount(brandIn);
const terms = await deeplyFulfilledObject(
const terms = harden({
...contractTerms,
description: AGORIC_INSTANCE_NAME,
brandIn,
brandOut,
timer,
unitAmountIn,
governedParams: {
[CONTRACT_ELECTORATE]: {
type: ParamTypes.INVITATION,
value: electorateInvitationAmount,
},
},
});
trace('got terms');

const governorTerms = await deeplyFulfilledObject(
harden({
...contractTerms,
description: AGORIC_INSTANCE_NAME,
brandIn,
brandOut,
timer,
unitAmountIn,
timer: chainTimerService,
governedContractInstallation: priceAggregator,
governed: {
terms,
},
}),
);
trace('got governorTerms', governorTerms);

const storageNode = await makeStorageNodeChild(chainStorage, STORAGE_PATH);
const marshaller = E(board).getReadonlyMarshaller();

trace('got contractGovernor', contractGovernor);

trace('awaiting startInstance');
// Create the price feed.
const aggregator = await E(zoe).startInstance(
priceAggregator,
/** @type {Installation<import('@agoric/governance/src/contractGovernor.js').start>} */
(contractGovernor),
undefined,
terms,
governorTerms,
{
storageNode: E(storageNode).makeChildNode(
sanitizePathSegment(AGORIC_INSTANCE_NAME),
),
marshaller,
governed: {
initialPoserInvitation,
marshaller,
storageNode: E(storageNode).makeChildNode(
sanitizePathSegment(AGORIC_INSTANCE_NAME),
),
},
},
);
trace('got aggregator');
await E(aggregators).set(terms, { aggregator });

E(E(agoricNamesAdmin).lookupAdmin('instance')).update(
Expand All @@ -191,9 +230,9 @@ export const createPriceFeed = async (
* @param {string} addr
*/
const addOracle = async addr => {
const invitation = await E(aggregator.creatorFacet).makeOracleInvitation(
addr,
);
// FIXME different facet that peeks under governance
const aggregatorFacet = E(aggregator.creatorFacet).getCreatorFacet();
const invitation = await E(aggregatorFacet).makeOracleInvitation(addr);
await reserveThenDeposit(
`${AGORIC_INSTANCE_NAME} member ${addr}`,
namesByAddressAdmin,
Expand Down Expand Up @@ -228,6 +267,8 @@ export const getManifestForPriceFeed = async (
chainStorage: t,
chainTimerService: t,
client: t,
contractGovernor: t,
economicCommitteeCreatorFacet: t,
namesByAddressAdmin: t,
priceAuthority: t,
priceAuthorityAdmin: t,
Expand Down
Loading

0 comments on commit 4e15f2f

Please sign in to comment.