From 81c2e8f9c1dd84b4ef256ff0a7cbc6ad04d61f89 Mon Sep 17 00:00:00 2001 From: Jack May Date: Tue, 22 Oct 2019 15:16:12 -0700 Subject: [PATCH] fix: loader report minimum number of signatures required (#535) --- web3.js/src/bpf-loader.js | 10 ++++++++++ web3.js/src/loader.js | 10 ++++++++++ web3.js/test/bpf-loader.test.js | 23 ++++++++++++++++++----- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/web3.js/src/bpf-loader.js b/web3.js/src/bpf-loader.js index 4c79be81d4..9cc2629050 100644 --- a/web3.js/src/bpf-loader.js +++ b/web3.js/src/bpf-loader.js @@ -16,6 +16,16 @@ export class BpfLoader { return new PublicKey('BPFLoader1111111111111111111111111111111111'); } + /** + * Minimum number of signatures required to load a program not including + * retries + * + * Can be used to calculate transaction fees + */ + static getMinNumSignatures(dataLength: number): number { + return Loader.getMinNumSignatures(dataLength); + } + /** * Load a BPF program * diff --git a/web3.js/src/loader.js b/web3.js/src/loader.js index 0c3e2ea477..5407feca10 100644 --- a/web3.js/src/loader.js +++ b/web3.js/src/loader.js @@ -28,6 +28,16 @@ export class Loader { return PACKET_DATA_SIZE - 300; } + /** + * Minimum number of signatures required to load a program not including + * retries + * + * Can be used to calculate transaction fees + */ + static getMinNumSignatures(dataLength: number): number { + return Math.ceil(dataLength / Loader.chunkSize); + } + /** * Loads a generic program * diff --git a/web3.js/test/bpf-loader.test.js b/web3.js/test/bpf-loader.test.js index c5e14bedb0..4a63e755b3 100644 --- a/web3.js/test/bpf-loader.test.js +++ b/web3.js/test/bpf-loader.test.js @@ -7,7 +7,6 @@ import { BpfLoader, Transaction, sendAndConfirmTransaction, - SOL_LAMPORTS, } from '../src'; import {mockRpcEnabled} from './__mocks__/node-fetch'; import {url} from './url'; @@ -18,15 +17,23 @@ 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'); return; } - const connection = new Connection(url); - const from = await newAccountWithLamports(connection, SOL_LAMPORTS); const data = await fs.readFile('test/fixtures/noop-c/noop.so'); + + const connection = new Connection(url); + const [, feeCalculator] = await connection.getRecentBlockhash(); + const fees = + feeCalculator.lamportsPerSignature * + (BpfLoader.getMinNumSignatures(data.length) + NUM_RETRIES); + const from = await newAccountWithLamports(connection, fees); + const programId = await BpfLoader.load(connection, from, data); const transaction = new Transaction().add({ keys: [{pubkey: from.publicKey, isSigner: true, isDebitable: true}], @@ -41,11 +48,17 @@ test('load BPF Rust program', async () => { return; } - const connection = new Connection(url); - const from = await newAccountWithLamports(connection, SOL_LAMPORTS); const data = await fs.readFile( 'test/fixtures/noop-rust/solana_bpf_rust_noop.so', ); + + const connection = new Connection(url); + const [, feeCalculator] = await connection.getRecentBlockhash(); + const fees = + feeCalculator.lamportsPerSignature * + (BpfLoader.getMinNumSignatures(data.length) + NUM_RETRIES); + const from = await newAccountWithLamports(connection, fees); + const programId = await BpfLoader.load(connection, from, data); const transaction = new Transaction().add({ keys: [{pubkey: from.publicKey, isSigner: true, isDebitable: true}],