Skip to content

Commit

Permalink
Merge pull request #7205 from Agoric/7192-oracle-error
Browse files Browse the repository at this point in the history
fix(oracle): default restartDelay parameter
  • Loading branch information
mergify[bot] authored Mar 23, 2023
2 parents 5933241 + 3aa2b5d commit a1c0b7a
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 21 deletions.
15 changes: 10 additions & 5 deletions packages/agoric-cli/src/commands/oracle.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@
// @ts-check
/* eslint-disable func-names */
/* global fetch */
import { Nat } from '@endo/nat';
import { Command } from 'commander';
import { inspect } from 'util';
import { makeRpcUtils, storageHelper } from '../lib/rpc.js';
import { outputAction } from '../lib/wallet.js';

const { agoricNames, fromBoard, vstorage } = await makeRpcUtils({ fetch });

// XXX support other decimal places
const COSMOS_UNIT = 1_000_000n;
const scaleDecimals = num => BigInt(num * Number(COSMOS_UNIT));

/**
*
* @param {import('anylogger').Logger} logger
Expand Down Expand Up @@ -120,19 +125,19 @@ export const makeOracleCommand = async logger => {
'offer that had continuing invitation result',
Number,
)
.requiredOption('--price [number]', 'price (per unitAmount)', BigInt)
.requiredOption('--roundId [number]', 'round', Number)
.requiredOption('--price [number]', 'price', Number)
.option('--roundId [number]', 'round', Number)
.action(async function (opts) {
const unitPrice = scaleDecimals(opts.price);
const roundId = 'roundId' in opts ? Nat(opts.roundId) : undefined;
/** @type {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */
const offer = {
id: Number(opts.offerId),
invitationSpec: {
source: 'continuing',
previousOffer: opts.oracleAdminAcceptOfferId,
invitationMakerName: 'PushPrice',
invitationArgs: harden([
{ unitPrice: opts.price, roundId: opts.roundId },
]),
invitationArgs: harden([{ unitPrice, roundId }]),
},
proposal: {},
};
Expand Down
32 changes: 25 additions & 7 deletions packages/agoric-cli/test/agops-oracle-smoketest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ ORACLE2_OFFER_ID=$(jq -r ".body | fromjson | .offer.id" <"$ORACLE_OFFER")

# Use invitation result, with continuing invitationMakers to propose a vote
PROPOSAL_OFFER=$(mktemp -t agops.XXX)
bin/agops oracle pushPriceRound --price 101 --roundId 1 --oracleAdminAcceptOfferId "$ORACLE_OFFER_ID" >|"$PROPOSAL_OFFER"
bin/agops oracle pushPriceRound --price 0.101 --roundId 1 --oracleAdminAcceptOfferId "$ORACLE_OFFER_ID" >|"$PROPOSAL_OFFER"
jq ".body | fromjson" <"$PROPOSAL_OFFER"
agoric wallet send --offer "$PROPOSAL_OFFER" --from gov1 --keyring-backend="test"

# submit another price in the round from the second oracle
PROPOSAL_OFFER=$(mktemp -t agops.XXX)
bin/agops oracle pushPriceRound --price 201 --roundId 1 --oracleAdminAcceptOfferId "$ORACLE2_OFFER_ID" >|"$PROPOSAL_OFFER"
bin/agops oracle pushPriceRound --price 0.201 --roundId 1 --oracleAdminAcceptOfferId "$ORACLE2_OFFER_ID" >|"$PROPOSAL_OFFER"
jq ".body | fromjson" <"$PROPOSAL_OFFER"
agoric wallet send --offer "$PROPOSAL_OFFER" --from gov2 --keyring-backend="test"

Expand All @@ -64,14 +64,32 @@ agd query vstorage keys published.priceFeed
agoric follow :published.priceFeed.ATOM-USD_price_feed.latestRound

# Set it to $13 per ATOM
# second round, second oracle has to be first this time (alternating start)
PROPOSAL_OFFER=$(mktemp -t agops.XXX)
bin/agops oracle pushPriceRound --price 14.0 --roundId 2 --oracleAdminAcceptOfferId "$ORACLE2_OFFER_ID" >|"$PROPOSAL_OFFER"
agoric wallet send --offer "$PROPOSAL_OFFER" --from gov2 --keyring-backend="test"
# second round, first oracle
PROPOSAL_OFFER=$(mktemp -t agops.XXX)
bin/agops oracle pushPriceRound --price 120000000 --roundId 2 --oracleAdminAcceptOfferId "$ORACLE_OFFER_ID" >|"$PROPOSAL_OFFER"
bin/agops oracle pushPriceRound --price 12.0 --roundId 2 --oracleAdminAcceptOfferId "$ORACLE_OFFER_ID" >|"$PROPOSAL_OFFER"
agoric wallet send --offer "$PROPOSAL_OFFER" --from gov1 --keyring-backend="test"
# second round, second oracle
PROPOSAL_OFFER=$(mktemp -t agops.XXX)
bin/agops oracle pushPriceRound --price 14000000 --roundId 2 --oracleAdminAcceptOfferId "$ORACLE2_OFFER_ID" >|"$PROPOSAL_OFFER"
agoric wallet send --offer "$PROPOSAL_OFFER" --from gov2 --keyring-backend="test"

# see new price
agoric follow :published.priceFeed.ATOM-USD_price_feed

