Merge branch 'master' into resubmit_sol_srm

This commit is contained in:
Ralfs 2021-06-02 20:25:56 +03:00 committed by GitHub
commit 88de4f5669
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 164 additions and 1 deletions

View File

@ -54,6 +54,23 @@ not use this key for production!
NOTE 2: You might get error messages if somebody else is also running the
oracle.
### Manual price feed
Alternatively, you can submit prices to the oracle manually by instructing the oracle to watch for changes to a local file.
This can be useful for testing specific behaviour (such as triggering liquidations).
Run the oracle:
```
yarn solink oracle-file {pair} {filepath}
```
{pair} must be one of the aggregator pairs in deploy.sandbox.json
Then you can update prices by running
```
echo {price} > {filepath}
```
# Observe The Aggregators
With the oracle running, you can subscribe to price changes. In another

67
config/setup.mainnet.json Normal file
View File

@ -0,0 +1,67 @@
{
"aggregators": {
"btc:usd": {
"decimals": 2,
"minSubmissions": 1,
"maxSubmissions": 3,
"restartDelay": 0,
"rewardAmount": 10000,
"rewardTokenAccount": "3oLHHTaRqNsuTMjsTtkVy8bock6Bx8gCmDxku4TurVj1",
"oracles": [
"blockworks",
"bartosz",
"defacto"
]
},
"eth:usd": {
"decimals": 2,
"minSubmissions": 1,
"maxSubmissions": 3,
"restartDelay": 0,
"rewardAmount": 10000,
"rewardTokenAccount": "3oLHHTaRqNsuTMjsTtkVy8bock6Bx8gCmDxku4TurVj1",
"oracles": [
"blockworks",
"bartosz",
"defacto"
]
},
"sol:usd": {
"decimals": 2,
"minSubmissions": 1,
"maxSubmissions": 3,
"restartDelay": 0,
"rewardAmount": 10000,
"rewardTokenAccount": "3oLHHTaRqNsuTMjsTtkVy8bock6Bx8gCmDxku4TurVj1",
"oracles": [
"blockworks",
"bartosz",
"defacto"
]
},
"srm:usd": {
"decimals": 2,
"minSubmissions": 1,
"maxSubmissions": 3,
"restartDelay": 0,
"rewardAmount": 10000,
"rewardTokenAccount": "3oLHHTaRqNsuTMjsTtkVy8bock6Bx8gCmDxku4TurVj1",
"oracles": [
"blockworks",
"bartosz",
"defacto"
]
}
},
"oracles": {
"blockworks": {
"owner": "GW6bnJN6cMNzVnoVfV9hW6vx6XxTfP8k3HA1PgWCumxV"
},
"bartosz": {
"owner": "3cGZFMZavPHzciggMLWzT74qdaakNAosMwQokHTEKmbx"
},
"defacto": {
"owner": "6KwCmCtjmaQg3jbX7dejnB29RqMByx32KryX3Lyuqmq8"
}
}
}

View File

@ -10,6 +10,8 @@ import { PriceFeeder } from "./PriceFeeder"
import { sleep, walletFromEnv } from "./utils"
import { PublicKey, Wallet } from "solray"
import { log } from "./log"
import { Submitter } from "./Submitter"
import { file } from "./feeds"
const cli = new Command()
@ -86,4 +88,51 @@ cli.command("observe").action(async (name?: string) => {
}
})
cli.command("oracle-file <pair> <path>").action(async (pair, path) => {
console.log(pair);
console.log(path);
let deployInfo = loadJSONFile<AggregatorDeployFile>(process.env.DEPLOY_FILE!)
// validate pair arg here
if (!(pair in deployInfo.aggregators)) {
throw 'Invalid pair ' + pair;
}
let slot = await conn.getSlot()
conn.onSlotChange((slotInfo) => {
slot = slotInfo.slot
})
const wallet = await walletFromEnv("ORACLE_MNEMONIC", conn)
// await maybeRequestAirdrop(wallet.pubkey)
let aggregatorInfo = deployInfo.aggregators[pair];
const oracleInfo = Object.values(aggregatorInfo.oracles).find(
(oracleInfo) => {
return oracleInfo.owner.equals(wallet.pubkey)
}
)
let minValueChangeForNewRound = 0
const submitter = new Submitter(
deployInfo.programID,
aggregatorInfo.pubkey,
oracleInfo!.pubkey,
wallet,
file(pair, path),
{
minValueChangeForNewRound,
},
() => slot
)
submitter.start();
})
cli.parse(process.argv)

View File

@ -6,7 +6,7 @@ import { eventsIter, median, notify } from "./utils"
import { log } from "./log"
import winston from "winston"
import fs from "fs";
const SECONDS = 1000
export const UPDATE = "UPDATE"
@ -292,6 +292,7 @@ export class Binance extends PriceFeed {
const quoteCurrency = payload.s.slice(3).toLowerCase();
const pair = `${baseCurrency}:${quoteCurrency == 'busd' ? 'usd' : quoteCurrency}`;
const price: IPrice = {
source: Binance.name,
pair,
@ -511,3 +512,32 @@ export function coinbase(pair: string): IPriceFeed {
return eventsIter(emitter, UPDATE)
}
export function file(pair: string, filepath: string): IPriceFeed {
const emitter = new EventEmitter()
try {
fs.accessSync(filepath);
} catch {
fs.writeFileSync(filepath, '');
console.log('feed file created at ' + filepath)
}
console.log('started file feed for ' + pair)
fs.watch(filepath, (event) => {
if (event === 'change') {
const data = fs.readFileSync(filepath, 'utf8')
const price: IPrice = {
source: "file",
pair,
decimals: 2,
value: parseFloat(data)
}
console.log('price update: ', price)
emitter.emit(UPDATE, price)
}
});
return eventsIter(emitter, UPDATE)
}