fix: return correct number of signatures needed to load programs (#12729)

This commit is contained in:
Justin Starry 2020-10-09 08:58:03 +08:00 committed by GitHub
parent 2c5f83c264
commit 6972e63f51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 10 deletions

View File

@ -34,7 +34,12 @@ export class Loader {
* Can be used to calculate transaction fees
*/
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
);
}
/**

View File

@ -19,8 +19,6 @@ if (!mockRpcEnabled) {
jest.setTimeout(120000);
}
const NUM_RETRIES = 100; /* allow some number of retries */
test('load BPF C program', async () => {
if (mockRpcEnabled) {
console.log('non-live test skipped');
@ -33,14 +31,23 @@ test('load BPF C program', async () => {
const {feeCalculator} = await connection.getRecentBlockhash();
const fees =
feeCalculator.lamportsPerSignature *
(BpfLoader.getMinNumSignatures(data.length) + NUM_RETRIES);
const balanceNeeded = await connection.getMinimumBalanceForRentExemption(
BpfLoader.getMinNumSignatures(data.length);
const payerBalance = await connection.getMinimumBalanceForRentExemption(0);
const executableBalance = await connection.getMinimumBalanceForRentExemption(
data.length,
);
const from = await newAccountWithLamports(connection, fees + balanceNeeded);
const from = await newAccountWithLamports(
connection,
payerBalance + fees + executableBalance,
);
const program = new Account();
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({
keys: [{pubkey: from.publicKey, isSigner: true, isWritable: true}],
programId: program.publicKey,
@ -72,18 +79,19 @@ describe('load BPF Rust program', () => {
const {feeCalculator} = await connection.getRecentBlockhash();
const fees =
feeCalculator.lamportsPerSignature *
(BpfLoader.getMinNumSignatures(programData.length) + NUM_RETRIES);
const balanceNeeded = await connection.getMinimumBalanceForRentExemption(
BpfLoader.getMinNumSignatures(programData.length);
const payerBalance = await connection.getMinimumBalanceForRentExemption(0);
const executableBalance = await connection.getMinimumBalanceForRentExemption(
programData.length,
);
payerAccount = await newAccountWithLamports(
connection,
fees + balanceNeeded,
payerBalance + fees + executableBalance,
);
// 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
const insufficientPayerAccount = await newAccountWithLamports(