# Set it to $20 per ATOM
PROPOSAL_OFFER=$(mktemp -t agops.XXX)
bin/agops oracle pushPriceRound --price 15.0 --roundId 3 --oracleAdminAcceptOfferId "$ORACLE_OFFER_ID" >|"$PROPOSAL_OFFER"
agoric wallet send --offer "$PROPOSAL_OFFER" --from gov1 --keyring-backend="test"
# second oracle
PROPOSAL_OFFER=$(mktemp -t agops.XXX)
bin/agops oracle pushPriceRound --price 25.0 --roundId 3 --oracleAdminAcceptOfferId "$ORACLE2_OFFER_ID" >|"$PROPOSAL_OFFER"
agoric wallet send --offer "$PROPOSAL_OFFER" --from gov2 --keyring-backend="test"

# leave round unspecified for contract to suggest ($21.2)
PROPOSAL_OFFER=$(mktemp -t agops.XXX)
bin/agops oracle pushPriceRound --price 21.0 --oracleAdminAcceptOfferId "$ORACLE2_OFFER_ID" >|"$PROPOSAL_OFFER"
agoric wallet send --offer "$PROPOSAL_OFFER" --from gov2 --keyring-backend="test"
# alternate
PROPOSAL_OFFER=$(mktemp -t agops.XXX)
bin/agops oracle pushPriceRound --price 21.4 --oracleAdminAcceptOfferId "$ORACLE_OFFER_ID" >|"$PROPOSAL_OFFER"
agoric wallet send --offer "$PROPOSAL_OFFER" --from gov1 --keyring-backend="test"
2 changes: 1 addition & 1 deletion packages/inter-protocol/scripts/price-feed-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const DEFAULT_CONTRACT_TERMS = {
POLL_INTERVAL: 30n,
maxSubmissionCount: 1000,
minSubmissionCount: 1,
restartDelay: 5, // in seconds according to chainTimerService
restartDelay: 1, // the number of rounds an Oracle has to wait before they can initiate another round
timeout: 10, // in seconds according to chainTimerService
minSubmissionValue: 1n,
maxSubmissionValue: 2n ** 256n,
Expand Down
2 changes: 1 addition & 1 deletion packages/inter-protocol/src/price/fluxAggregator.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const priceDescriptionFromQuote = quote => quote.quoteAmount.value[0];
* @typedef {object} ChainlinkConfig
* @property {number} maxSubmissionCount
* @property {number} minSubmissionCount
* @property {RelativeTimeValue} restartDelay the number of rounds an Oracle has to wait before they can initiate a round
* @property {bigint} restartDelay the number of rounds an Oracle has to wait before they can initiate a round
* @property {number} minSubmissionValue an immutable check for a lower bound of what
* submission values are accepted from an oracle
* @property {number} maxSubmissionValue an immutable check for an upper bound of what
Expand Down
9 changes: 6 additions & 3 deletions packages/inter-protocol/src/price/priceOracleKit.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,12 @@ const AdminI = M.interface('OracleKitAdmin', {
});

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

Expand Down
4 changes: 3 additions & 1 deletion packages/inter-protocol/src/price/roundsManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,9 @@ export const makeRoundsManagerKit = defineDurableExoClassKit(
const { helper } = this.facets;
const { details } = this.state;
helper.acceptingSubmissions(roundId) ||
Fail`round not accepting submissions`;
Fail`round ${q(
Number(roundId),
)} not accepting submissions from oracle ${q(status.oracleId)}`;

const lastRoundDetails = details.get(roundId);
details.set(roundId, {
Expand Down
9 changes: 6 additions & 3 deletions packages/inter-protocol/test/price/test-fluxAggregator.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ test('basic', async t => {
// should ONLY be between the OracleB and C values, which is why it is 25000
await oracleTimer.tick();
await t.throwsAsync(E(oracleA).pushPrice({ roundId: 2, unitPrice: 1000n }), {
message: 'round not accepting submissions',
message:
'round 2 not accepting submissions from oracle "agorice1priceOracleA"',
});
await E(oracleB).pushPrice({ roundId: 2, unitPrice: 2000n });
await E(oracleC).pushPrice({ roundId: 2, unitPrice: 3000n });
Expand Down Expand Up @@ -342,7 +343,8 @@ test('interleaved', async t => {
await oracleTimer.tick();
// round 3 is NOT yet supersedeable (since no value present and not yet timed out), so these should fail
await t.throwsAsync(E(oracleA).pushPrice({ roundId: 4, unitPrice: 4000n }), {
message: 'round not accepting submissions',
message:
'round 4 not accepting submissions from oracle "agorice1priceOracleA"',
});
await E(oracleB).pushPrice({ roundId: 4, unitPrice: 5000n });
await E(oracleC).pushPrice({ roundId: 4, unitPrice: 6000n });
Expand Down Expand Up @@ -620,7 +622,8 @@ test('notifications', async t => {
);

await t.throwsAsync(E(oracleA).pushPrice({ roundId: 2, unitPrice: 1000n }), {
message: 'round not accepting submissions',
message:
'round 2 not accepting submissions from oracle "agorice1priceOracleA"',
});
// A started last round so fails to start next round
t.deepEqual(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ const acceptInvitation = async (wallet, priceAggregator) => {
};

let pushPriceCounter = 0;
/**
* @param {*} wallet
* @param {string} adminOfferId
* @param {import('@agoric/inter-protocol/src/price/roundsManager.js').PriceRound} priceRound
* @returns
*/
const pushPrice = async (wallet, adminOfferId, priceRound) => {
/** @type {import('@agoric/smart-wallet/src/invitations.js').ContinuingInvitationSpec} */
const proposeInvitationSpec = {
Expand Down

0 comments on commit a1c0b7a

Please sign in to comment.