fix: return correct number of signatures needed to load programs (#12729)
This commit is contained in:
@ -34,7 +34,12 @@ export class Loader {
|
|||||||
* Can be used to calculate transaction fees
|
* Can be used to calculate transaction fees
|
||||||
*/
|
*/
|
||||||
static getMinNumSignatures(dataLength: number): number {
|
static getMinNumSignatures(dataLength: number): number {
|
||||||
return Math.ceil(dataLength / Loader.chunkSize);
|
return (
|
||||||
|
2 * // Every transaction requires two signatures (payer + program)
|
||||||
|
(Math.ceil(dataLength / Loader.chunkSize) +
|
||||||
|
1 + // Add one for Create transaction
|
||||||
|
1) // Add one for Finalize transaction
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,8 +19,6 @@ if (!mockRpcEnabled) {
|
|||||||
jest.setTimeout(120000);
|
jest.setTimeout(120000);
|
||||||
}
|
}
|
||||||
|
|
||||||
const NUM_RETRIES = 100; /* allow some number of retries */
|
|
||||||
|
|
||||||
test('load BPF C program', async () => {
|
test('load BPF C program', async () => {
|
||||||
if (mockRpcEnabled) {
|
if (mockRpcEnabled) {
|
||||||
console.log('non-live test skipped');
|
console.log('non-live test skipped');
|
||||||
@ -33,14 +31,23 @@ test('load BPF C program', async () => {
|
|||||||
const {feeCalculator} = await connection.getRecentBlockhash();
|
const {feeCalculator} = await connection.getRecentBlockhash();
|
||||||
const fees =
|
const fees =
|
||||||
feeCalculator.lamportsPerSignature *
|
feeCalculator.lamportsPerSignature *
|
||||||
(BpfLoader.getMinNumSignatures(data.length) + NUM_RETRIES);
|
BpfLoader.getMinNumSignatures(data.length);
|
||||||
const balanceNeeded = await connection.getMinimumBalanceForRentExemption(
|
const payerBalance = await connection.getMinimumBalanceForRentExemption(0);
|
||||||
|
const executableBalance = await connection.getMinimumBalanceForRentExemption(
|
||||||
data.length,
|
data.length,
|
||||||
);
|
);
|
||||||
const from = await newAccountWithLamports(connection, fees + balanceNeeded);
|
const from = await newAccountWithLamports(
|
||||||
|
connection,
|
||||||
|
payerBalance + fees + executableBalance,
|
||||||
|
);
|
||||||
|
|
||||||
const program = new Account();
|
const program = new Account();
|
||||||
await BpfLoader.load(connection, from, program, data, BPF_LOADER_PROGRAM_ID);
|
await BpfLoader.load(connection, from, program, data, BPF_LOADER_PROGRAM_ID);
|
||||||
|
|
||||||
|
// Check that program loading costed exactly `fees + executableBalance`
|
||||||
|
const fromBalance = await connection.getBalance(from.publicKey);
|
||||||
|
expect(fromBalance).toEqual(payerBalance);
|
||||||
|
|
||||||
const transaction = new Transaction().add({
|
const transaction = new Transaction().add({
|
||||||
keys: [{pubkey: from.publicKey, isSigner: true, isWritable: true}],
|
keys: [{pubkey: from.publicKey, isSigner: true, isWritable: true}],
|
||||||
programId: program.publicKey,
|
programId: program.publicKey,
|
||||||
@ -72,18 +79,19 @@ describe('load BPF Rust program', () => {
|
|||||||
const {feeCalculator} = await connection.getRecentBlockhash();
|
const {feeCalculator} = await connection.getRecentBlockhash();
|
||||||
const fees =
|
const fees =
|
||||||
feeCalculator.lamportsPerSignature *
|
feeCalculator.lamportsPerSignature *
|
||||||
(BpfLoader.getMinNumSignatures(programData.length) + NUM_RETRIES);
|
BpfLoader.getMinNumSignatures(programData.length);
|
||||||
const balanceNeeded = await connection.getMinimumBalanceForRentExemption(
|
const payerBalance = await connection.getMinimumBalanceForRentExemption(0);
|
||||||
|
const executableBalance = await connection.getMinimumBalanceForRentExemption(
|
||||||
programData.length,
|
programData.length,
|
||||||
);
|
);
|
||||||
|
|
||||||
payerAccount = await newAccountWithLamports(
|
payerAccount = await newAccountWithLamports(
|
||||||
connection,
|
connection,
|
||||||
fees + balanceNeeded,
|
payerBalance + fees + executableBalance,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create program account with low balance
|
// Create program account with low balance
|
||||||
program = await newAccountWithLamports(connection, balanceNeeded - 1);
|
program = await newAccountWithLamports(connection, executableBalance - 1);
|
||||||
|
|
||||||
// First load will fail part way due to lack of funds
|
// First load will fail part way due to lack of funds
|
||||||
const insufficientPayerAccount = await newAccountWithLamports(
|
const insufficientPayerAccount = await newAccountWithLamports(
|
||||||
|
Reference in New Issue
Block a user