solana.js: save result fixes
This commit is contained in:
parent
3309e086c1
commit
bee8ef1d24
|
@ -23,7 +23,10 @@ import { QueueAccount } from './queueAccount';
|
||||||
import { LeaseAccount, LeaseExtendParams } from './leaseAccount';
|
import { LeaseAccount, LeaseExtendParams } from './leaseAccount';
|
||||||
import { PermissionAccount } from './permissionAccount';
|
import { PermissionAccount } from './permissionAccount';
|
||||||
import * as spl from '@solana/spl-token';
|
import * as spl from '@solana/spl-token';
|
||||||
import { TransactionObject } from '../TransactionObject';
|
import {
|
||||||
|
TransactionObject,
|
||||||
|
TransactionObjectOptions,
|
||||||
|
} from '../TransactionObject';
|
||||||
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
||||||
import { AggregatorHistoryBuffer } from './aggregatorHistoryBuffer';
|
import { AggregatorHistoryBuffer } from './aggregatorHistoryBuffer';
|
||||||
import { CrankAccount } from './crankAccount';
|
import { CrankAccount } from './crankAccount';
|
||||||
|
@ -1306,42 +1309,19 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
||||||
return txnSignature;
|
return txnSignature;
|
||||||
}
|
}
|
||||||
|
|
||||||
public saveResultInstruction(
|
public saveResultInstructionSync(
|
||||||
params: {
|
payer: PublicKey,
|
||||||
queueAccount: QueueAccount;
|
params: AggregatorSaveResultSyncParams,
|
||||||
queueAuthority: PublicKey;
|
options?: TransactionObjectOptions
|
||||||
feedPermission: [PermissionAccount, number];
|
): TransactionObject {
|
||||||
jobs: Array<OracleJob>;
|
|
||||||
// oracle
|
|
||||||
oracleAccount: OracleAccount;
|
|
||||||
oracleAuthority: PublicKey;
|
|
||||||
oracleIdx: number;
|
|
||||||
oraclePermission: [PermissionAccount, number];
|
|
||||||
// response
|
|
||||||
value: Big;
|
|
||||||
minResponse: Big;
|
|
||||||
maxResponse: Big;
|
|
||||||
// token
|
|
||||||
mint: PublicKey;
|
|
||||||
payoutWallet: PublicKey;
|
|
||||||
lease: [LeaseAccount, number];
|
|
||||||
leaseEscrow: PublicKey;
|
|
||||||
} & Partial<{
|
|
||||||
error?: boolean;
|
|
||||||
historyBuffer?: PublicKey;
|
|
||||||
oracles: Array<types.OracleAccountData>;
|
|
||||||
}>
|
|
||||||
): TransactionInstruction {
|
|
||||||
const [leaseAccount, leaseBump] = params.lease;
|
|
||||||
const [feedPermissionAccount, feedPermissionBump] = params.feedPermission;
|
|
||||||
const [oraclePermissionAccount, oraclePermissionBump] =
|
const [oraclePermissionAccount, oraclePermissionBump] =
|
||||||
params.oraclePermission;
|
params.oraclePermission;
|
||||||
|
|
||||||
if (params.oracleIdx < 0) {
|
if (params.oracleIdx < 0 || params.oracleIdx > params.oracles.length - 1) {
|
||||||
throw new Error('Failed to find oracle in current round');
|
throw new Error('Failed to find oracle in current round');
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.aggregatorSaveResult(
|
const saveResultIxn = types.aggregatorSaveResult(
|
||||||
this.program,
|
this.program,
|
||||||
{
|
{
|
||||||
params: {
|
params: {
|
||||||
|
@ -1353,108 +1333,73 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
||||||
.borsh,
|
.borsh,
|
||||||
maxResponse: types.SwitchboardDecimal.fromBig(params.maxResponse)
|
maxResponse: types.SwitchboardDecimal.fromBig(params.maxResponse)
|
||||||
.borsh,
|
.borsh,
|
||||||
feedPermissionBump: feedPermissionBump,
|
feedPermissionBump: params.permissionBump,
|
||||||
oraclePermissionBump: oraclePermissionBump,
|
oraclePermissionBump: oraclePermissionBump,
|
||||||
leaseBump: leaseBump,
|
leaseBump: params.leaseBump,
|
||||||
stateBump: this.program.programState.bump,
|
stateBump: this.program.programState.bump,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
aggregator: this.publicKey,
|
aggregator: this.publicKey,
|
||||||
oracle: params.oracleAccount.publicKey,
|
oracle: params.oracles[params.oracleIdx].account.publicKey,
|
||||||
oracleAuthority: params.oracleAuthority,
|
oracleAuthority: params.oracles[params.oracleIdx].state.oracleAuthority,
|
||||||
oracleQueue: params.queueAccount.publicKey,
|
oracleQueue: params.queueAccount.publicKey,
|
||||||
queueAuthority: params.queueAuthority,
|
queueAuthority: params.queueAuthority,
|
||||||
feedPermission: feedPermissionAccount.publicKey,
|
feedPermission: params.permissionAccount.publicKey,
|
||||||
oraclePermission: oraclePermissionAccount.publicKey,
|
oraclePermission: oraclePermissionAccount.publicKey,
|
||||||
lease: leaseAccount.publicKey,
|
lease: params.leaseAccount.publicKey,
|
||||||
escrow: params.leaseEscrow,
|
escrow: params.leaseEscrow,
|
||||||
tokenProgram: spl.TOKEN_PROGRAM_ID,
|
tokenProgram: spl.TOKEN_PROGRAM_ID,
|
||||||
programState: this.program.programState.publicKey,
|
programState: this.program.programState.publicKey,
|
||||||
historyBuffer: params.historyBuffer ?? this.publicKey,
|
historyBuffer: params.historyBuffer ?? this.publicKey,
|
||||||
mint: params.mint,
|
mint: this.program.mint.address,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
public async saveResult(
|
|
||||||
params: {
|
|
||||||
jobs: Array<OracleJob>;
|
|
||||||
oracleAccount: OracleAccount;
|
|
||||||
value: Big;
|
|
||||||
minResponse: Big;
|
|
||||||
maxResponse: Big;
|
|
||||||
} & Partial<{
|
|
||||||
queueAccount: QueueAccount;
|
|
||||||
queueAuthority: PublicKey;
|
|
||||||
aggregator: types.AggregatorAccountData;
|
|
||||||
feedPermission: [PermissionAccount, number];
|
|
||||||
historyBuffer: PublicKey;
|
|
||||||
oracleIdx: number;
|
|
||||||
oracleAuthority: PublicKey;
|
|
||||||
oraclePermission: [PermissionAccount, number];
|
|
||||||
error: boolean;
|
|
||||||
mint: PublicKey;
|
|
||||||
payoutWallet: PublicKey;
|
|
||||||
lease: [LeaseAccount, number];
|
|
||||||
leaseEscrow: PublicKey;
|
|
||||||
oracles: Array<types.OracleAccountData>;
|
|
||||||
}>
|
|
||||||
): Promise<TransactionSignature> {
|
|
||||||
const payer = this.program.walletPubkey;
|
|
||||||
const aggregator = params.aggregator ?? (await this.loadData());
|
|
||||||
|
|
||||||
const remainingAccounts: Array<PublicKey> = [];
|
const remainingAccounts: Array<PublicKey> = [];
|
||||||
for (let i = 0; i < aggregator.oracleRequestBatchSize; ++i) {
|
params.oracles.forEach(oracle =>
|
||||||
remainingAccounts.push(aggregator.currentRound.oraclePubkeysData[i]);
|
remainingAccounts.push(oracle.account.publicKey)
|
||||||
}
|
);
|
||||||
for (const oracle of params?.oracles ??
|
params.oracles.forEach(oracle =>
|
||||||
(await this.loadCurrentRoundOracles(aggregator)).map(a => a.state)) {
|
remainingAccounts.push(oracle.state.tokenAccount)
|
||||||
remainingAccounts.push(oracle.tokenAccount);
|
);
|
||||||
}
|
|
||||||
remainingAccounts.push(this.slidingWindowKey);
|
remainingAccounts.push(this.slidingWindowKey);
|
||||||
|
|
||||||
|
saveResultIxn.keys.push(
|
||||||
|
...remainingAccounts.map((pubkey): AccountMeta => {
|
||||||
|
return { isSigner: false, isWritable: true, pubkey };
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return new TransactionObject(payer, [saveResultIxn], [], options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async saveResultInstruction(
|
||||||
|
payer: PublicKey,
|
||||||
|
params: AggregatorSaveResultAsyncParams,
|
||||||
|
options?: TransactionObjectOptions
|
||||||
|
): Promise<TransactionObject> {
|
||||||
|
const aggregator = params.aggregator ?? (await this.loadData());
|
||||||
|
|
||||||
|
const oracles =
|
||||||
|
params.oracles ?? (await this.loadCurrentRoundOracles(aggregator));
|
||||||
|
|
||||||
const oracleIdx =
|
const oracleIdx =
|
||||||
params.oracleIdx ??
|
params.oracleIdx ??
|
||||||
aggregator.currentRound.oraclePubkeysData
|
oracles.findIndex(o =>
|
||||||
.slice(0, aggregator.oracleRequestBatchSize)
|
o.account.publicKey.equals(params.oracleAccount.publicKey)
|
||||||
.findIndex(o => o.equals(params.oracleAccount.publicKey));
|
);
|
||||||
|
|
||||||
if (oracleIdx < 0) {
|
if (oracleIdx < 0 || oracleIdx > oracles.length - 1) {
|
||||||
throw new Error('Failed to find oracle in current round');
|
throw new Error('Failed to find oracle in current round');
|
||||||
}
|
}
|
||||||
|
|
||||||
const ixns: Array<TransactionInstruction> = [];
|
|
||||||
|
|
||||||
const payoutWallet =
|
|
||||||
params.payoutWallet ?? this.program.mint.getAssociatedAddress(payer);
|
|
||||||
const payoutWalletAccountInfo =
|
|
||||||
await this.program.connection.getAccountInfo(payoutWallet);
|
|
||||||
if (payoutWalletAccountInfo === null) {
|
|
||||||
const [createTokenAccountTxn] =
|
|
||||||
this.program.mint.createAssocatedUserInstruction(payer);
|
|
||||||
ixns.push(...createTokenAccountTxn.ixns);
|
|
||||||
}
|
|
||||||
|
|
||||||
const queueAccount =
|
const queueAccount =
|
||||||
params.queueAccount ??
|
params.queueAccount ??
|
||||||
new QueueAccount(this.program, aggregator.queuePubkey);
|
new QueueAccount(this.program, aggregator.queuePubkey);
|
||||||
|
|
||||||
let queueAuthority = params.queueAuthority;
|
const queueAuthority =
|
||||||
let mint = params.mint;
|
params.queueAuthority ?? (await queueAccount.loadData()).authority;
|
||||||
if (!queueAuthority || !mint) {
|
|
||||||
const queue = await queueAccount.loadData();
|
|
||||||
queueAuthority = queue.authority;
|
|
||||||
mint = mint ?? queue.mint ?? spl.NATIVE_MINT;
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
|
||||||
permissionAccount,
|
|
||||||
permissionBump,
|
|
||||||
leaseAccount,
|
|
||||||
leaseBump,
|
|
||||||
leaseEscrow,
|
|
||||||
} = this.getAccounts(queueAccount, queueAuthority);
|
|
||||||
|
|
||||||
const [oraclePermissionAccount, oraclePermissionBump] =
|
const [oraclePermissionAccount, oraclePermissionBump] =
|
||||||
params.oraclePermission ??
|
params.oraclePermission ??
|
||||||
|
@ -1464,50 +1409,54 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
||||||
queueAccount.publicKey,
|
queueAccount.publicKey,
|
||||||
params.oracleAccount.publicKey
|
params.oracleAccount.publicKey
|
||||||
);
|
);
|
||||||
try {
|
|
||||||
await oraclePermissionAccount.loadData();
|
|
||||||
} catch (_) {
|
|
||||||
throw new Error(
|
|
||||||
'A requested oracle permission pda account has not been initialized.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const historyBuffer = params.historyBuffer ?? aggregator.historyBuffer;
|
const accounts: AggregatorPdaAccounts =
|
||||||
|
params.permissionAccount === undefined ||
|
||||||
|
params.leaseAccount === undefined ||
|
||||||
|
params.leaseEscrow === undefined ||
|
||||||
|
params.permissionBump === undefined ||
|
||||||
|
params.leaseBump === undefined
|
||||||
|
? this.getAccounts(queueAccount, queueAuthority)
|
||||||
|
: {
|
||||||
|
permissionAccount: params.permissionAccount,
|
||||||
|
permissionBump: params.permissionBump,
|
||||||
|
leaseAccount: params.leaseAccount,
|
||||||
|
leaseBump: params.leaseBump,
|
||||||
|
leaseEscrow: params.leaseEscrow,
|
||||||
|
};
|
||||||
|
|
||||||
const saveResultIxn = this.saveResultInstruction({
|
const saveResultTxn = this.saveResultInstructionSync(
|
||||||
queueAccount,
|
payer,
|
||||||
queueAuthority,
|
{
|
||||||
feedPermission: [permissionAccount, permissionBump],
|
...accounts,
|
||||||
jobs: params.jobs,
|
queueAccount,
|
||||||
historyBuffer: historyBuffer.equals(PublicKey.default)
|
queueAuthority,
|
||||||
? undefined
|
jobs: params.jobs,
|
||||||
: historyBuffer,
|
historyBuffer: aggregator.historyBuffer.equals(PublicKey.default)
|
||||||
oracleAccount: params.oracleAccount,
|
? undefined
|
||||||
oracleAuthority: (await params.oracleAccount.loadData()).oracleAuthority,
|
: aggregator.historyBuffer,
|
||||||
oracleIdx,
|
oracleIdx,
|
||||||
oraclePermission: [oraclePermissionAccount, oraclePermissionBump],
|
oraclePermission: [oraclePermissionAccount, oraclePermissionBump],
|
||||||
value: params.value,
|
value: params.value,
|
||||||
minResponse: params.minResponse,
|
minResponse: params.minResponse,
|
||||||
maxResponse: params.maxResponse,
|
maxResponse: params.maxResponse,
|
||||||
error: params.error ?? false,
|
error: params.error ?? false,
|
||||||
mint,
|
aggregator: aggregator,
|
||||||
payoutWallet: payoutWallet,
|
oracles: oracles,
|
||||||
lease: [leaseAccount, leaseBump],
|
},
|
||||||
leaseEscrow: leaseEscrow,
|
options
|
||||||
});
|
|
||||||
|
|
||||||
// add remaining accounts
|
|
||||||
saveResultIxn.keys.push(
|
|
||||||
...remainingAccounts.map((pubkey): AccountMeta => {
|
|
||||||
return { isSigner: false, isWritable: true, pubkey };
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
|
return saveResultTxn;
|
||||||
|
}
|
||||||
|
|
||||||
ixns.push(saveResultIxn);
|
public async saveResult(
|
||||||
const saveResultTxn = new TransactionObject(
|
params: AggregatorSaveResultAsyncParams,
|
||||||
|
options?: TransactionObjectOptions
|
||||||
|
): Promise<TransactionSignature> {
|
||||||
|
const saveResultTxn = await this.saveResultInstruction(
|
||||||
this.program.walletPubkey,
|
this.program.walletPubkey,
|
||||||
ixns,
|
params,
|
||||||
[]
|
options
|
||||||
);
|
);
|
||||||
const txnSignature = await this.program.signAndSend(saveResultTxn);
|
const txnSignature = await this.program.signAndSend(saveResultTxn);
|
||||||
return txnSignature;
|
return txnSignature;
|
||||||
|
@ -2054,3 +2003,30 @@ export type AggregatorPdaAccounts = {
|
||||||
leaseBump: number;
|
leaseBump: number;
|
||||||
leaseEscrow: PublicKey;
|
leaseEscrow: PublicKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type SaveResultResponse = {
|
||||||
|
jobs: Array<OracleJob>;
|
||||||
|
// oracleAccount: OracleAccount;
|
||||||
|
value: Big;
|
||||||
|
minResponse: Big;
|
||||||
|
maxResponse: Big;
|
||||||
|
error?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SaveResultAccounts = AggregatorPdaAccounts & {
|
||||||
|
aggregator: types.AggregatorAccountData;
|
||||||
|
// queue
|
||||||
|
queueAccount: QueueAccount;
|
||||||
|
queueAuthority: PublicKey;
|
||||||
|
// oracle
|
||||||
|
oraclePermission: [PermissionAccount, number];
|
||||||
|
oracles: Array<{ account: OracleAccount; state: types.OracleAccountData }>;
|
||||||
|
oracleIdx: number;
|
||||||
|
// history
|
||||||
|
historyBuffer?: PublicKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AggregatorSaveResultSyncParams = SaveResultResponse &
|
||||||
|
SaveResultAccounts;
|
||||||
|
export type AggregatorSaveResultAsyncParams = SaveResultResponse &
|
||||||
|
(Partial<SaveResultAccounts> & { oracleAccount: OracleAccount });
|
||||||
|
|
Loading…
Reference in New Issue