Skip to content

Commit

Permalink
feat(price): removeOracles by EC
Browse files Browse the repository at this point in the history
  • Loading branch information
turadg committed Feb 13, 2023
1 parent 269fffa commit bcf33fe
Show file tree
Hide file tree
Showing 5 changed files with 452 additions and 307 deletions.
25 changes: 13 additions & 12 deletions packages/inter-protocol/src/price/fluxAggregator.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
} from '@agoric/zoe/src/contractSupport/index.js';
import { E } from '@endo/eventual-send';
import { Far } from '@endo/marshal';
import { makeOracleAdmin } from './priceOracleKit.js';
import { makeOracleAdminKit } from './priceOracleKit.js';
import { makeRoundsManagerKit } from './roundsManager.js';

const trace = makeTracer('FlxAgg', false);
Expand Down Expand Up @@ -132,7 +132,7 @@ export const provideFluxAggregator = (

const memoizedPath = makeStorageNodePathProvider(baggage);

/** @type {MapStore<string, *>} */
/** @type {MapStore<string, import('./priceOracleKit.js').OracleKit>} */
const oracles = makeScalarBigMapStore('oracles', {
durable: true,
});
Expand Down Expand Up @@ -211,15 +211,15 @@ export const provideFluxAggregator = (
* @param {ZCFSeat} seat
*/
const offerHandler = async seat => {
const admin = await creatorFacet.initOracle(oracleId);
const { oracle } = await creatorFacet.initOracle(oracleId);
const invitationMakers = Far('invitation makers', {
/** @param {import('./roundsManager.js').PriceRound} result */
PushPrice(result) {
return zcf.makeInvitation(
/** @param {ZCFSeat} cSeat */
async cSeat => {
cSeat.exit();
await admin.pushPrice(result);
await oracle.pushPrice(result);
},
'PushPrice',
);
Expand All @@ -228,17 +228,18 @@ export const provideFluxAggregator = (
seat.exit();

return harden({
admin,

invitationMakers,
oracle,
});
};

return zcf.makeInvitation(offerHandler, INVITATION_MAKERS_DESC);
},
/** @param {string} oracleId */
deleteOracle: async oracleId => {
// FIXME how to GC and remove its powers?
removeOracle: async oracleId => {
trace('deleteOracle', oracleId);
const kit = oracles.get(oracleId);
kit.admin.disable();
oracles.delete(oracleId);
},

Expand All @@ -251,7 +252,7 @@ export const provideFluxAggregator = (
trace('initOracle', oracleId);
assert.typeof(oracleId, 'string');

const oracleAdmin = makeOracleAdmin(
const oracleKit = makeOracleAdminKit(
harden({
minSubmissionValue,
maxSubmissionValue,
Expand All @@ -260,9 +261,9 @@ export const provideFluxAggregator = (
timer: timerPresence,
}),
);
oracles.init(oracleId, oracleAdmin);
oracles.init(oracleId, oracleKit);

return oracleAdmin;
return oracleKit;
},

/**
Expand All @@ -275,7 +276,7 @@ export const provideFluxAggregator = (
*/
async oracleRoundState(oracleId, queriedRoundId) {
const blockTimestamp = await E(timerPresence).getCurrentTimestamp();
const status = await E(oracles.get(oracleId)).getStatus();
const status = await E(oracles.get(oracleId).oracle).getStatus();

const oracleCount = oracles.getSize();

Expand Down
24 changes: 23 additions & 1 deletion packages/inter-protocol/src/price/fluxAggregatorContract.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,12 @@ export const start = async (zcf, privateArgs, baggage) => {
);

/**
* Initialize a new oracle and send an invitation to administer it.
* Initialize a new oracle and send an invitation to control it.
*
* @param {string} addr
*/
const addOracle = async addr => {
trace('addOracle', addr);
const invitation = await E(fa.creatorFacet).makeOracleInvitation(addr);
// XXX imported from 'proposals' path
await reserveThenDeposit(
Expand All @@ -97,6 +98,17 @@ export const start = async (zcf, privateArgs, baggage) => {
return `added ${addr}`;
};

/**
* Remove an oracle from aggregation and disable its facet.
*
* @param {string} oracleId
*/
const removeOracle = async oracleId => {
trace('removeOracle', oracleId);
await E(fa.creatorFacet).removeOracle(oracleId);
return `removed ${oracleId}`;
};

const governedApis = {
/**
* Add the specified oracles. May partially fail, such that some oracles are added and others aren't.
Expand All @@ -107,6 +119,16 @@ export const start = async (zcf, privateArgs, baggage) => {
addOracles: oracleIds => {
return Promise.allSettled(oracleIds.map(addOracle));
},
/**
* Remove the specified oracles. May partially fail, such that some oracles are removed and others aren't.
* If the oracle was never part of the set that's a PromiseRejectedResult
*
* @param {string[]} oracleIds
* @returns {Promise<Array<PromiseSettledResult<string>>>}
*/
removeOracles: oracleIds => {
return Promise.allSettled(oracleIds.map(removeOracle));
},
};

const governorFacet = makeGovernorFacet(fa.creatorFacet, governedApis);
Expand Down
103 changes: 63 additions & 40 deletions packages/inter-protocol/src/price/priceOracleKit.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { defineDurableExoClass, M, makeKindHandle } from '@agoric/vat-data';
import { Fail } from '@agoric/assert';
import { makeTracer } from '@agoric/internal';
import { defineDurableExoClassKit, M, makeKindHandle } from '@agoric/vat-data';

const trace = makeTracer('OrKit', false);

export const INVITATION_MAKERS_DESC = 'oracle invitation';

Expand All @@ -15,6 +19,7 @@ export const INVITATION_MAKERS_DESC = 'oracle invitation';

/**
* @typedef {object} OracleStatus
* @property {boolean} [disabled]
* @property {bigint} lastReportedRound
* @property {bigint} lastStartedRound
* @property {bigint} latestSubmission
Expand All @@ -29,7 +34,7 @@ export const INVITATION_MAKERS_DESC = 'oracle invitation';
*/
/** @typedef {ImmutableState & MutableState} State */

const oracleAdminKind = makeKindHandle('OracleAdmin');
const oracleKitKind = makeKindHandle('OracleKit');

/**
* @param {HeldParams} heldParams
Expand All @@ -39,63 +44,81 @@ const initState = ({ oracleId, roundPowers }) => {
return {
oracleId,
roundPowers,
disabled: false,
lastReportedRound: 0n,
lastStartedRound: 0n,
latestSubmission: 0n,
};
};

const OracleAdminI = M.interface('OracleAdmin', {
const AdminI = M.interface('OracleKitAdmin', {
disable: M.call().returns(),
});

const OracleI = M.interface('Oracle', {
pushPrice: M.call({ roundId: M.any(), unitPrice: M.bigint() }).returns(
M.promise(),
),
getStatus: M.call().returns(M.record()),
});

export const makeOracleAdmin = defineDurableExoClass(
oracleAdminKind,
OracleAdminI,
export const makeOracleAdminKit = defineDurableExoClassKit(
oracleKitKind,
{ admin: AdminI, oracle: OracleI },
initState,
{
/**
* push a unitPrice result from this oracle
*
* @param {PriceDatum} datum
*/
async pushPrice({ roundId: roundIdRaw = undefined, unitPrice: valueRaw }) {
const { state } = this;
const { roundPowers } = state;
const result = await roundPowers.handlePush(
{
admin: {
disable() {
trace(`oracle ${this.state.oracleId} disabled`);
this.state.disabled = true;
},
},
oracle: {
/**
* push a unitPrice result from this oracle
*
* @param {PriceDatum} datum
*/
async pushPrice({
roundId: roundIdRaw = undefined,
unitPrice: valueRaw,
}) {
const { state } = this;
!state.disabled || Fail`pushPrice for disabled oracle`;
const { roundPowers } = state;
const result = await roundPowers.handlePush(
{
oracleId: state.oracleId,
lastReportedRound: state.lastReportedRound,
lastStartedRound: state.lastStartedRound,
latestSubmission: state.latestSubmission,
},
{
roundId: roundIdRaw,
unitPrice: valueRaw,
},
);

state.lastReportedRound = result.lastReportedRound;
state.lastStartedRound = result.lastStartedRound;
state.latestSubmission = result.latestSubmission;
},
/**
*
* @returns {OracleStatus}
*/
getStatus() {
const { state } = this;
return {
oracleId: state.oracleId,
disabled: state.disabled,
lastReportedRound: state.lastReportedRound,
lastStartedRound: state.lastStartedRound,
latestSubmission: state.latestSubmission,
},
{
roundId: roundIdRaw,
unitPrice: valueRaw,
},
);

state.lastReportedRound = result.lastReportedRound;
state.lastStartedRound = result.lastStartedRound;
state.latestSubmission = result.latestSubmission;
},
/**
*
* @returns {OracleStatus}
*/
getStatus() {
const { state } = this;
return {
oracleId: state.oracleId,
lastReportedRound: state.lastReportedRound,
lastStartedRound: state.lastStartedRound,
latestSubmission: state.latestSubmission,
};
};
},
},
},
);

/** @typedef {ReturnType<typeof makeOracleAdmin>} OracleAdmin */
/** @typedef {ReturnType<typeof makeOracleAdminKit>} OracleKit */
Loading

0 comments on commit bcf33fe

Please sign in to comment.