Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve test coverage on reimbursement tests #822

Merged
merged 1 commit into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 101 additions & 73 deletions contracts/tests/ocr2.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ describe("ocr2", () => {
.accounts({ feed })
.rpc();

await provider.connection.confirmTransaction(tx, "confirmed")
await provider.connection.confirmTransaction(tx, "confirmed");
let t = await provider.connection.getTransaction(tx, {
commitment: "confirmed",
});
Expand All @@ -134,7 +134,7 @@ describe("ocr2", () => {
epoch: number,
round: number,
answer: BN,
computeUnitPrice: number = 0,
computeUnitPrice?: number,
juels: Buffer = Buffer.from([0, 0, 0, 0, 0, 0, 0, 2]) // juels per lamport (2)
): Promise<string> => {
let account = await program.account.state.fetch(state.publicKey);
Expand Down Expand Up @@ -211,8 +211,12 @@ describe("ocr2", () => {
const transmitter = oracles[0].transmitter;

const tx = new Transaction();
if (computeUnitPrice > 0) {
tx.add(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: computeUnitPrice }))
if (computeUnitPrice != undefined) {
tx.add(
ComputeBudgetProgram.setComputeUnitPrice({
microLamports: computeUnitPrice,
})
);
}
tx.add(
new TransactionInstruction({
Expand All @@ -231,7 +235,11 @@ describe("ocr2", () => {
isSigner: false,
},
{ pubkey: storeAuthority, isWritable: false, isSigner: false },
{ pubkey: SYSVAR_INSTRUCTIONS_PUBKEY, isWritable: false, isSigner: false },
{
pubkey: SYSVAR_INSTRUCTIONS_PUBKEY,
isWritable: false,
isSigner: false,
},
],
data: Buffer.concat([
Buffer.from([storeNonce]),
Expand All @@ -257,13 +265,18 @@ describe("ocr2", () => {

it("Funds the payer", async () => {
await provider.connection.confirmTransaction(
await provider.connection.requestAirdrop(
fromWallet.publicKey,
LAMPORTS_PER_SOL * 1000
), "confirmed");
await provider.connection.requestAirdrop(
fromWallet.publicKey,
LAMPORTS_PER_SOL * 1000
),
"confirmed"
);

await provider.connection.confirmTransaction(
await provider.connection.requestAirdrop(payer.publicKey, LAMPORTS_PER_SOL * 1000),
await provider.connection.requestAirdrop(
payer.publicKey,
LAMPORTS_PER_SOL * 1000
),
"confirmed"
);
});
Expand Down Expand Up @@ -942,13 +955,13 @@ describe("ocr2", () => {
// can still pay out oracles even if a token account is closed

// Close oracle0's token account
let oracle = oracles[0]
let oracle = oracles[0];
let tx = await closeAccount(
provider.connection,
fromWallet,
oracle.payee.address, // account
recipientTokenAccount.address, // destination
oracle.transmitter, // authority
oracle.transmitter // authority
);
await provider.connection.confirmTransaction(tx);

Expand Down Expand Up @@ -992,69 +1005,85 @@ describe("ocr2", () => {
}
});

it("Transmit reimburses for setComputeUnitPrice", async () => {
const transmitter = oracles[0].transmitter.publicKey;

let account = await program.account.state.fetch(state.publicKey);
let currentOracles = account.oracles.xs.slice(0, account.oracles.len);
// get the transmitter
let i = currentOracles.findIndex((o) => o.transmitter.equals(transmitter));
let oracle = currentOracles[i];
console.log(oracle);
let before = oracle.paymentGjuels;

let computePriceMicroLamports = 10;
let juelsPerLamport = Buffer.from([0, 0, 0, 0, 59, 154, 202, 0]); // 1 gjuel (to_be_bytes)
let tx = await transmit(
feed.publicKey,
rounds + 1,
rounds + 1,
new BN(rounds + 2),
computePriceMicroLamports,
juelsPerLamport,
let computePriceArr = [undefined, 0, 10, 100, 10_000, 100_000, 1_000_000];
computePriceArr.forEach((computePriceMicroLamports, offset) => {
it(
"Transmit reimburses for setComputeUnitPrice: " +
computePriceMicroLamports,
async () => {
const transmitter = oracles[0].transmitter.publicKey;

let account = await program.account.state.fetch(state.publicKey);
let currentOracles = account.oracles.xs.slice(0, account.oracles.len);
// get the transmitter
let i = currentOracles.findIndex((o) =>
o.transmitter.equals(transmitter)
);
let oracle = currentOracles[i];
console.log(oracle);
let before = oracle.paymentGjuels;

let juelsPerLamport = Buffer.from([0, 0, 0, 0, 59, 154, 202, 0]); // 1 gjuel (to_be_bytes)
let tx = await transmit(
feed.publicKey,
rounds + 1 + offset,
rounds + 1 + offset,
new BN(rounds + 2),
computePriceMicroLamports,
juelsPerLamport
);
await provider.connection.confirmTransaction(tx, "confirmed");
let t = await provider.connection.getTransaction(tx, {
commitment: "confirmed",
});
console.log(t.meta.logMessages); // 195_785/195_997
account = await program.account.state.fetch(
state.publicKey,
"confirmed"
);
currentOracles = account.oracles.xs.slice(0, account.oracles.len);
// get the transmitter
oracle = currentOracles[i];
let after = oracle.paymentGjuels;

let payment = after.sub(before).toNumber();
let execUnits = 25_000 * (f + 1) + 21_000;
let computeUnitCostLamports =
(execUnits * computePriceMicroLamports) / Math.pow(10, 6);
let lamportsPerSignature = 5000;
let signers = 1;
let computeUnitCostGjuels = Math.ceil(
((computeUnitCostLamports || 0) + lamportsPerSignature * signers) * 1
); // 1 lamport = 1 gjuel, use 0 if computeUnitCostLamports is NaN
assert.equal(payment, transmissionPayment + computeUnitCostGjuels);

// payOracles to clean up the payment state for the next test
let payees = currentOracles.map((oracle) => {
return { pubkey: oracle.payee, isWritable: true, isSigner: false };
});
tx = await program.rpc.payOracles({
accounts: {
state: state.publicKey,
authority: owner.publicKey,
accessController: billingAccessController.publicKey,
tokenReceiver: recipientTokenAccount.address,
tokenVault: tokenVault,
vaultAuthority: vaultAuthority,
tokenProgram: TOKEN_PROGRAM_ID,
},
remainingAccounts: payees,
});
await provider.connection.confirmTransaction(tx);
}
);
await provider.connection.confirmTransaction(tx, "confirmed");
let t = await provider.connection.getTransaction(tx, { commitment: "confirmed" });
console.log(t.meta.logMessages); // 195_785/195_997
account = await program.account.state.fetch(state.publicKey, 'confirmed');
currentOracles = account.oracles.xs.slice(0, account.oracles.len);
// get the transmitter
oracle = currentOracles[i];
let after = oracle.paymentGjuels;

let payment = after.sub(before).toNumber();
let execUnits = (25_000 * (f+1) + 21_000);
let computeUnitCostLamports = execUnits * computePriceMicroLamports / Math.pow(10, 6);
let lamportsPerSignature = 5000;
let signers = 1;
let computeUnitCostGjuels = Math.ceil((computeUnitCostLamports + lamportsPerSignature * signers) * 1); // 1 lamport = 1 gjuel
assert.equal(payment, transmissionPayment + computeUnitCostGjuels);

// payOracles to clean up the payment state for the next test
let payees = currentOracles.map((oracle) => {
return { pubkey: oracle.payee, isWritable: true, isSigner: false };
});
tx = await program.rpc.payOracles({
accounts: {
state: state.publicKey,
authority: owner.publicKey,
accessController: billingAccessController.publicKey,
tokenReceiver: recipientTokenAccount.address,
tokenVault: tokenVault,
vaultAuthority: vaultAuthority,
tokenProgram: TOKEN_PROGRAM_ID,
},
remainingAccounts: payees,
});
await provider.connection.confirmTransaction(tx);
});

it("Transmit does not fail on juelsPerFeecoin edge cases", async () => {
// zero value u64 juelsPerFeecoin
await transmit(
feed.publicKey,
rounds + 2,
rounds + 2,
rounds + computePriceArr.length + 1,
rounds + computePriceArr.length + 1,
new BN(rounds + 1),
0,
Buffer.from([0, 0, 0, 0, 0, 0, 0, 0])
Expand All @@ -1063,8 +1092,8 @@ describe("ocr2", () => {
// max value u64 juelsPerFeecoin
await transmit(
feed.publicKey,
rounds + 3,
rounds + 3,
rounds + computePriceArr.length + 2,
rounds + computePriceArr.length + 2,
new BN(rounds + 2),
0,
Buffer.from([127, 127, 127, 127, 127, 127, 127, 127])
Expand Down Expand Up @@ -1153,8 +1182,8 @@ describe("ocr2", () => {
remainingAccounts: payees,
preInstructions: [
// close seems to consume just over 200k units for some reason now
ComputeBudgetProgram.setComputeUnitLimit({ units: 300_000 })
]
ComputeBudgetProgram.setComputeUnitLimit({ units: 300_000 }),
],
});
// Print out program log so we can see total units consumed
await provider.connection.confirmTransaction(tx, "confirmed");
Expand Down Expand Up @@ -1296,5 +1325,4 @@ describe("ocr2", () => {
);
assert.equal(new BN(round.answer, 10, "le").toNumber(), 100);
});

});
16 changes: 8 additions & 8 deletions contracts/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -244,11 +244,11 @@
integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==

"@types/node@*":
version "22.3.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.3.0.tgz#7f8da0e2b72c27c4f9bd3cb5ef805209d04d4f9e"
integrity sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==
version "22.4.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.4.0.tgz#c295fe1d6f5f58916cc61dbef8cf65b5b9b71de9"
integrity sha512-49AbMDwYUz7EXxKU/r7mXOsxwFr4BYbvB7tWYxVuLdb2ibd30ijjXINSMAHiEEZk5PCRBmW1gUeisn2VMKt3cQ==
dependencies:
undici-types "~6.18.2"
undici-types "~6.19.2"

"@types/node@^12.12.54":
version "12.20.55"
Expand Down Expand Up @@ -1501,10 +1501,10 @@ typescript@^4.5.4:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==

undici-types@~6.18.2:
version "6.18.2"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.18.2.tgz#8b678cf939d4fc9ec56be3c68ed69c619dee28b0"
integrity sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==
undici-types@~6.19.2:
version "6.19.6"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.6.tgz#e218c3df0987f4c0e0008ca00d6b6472d9b89b36"
integrity sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org==

utf-8-validate@^5.0.2:
version "5.0.10"
Expand Down
Loading