solana.js: added aggregator transfer tests
This commit is contained in:
parent
3f34dd61e8
commit
ae9eb8e05e
|
@ -454,7 +454,7 @@ export class LeaseAccount extends Account<types.LeaseAccountData> {
|
||||||
params: {
|
params: {
|
||||||
amount: number;
|
amount: number;
|
||||||
unwrap?: boolean;
|
unwrap?: boolean;
|
||||||
withdrawWallet?: PublicKey;
|
withdrawWallet: PublicKey;
|
||||||
withdrawAuthority?: Keypair;
|
withdrawAuthority?: Keypair;
|
||||||
}
|
}
|
||||||
): Promise<TransactionObject> {
|
): Promise<TransactionObject> {
|
||||||
|
@ -464,20 +464,9 @@ export class LeaseAccount extends Account<types.LeaseAccountData> {
|
||||||
const withdrawAuthority = params.withdrawAuthority
|
const withdrawAuthority = params.withdrawAuthority
|
||||||
? params.withdrawAuthority.publicKey
|
? params.withdrawAuthority.publicKey
|
||||||
: payer;
|
: payer;
|
||||||
const withdrawWallet = params.withdrawWallet
|
const withdrawWallet = params.withdrawWallet;
|
||||||
? params.withdrawWallet
|
|
||||||
: this.program.mint.getAssociatedAddress(withdrawAuthority);
|
|
||||||
|
|
||||||
// create token wallet if it doesnt exist
|
// // create token wallet if it doesnt exist
|
||||||
const withdrawWalletAccountInfo =
|
|
||||||
await this.program.connection.getAccountInfo(withdrawWallet);
|
|
||||||
if (withdrawWalletAccountInfo === null) {
|
|
||||||
const [createUserTxn] = this.program.mint.createAssocatedUserInstruction(
|
|
||||||
payer,
|
|
||||||
withdrawAuthority
|
|
||||||
);
|
|
||||||
txns.push(createUserTxn);
|
|
||||||
}
|
|
||||||
|
|
||||||
const lease = await this.loadData();
|
const lease = await this.loadData();
|
||||||
const accountInfos = await this.program.connection.getMultipleAccountsInfo([
|
const accountInfos = await this.program.connection.getMultipleAccountsInfo([
|
||||||
|
@ -558,7 +547,7 @@ export class LeaseAccount extends Account<types.LeaseAccountData> {
|
||||||
public async withdraw(params: {
|
public async withdraw(params: {
|
||||||
amount: number;
|
amount: number;
|
||||||
unwrap?: boolean;
|
unwrap?: boolean;
|
||||||
withdrawWallet?: PublicKey;
|
withdrawWallet: PublicKey;
|
||||||
withdrawAuthority?: Keypair;
|
withdrawAuthority?: Keypair;
|
||||||
}): Promise<TransactionSignature> {
|
}): Promise<TransactionSignature> {
|
||||||
const withdrawTxn = await this.withdrawInstruction(
|
const withdrawTxn = await this.withdrawInstruction(
|
||||||
|
|
|
@ -232,6 +232,7 @@ describe('Aggregator Tests', () => {
|
||||||
await leaseAccount.withdraw({
|
await leaseAccount.withdraw({
|
||||||
amount: 1,
|
amount: 1,
|
||||||
unwrap: true,
|
unwrap: true,
|
||||||
|
withdrawWallet: userTokenAddress,
|
||||||
});
|
});
|
||||||
|
|
||||||
const finalBalance = await leaseAccount.getBalance();
|
const finalBalance = await leaseAccount.getBalance();
|
||||||
|
@ -257,88 +258,6 @@ describe('Aggregator Tests', () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Transfers aggregator to a new queue', async () => {
|
|
||||||
const newQueueAuthority = Keypair.generate();
|
|
||||||
|
|
||||||
const [newQueue] = await sbv2.QueueAccount.create(ctx.program, {
|
|
||||||
name: 'new-queue',
|
|
||||||
metadata: '',
|
|
||||||
authority: newQueueAuthority.publicKey,
|
|
||||||
queueSize: 1,
|
|
||||||
reward: 0,
|
|
||||||
minStake: 0,
|
|
||||||
oracleTimeout: 86400,
|
|
||||||
slashingEnabled: false,
|
|
||||||
unpermissionedFeeds: true,
|
|
||||||
unpermissionedVrf: true,
|
|
||||||
enableBufferRelayers: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const [aggregatorAccount] = await queueAccount.createFeed({
|
|
||||||
queueAuthority: queueAuthority,
|
|
||||||
batchSize: 1,
|
|
||||||
minRequiredOracleResults: 1,
|
|
||||||
minRequiredJobResults: 1,
|
|
||||||
minUpdateDelaySeconds: 60,
|
|
||||||
fundAmount: 1.25,
|
|
||||||
enable: true,
|
|
||||||
jobs: [
|
|
||||||
{
|
|
||||||
weight: 1,
|
|
||||||
data: OracleJob.encodeDelimited(
|
|
||||||
OracleJob.fromObject({
|
|
||||||
tasks: [
|
|
||||||
{
|
|
||||||
valueTask: {
|
|
||||||
value: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
).finish(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
await aggregatorAccount.loadData();
|
|
||||||
|
|
||||||
await aggregatorAccount.transfer({
|
|
||||||
newQueue,
|
|
||||||
enable: true,
|
|
||||||
queueAuthority: newQueueAuthority,
|
|
||||||
});
|
|
||||||
|
|
||||||
const aggregator = await aggregatorAccount.loadData();
|
|
||||||
assert(
|
|
||||||
aggregator.queuePubkey.equals(newQueue.publicKey),
|
|
||||||
`Aggregator queue mismatch, expected ${newQueue.publicKey}, received ${aggregator.queuePubkey}`
|
|
||||||
);
|
|
||||||
|
|
||||||
const [newLeaseAccount] = LeaseAccount.fromSeed(
|
|
||||||
ctx.program,
|
|
||||||
newQueue.publicKey,
|
|
||||||
aggregatorAccount.publicKey
|
|
||||||
);
|
|
||||||
const balance = await newLeaseAccount.getBalance();
|
|
||||||
assert(
|
|
||||||
balance === 1.25,
|
|
||||||
`Aggregator did not transfer full lease balance, expected 1.25, received ${balance}`
|
|
||||||
);
|
|
||||||
|
|
||||||
const [newPermissionAccount] = PermissionAccount.fromSeed(
|
|
||||||
ctx.program,
|
|
||||||
newQueueAuthority.publicKey,
|
|
||||||
newQueue.publicKey,
|
|
||||||
aggregatorAccount.publicKey
|
|
||||||
);
|
|
||||||
const newPermission = await newPermissionAccount.loadData();
|
|
||||||
assert(
|
|
||||||
newPermission.permissions === PermitOracleQueueUsage.discriminator + 1,
|
|
||||||
`Aggregator permission mismatch, expected ${
|
|
||||||
PermitOracleQueueUsage.discriminator + 1
|
|
||||||
}, received ${newPermission.permissions}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Adds job, updates it's config, then removes it from aggregator", async () => {
|
it("Adds job, updates it's config, then removes it from aggregator", async () => {
|
||||||
const aggregatorKeypair = Keypair.generate();
|
const aggregatorKeypair = Keypair.generate();
|
||||||
const aggregatorAuthority = Keypair.generate();
|
const aggregatorAuthority = Keypair.generate();
|
||||||
|
|
|
@ -0,0 +1,239 @@
|
||||||
|
/* eslint-disable no-unused-vars */
|
||||||
|
import 'mocha';
|
||||||
|
|
||||||
|
import { setupTest, TestContext } from './utilts';
|
||||||
|
import { Keypair } from '@solana/web3.js';
|
||||||
|
import { AggregatorAccount, CrankAccount, QueueAccount } from '../src';
|
||||||
|
import { OracleJob } from '@switchboard-xyz/common';
|
||||||
|
import { assert } from 'console';
|
||||||
|
|
||||||
|
describe('Transfer Tests', () => {
|
||||||
|
let ctx: TestContext;
|
||||||
|
|
||||||
|
// const freshUser = Keypair.generate();
|
||||||
|
|
||||||
|
const origQueueAuthority = Keypair.generate();
|
||||||
|
let origQueueAccount: QueueAccount;
|
||||||
|
let origCrankAccount: CrankAccount;
|
||||||
|
|
||||||
|
const newQueueAuthority = Keypair.generate();
|
||||||
|
let newQueueAccount: QueueAccount;
|
||||||
|
let newCrankAccount: CrankAccount;
|
||||||
|
|
||||||
|
const aggregatorAuthority = Keypair.generate();
|
||||||
|
let aggregatorAccount: AggregatorAccount;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
ctx = await setupTest();
|
||||||
|
|
||||||
|
const [accounts, signatures] = await ctx.program.createNetwork({
|
||||||
|
name: 'Queue-1',
|
||||||
|
reward: 0,
|
||||||
|
minStake: 0,
|
||||||
|
unpermissionedFeeds: false,
|
||||||
|
unpermissionedVrf: false,
|
||||||
|
authority: origQueueAuthority.publicKey,
|
||||||
|
oracles: [
|
||||||
|
{ name: 'Oracle-1', enable: true, queueAuthority: origQueueAuthority },
|
||||||
|
],
|
||||||
|
cranks: [{ name: 'Crank-1', maxRows: 100 }],
|
||||||
|
});
|
||||||
|
if (accounts.oracles.length < 1) {
|
||||||
|
throw new Error(`Failed to create an oracle`);
|
||||||
|
}
|
||||||
|
if (accounts.cranks.length < 1) {
|
||||||
|
throw new Error(`Failed to create a crank`);
|
||||||
|
}
|
||||||
|
origQueueAccount = accounts.queueAccount;
|
||||||
|
origCrankAccount = accounts.cranks[0];
|
||||||
|
await accounts.oracles[0].account.heartbeat({
|
||||||
|
queueAccount: accounts.queueAccount,
|
||||||
|
queueAuthority: origQueueAuthority.publicKey,
|
||||||
|
});
|
||||||
|
|
||||||
|
const [accounts2, signatures2] = await ctx.program.createNetwork({
|
||||||
|
name: 'Queue-2',
|
||||||
|
reward: 0,
|
||||||
|
minStake: 0,
|
||||||
|
unpermissionedFeeds: false,
|
||||||
|
unpermissionedVrf: false,
|
||||||
|
authority: newQueueAuthority.publicKey,
|
||||||
|
oracles: [
|
||||||
|
{ name: 'Oracle-2', enable: true, queueAuthority: newQueueAuthority },
|
||||||
|
],
|
||||||
|
cranks: [{ name: 'Crank-2', maxRows: 100 }],
|
||||||
|
});
|
||||||
|
if (accounts2.oracles.length < 1) {
|
||||||
|
throw new Error(`Failed to create an oracle`);
|
||||||
|
}
|
||||||
|
if (accounts2.cranks.length < 1) {
|
||||||
|
throw new Error(`Failed to create a crank`);
|
||||||
|
}
|
||||||
|
newQueueAccount = accounts2.queueAccount;
|
||||||
|
newCrankAccount = accounts2.cranks[0];
|
||||||
|
await accounts2.oracles[0].account.heartbeat({
|
||||||
|
queueAccount: accounts2.queueAccount,
|
||||||
|
queueAuthority: newQueueAuthority.publicKey,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Creates an aggregator on the orig queue and crank', async () => {
|
||||||
|
[aggregatorAccount] = await origQueueAccount.createFeed({
|
||||||
|
name: 'Aggregator-1',
|
||||||
|
authority: aggregatorAuthority,
|
||||||
|
batchSize: 1,
|
||||||
|
minRequiredOracleResults: 1,
|
||||||
|
minRequiredJobResults: 1,
|
||||||
|
minUpdateDelaySeconds: 10,
|
||||||
|
crankPubkey: origCrankAccount.publicKey,
|
||||||
|
fundAmount: 0.65,
|
||||||
|
enable: true,
|
||||||
|
queueAuthority: origQueueAuthority,
|
||||||
|
jobs: [
|
||||||
|
{
|
||||||
|
data: OracleJob.encodeDelimited(
|
||||||
|
OracleJob.fromObject({
|
||||||
|
tasks: [
|
||||||
|
{
|
||||||
|
valueTask: {
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
).finish(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const aggregator = await aggregatorAccount.loadData();
|
||||||
|
const accounts = await aggregatorAccount.fetchAccounts(
|
||||||
|
aggregator,
|
||||||
|
origQueueAccount
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
accounts.aggregator.data.queuePubkey.equals(origQueueAccount.publicKey),
|
||||||
|
`Incorrect queue, expected ${origQueueAccount.publicKey}, received ${accounts.aggregator.data.queuePubkey}`
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
accounts.aggregator.data.crankPubkey.equals(origCrankAccount.publicKey),
|
||||||
|
`Incorrect crank, expected ${origCrankAccount.publicKey}, received ${accounts.aggregator.data.crankPubkey}`
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
accounts.lease.balance === 0.65,
|
||||||
|
`Incorrect lease balance, expected 0.65, received ${accounts.lease.balance}`
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
accounts.permission.data.permissions === 2,
|
||||||
|
`Incorrect permissions, expected PermitOracleQueueUsage (2), received ${accounts.permission.data.permissions}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Transfers the aggregator to a new queue and crank along with its balances', async () => {
|
||||||
|
if (!aggregatorAccount) {
|
||||||
|
throw new Error(`No aggregatorAccount to transfer`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const [permissionAccount, leaseAccount, signatures] =
|
||||||
|
await aggregatorAccount.transferQueue({
|
||||||
|
newQueue: newQueueAccount,
|
||||||
|
loadAmount: 1,
|
||||||
|
authority: aggregatorAuthority,
|
||||||
|
newCrank: newCrankAccount,
|
||||||
|
enable: true,
|
||||||
|
queueAuthority: newQueueAuthority,
|
||||||
|
});
|
||||||
|
|
||||||
|
const accounts = await aggregatorAccount.fetchAccounts();
|
||||||
|
|
||||||
|
assert(
|
||||||
|
accounts.permission.publicKey.equals(permissionAccount.publicKey),
|
||||||
|
`Incorrect permission account, expected ${permissionAccount.publicKey}, received ${accounts.permission.publicKey}`
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
accounts.aggregator.data.queuePubkey.equals(newQueueAccount.publicKey),
|
||||||
|
`Incorrect queue, expected ${newQueueAccount.publicKey}, received ${accounts.aggregator.data.queuePubkey}`
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
accounts.aggregator.data.crankPubkey.equals(newCrankAccount.publicKey),
|
||||||
|
`Incorrect crank, expected ${newCrankAccount.publicKey}, received ${accounts.aggregator.data.crankPubkey}`
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
accounts.lease.balance === 1.65,
|
||||||
|
`Incorrect lease balance, expected 1.65, received ${accounts.lease.balance}`
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
accounts.permission.data.permissions === 2,
|
||||||
|
`Incorrect permissions, expected PermitOracleQueueUsage (2), received ${accounts.permission.data.permissions}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Transfers an aggregator to a new queue in sequence', async () => {
|
||||||
|
const [aggregatorAccount] = await origQueueAccount.createFeed({
|
||||||
|
name: 'Aggregator-2',
|
||||||
|
authority: aggregatorAuthority,
|
||||||
|
batchSize: 1,
|
||||||
|
minRequiredOracleResults: 1,
|
||||||
|
minRequiredJobResults: 1,
|
||||||
|
minUpdateDelaySeconds: 10,
|
||||||
|
crankPubkey: origCrankAccount.publicKey,
|
||||||
|
fundAmount: 0.25,
|
||||||
|
enable: true,
|
||||||
|
queueAuthority: origQueueAuthority,
|
||||||
|
jobs: [
|
||||||
|
{
|
||||||
|
data: OracleJob.encodeDelimited(
|
||||||
|
OracleJob.fromObject({
|
||||||
|
tasks: [
|
||||||
|
{
|
||||||
|
valueTask: {
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
).finish(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const [permissionAccount, leaseAccount] =
|
||||||
|
await aggregatorAccount.transferQueuePart1({
|
||||||
|
newQueue: newQueueAccount,
|
||||||
|
loadAmount: 0.75,
|
||||||
|
});
|
||||||
|
|
||||||
|
await aggregatorAccount.transferQueuePart2({
|
||||||
|
newQueue: newQueueAccount,
|
||||||
|
enable: true,
|
||||||
|
queueAuthority: newQueueAuthority,
|
||||||
|
});
|
||||||
|
|
||||||
|
await aggregatorAccount.transferQueuePart3({
|
||||||
|
newQueue: newQueueAccount,
|
||||||
|
authority: aggregatorAuthority,
|
||||||
|
newCrank: newCrankAccount,
|
||||||
|
});
|
||||||
|
|
||||||
|
const accounts = await aggregatorAccount.fetchAccounts();
|
||||||
|
|
||||||
|
assert(
|
||||||
|
accounts.aggregator.data.queuePubkey.equals(newQueueAccount.publicKey),
|
||||||
|
`Incorrect queue, expected ${newQueueAccount.publicKey}, received ${accounts.aggregator.data.queuePubkey}`
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
accounts.aggregator.data.crankPubkey.equals(newCrankAccount.publicKey),
|
||||||
|
`Incorrect crank, expected ${newCrankAccount.publicKey}, received ${accounts.aggregator.data.crankPubkey}`
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
accounts.lease.balance === 1,
|
||||||
|
`Incorrect lease balance, expected 1.0, received ${accounts.lease.balance}`
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
accounts.permission.data.permissions === 2,
|
||||||
|
`Incorrect permissions, expected PermitOracleQueueUsage (2), received ${accounts.permission.data.permissions}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue