From 839e93480c4dbf8fc76a93d78baa46d5995dd814 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Wed, 20 May 2020 17:13:21 +0800 Subject: [PATCH] feat: update transaction confirming apis --- web3.js/module.d.ts | 21 +-- web3.js/module.flow.js | 21 +-- web3.js/src/connection.js | 66 ++++---- web3.js/src/index.js | 5 +- web3.js/src/loader.js | 16 +- .../util/send-and-confirm-raw-transaction.js | 44 ++--- .../src/util/send-and-confirm-transaction.js | 95 ++--------- web3.js/test/bpf-loader.test.js | 4 +- web3.js/test/connection.test.js | 158 +++++++++--------- web3.js/test/nonce.test.js | 4 +- web3.js/test/stake-program.test.js | 39 ++--- web3.js/test/system-program.test.js | 24 ++- web3.js/test/transaction-payer.test.js | 33 ++-- 13 files changed, 214 insertions(+), 316 deletions(-) diff --git a/web3.js/module.d.ts b/web3.js/module.d.ts index e4c76f67c7..4653c9e89c 100644 --- a/web3.js/module.d.ts +++ b/web3.js/module.d.ts @@ -210,14 +210,10 @@ declare module '@solana/web3.js' { endSlot: number, ): Promise>; getVoteAccounts(commitment?: Commitment): Promise; - confirmTransactionAndContext( - signature: TransactionSignature, - commitment?: Commitment, - ): Promise>; confirmTransaction( signature: TransactionSignature, - commitment?: Commitment, - ): Promise; + confirmations?: number, + ): Promise>; getSlot(commitment?: Commitment): Promise; getSlotLeader(commitment?: Commitment): Promise; getSignatureStatus( @@ -247,7 +243,7 @@ declare module '@solana/web3.js' { ): Promise; sendTransaction( transaction: Transaction, - ...signers: Array + signers: Array, ): Promise; sendEncodedTransaction( encodedTransaction: string, @@ -769,20 +765,15 @@ declare module '@solana/web3.js' { export function sendAndConfirmTransaction( connection: Connection, transaction: Transaction, - ...signers: Array - ): Promise; - - export function sendAndConfirmRecentTransaction( - connection: Connection, - transaction: Transaction, - ...signers: Array + signers: Array, + confirmations?: number, ): Promise; // === src/util/send-and-confirm-raw-transaction.js === export function sendAndConfirmRawTransaction( connection: Connection, wireTransaction: Buffer, - commitment?: Commitment, + confirmations?: number, ): Promise; // === src/util/cluster.js === diff --git a/web3.js/module.flow.js b/web3.js/module.flow.js index 4f34bd617f..5455d6b483 100644 --- a/web3.js/module.flow.js +++ b/web3.js/module.flow.js @@ -223,14 +223,10 @@ declare module '@solana/web3.js' { endSlot: number, ): Promise>; getVoteAccounts(commitment: ?Commitment): Promise; - confirmTransactionAndContext( - signature: TransactionSignature, - commitment: ?Commitment, - ): Promise>; confirmTransaction( signature: TransactionSignature, - commitment: ?Commitment, - ): Promise; + confirmations: ?number, + ): Promise>; getSlot(commitment: ?Commitment): Promise; getSlotLeader(commitment: ?Commitment): Promise; getSignatureStatus( @@ -260,7 +256,7 @@ declare module '@solana/web3.js' { ): Promise; sendTransaction( transaction: Transaction, - ...signers: Array + signers: Array, ): Promise; sendEncodedTransaction( encodedTransaction: string, @@ -784,20 +780,15 @@ declare module '@solana/web3.js' { declare export function sendAndConfirmTransaction( connection: Connection, transaction: Transaction, - ...signers: Array - ): Promise; - - declare export function sendAndConfirmRecentTransaction( - connection: Connection, - transaction: Transaction, - ...signers: Array + signers: Array, + confirmations: ?number, ): Promise; // === src/util/send-and-confirm-raw-transaction.js === declare export function sendAndConfirmRawTransaction( connection: Connection, wireTransaction: Buffer, - commitment: ?Commitment, + confirmations: ?number, ): Promise; // === src/util/cluster.js === diff --git a/web3.js/src/connection.js b/web3.js/src/connection.js index ee681ea576..23ebd773a4 100644 --- a/web3.js/src/connection.js +++ b/web3.js/src/connection.js @@ -469,13 +469,6 @@ const GetProgramAccountsRpcResult = jsonRpcResult( struct.array([ProgramAccountInfoResult]), ); -/** - * Expected JSON RPC response for the "confirmTransaction" message - */ -const ConfirmTransactionAndContextRpcResult = jsonRpcResultAndContext( - 'boolean', -); - /** * Expected JSON RPC response for the "getSlot" message */ @@ -1063,35 +1056,44 @@ export class Connection { }); } - /** - * Confirm the transaction identified by the specified signature, return with context - */ - async confirmTransactionAndContext( - signature: TransactionSignature, - commitment: ?Commitment, - ): Promise> { - const args = this._argsWithCommitment([signature], commitment); - const unsafeRes = await this._rpcRequest('confirmTransaction', args); - const res = ConfirmTransactionAndContextRpcResult(unsafeRes); - if (res.error) { - throw new Error('failed to confirm transaction: ' + res.error.message); - } - assert(typeof res.result !== 'undefined'); - return res.result; - } - /** * Confirm the transaction identified by the specified signature */ async confirmTransaction( signature: TransactionSignature, - commitment: ?Commitment, - ): Promise { - return await this.confirmTransactionAndContext(signature, commitment) - .then(x => x.value) - .catch(e => { - throw new Error('failed to confirm transaction: ' + e); - }); + confirmations: ?number, + ): Promise> { + const NUM_STATUS_RETRIES = 10; + + const MS_PER_SECOND = 1000; + const MS_PER_SLOT = + (DEFAULT_TICKS_PER_SLOT / NUM_TICKS_PER_SECOND) * MS_PER_SECOND; + + let statusRetries = NUM_STATUS_RETRIES; + let statusResponse = await this.getSignatureStatus(signature); + for (;;) { + const status = statusResponse.value; + if (status) { + // Received a status, if not an error wait for confirmation + statusRetries = NUM_STATUS_RETRIES; + if ( + status.err || + status.confirmations === null || + (typeof confirmations === 'number' && + status.confirmations >= confirmations) + ) { + break; + } + } else if (--statusRetries <= 0) { + break; + } + + // Sleep for approximately half a slot + await sleep(MS_PER_SLOT / 2); + statusResponse = await this.getSignatureStatus(signature); + } + + return statusResponse; } /** @@ -1474,7 +1476,7 @@ export class Connection { */ async sendTransaction( transaction: Transaction, - ...signers: Array + signers: Array, ): Promise { if (transaction.nonceInfo) { transaction.sign(...signers); diff --git a/web3.js/src/index.js b/web3.js/src/index.js index 90a9e763cd..4b8eb56c32 100644 --- a/web3.js/src/index.js +++ b/web3.js/src/index.js @@ -30,10 +30,7 @@ export { SYSVAR_REWARDS_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY, } from './sysvar'; -export { - sendAndConfirmTransaction, - sendAndConfirmRecentTransaction, -} from './util/send-and-confirm-transaction'; +export {sendAndConfirmTransaction} from './util/send-and-confirm-transaction'; export {sendAndConfirmRawTransaction} from './util/send-and-confirm-raw-transaction'; export {clusterApiUrl} from './util/cluster'; diff --git a/web3.js/src/loader.js b/web3.js/src/loader.js index a49294a140..85dc35d2c1 100644 --- a/web3.js/src/loader.js +++ b/web3.js/src/loader.js @@ -65,7 +65,12 @@ export class Loader { space: data.length, programId, }); - await sendAndConfirmTransaction(connection, transaction, payer, program); + await sendAndConfirmTransaction( + connection, + transaction, + [payer, program], + 1, + ); } const dataLayout = BufferLayout.struct([ @@ -102,7 +107,7 @@ export class Loader { data, }); transactions.push( - sendAndConfirmTransaction(connection, transaction, payer, program), + sendAndConfirmTransaction(connection, transaction, [payer, program], 1), ); // Delay ~1 tick between write transactions in an attempt to reduce AccountInUse errors @@ -143,7 +148,12 @@ export class Loader { programId, data, }); - await sendAndConfirmTransaction(connection, transaction, payer, program); + await sendAndConfirmTransaction( + connection, + transaction, + [payer, program], + 1, + ); } } } diff --git a/web3.js/src/util/send-and-confirm-raw-transaction.js b/web3.js/src/util/send-and-confirm-raw-transaction.js index 7171fa7e93..84349f2759 100644 --- a/web3.js/src/util/send-and-confirm-raw-transaction.js +++ b/web3.js/src/util/send-and-confirm-raw-transaction.js @@ -1,54 +1,34 @@ // @flow import {Connection} from '../connection'; -import type {Commitment} from '../connection'; -import {sleep} from './sleep'; import type {TransactionSignature} from '../transaction'; -import {DEFAULT_TICKS_PER_SLOT, NUM_TICKS_PER_SECOND} from '../timing'; /** - * Sign, send and confirm a raw transaction + * Send and confirm a raw transaction */ export async function sendAndConfirmRawTransaction( connection: Connection, rawTransaction: Buffer, - commitment: ?Commitment, + confirmations: ?number, ): Promise { const start = Date.now(); - const statusCommitment = commitment || connection.commitment || 'max'; - let signature = await connection.sendRawTransaction(rawTransaction); + const signature = await connection.sendRawTransaction(rawTransaction); + const status = (await connection.confirmTransaction(signature, confirmations)) + .value; - // Wait up to a couple slots for a confirmation - let status = null; - let statusRetries = 6; - for (;;) { - status = (await connection.getSignatureStatus(signature)).value; - if (status) { - if (statusCommitment === 'max' && status.confirmations === null) { - break; - } else if (statusCommitment === 'recent') { - break; - } - } - - // Sleep for approximately half a slot - await sleep((500 * DEFAULT_TICKS_PER_SLOT) / NUM_TICKS_PER_SECOND); - - if (--statusRetries <= 0) { - const duration = (Date.now() - start) / 1000; + if (status) { + if (status.err) { throw new Error( - `Raw Transaction '${signature}' was not confirmed in ${duration.toFixed( - 2, - )} seconds (${JSON.stringify(status)})`, + `Raw transaction ${signature} failed (${JSON.stringify(status)})`, ); } - } - - if (status && !status.err) { return signature; } + const duration = (Date.now() - start) / 1000; throw new Error( - `Raw transaction ${signature} failed (${JSON.stringify(status)})`, + `Raw transaction '${signature}' was not confirmed in ${duration.toFixed( + 2, + )} seconds`, ); } diff --git a/web3.js/src/util/send-and-confirm-transaction.js b/web3.js/src/util/send-and-confirm-transaction.js index 6fd7c13adb..9e5516640e 100644 --- a/web3.js/src/util/send-and-confirm-transaction.js +++ b/web3.js/src/util/send-and-confirm-transaction.js @@ -1,111 +1,52 @@ // @flow -import invariant from 'assert'; - import {Connection} from '../connection'; -import type {Commitment} from '../connection'; import {Transaction} from '../transaction'; import {sleep} from './sleep'; import type {Account} from '../account'; import type {TransactionSignature} from '../transaction'; -import {DEFAULT_TICKS_PER_SLOT, NUM_TICKS_PER_SECOND} from '../timing'; - -const MS_PER_SECOND = 1000; -const MS_PER_SLOT = - (DEFAULT_TICKS_PER_SLOT / NUM_TICKS_PER_SECOND) * MS_PER_SECOND; const NUM_SEND_RETRIES = 10; -const NUM_STATUS_RETRIES = 10; /** - * Sign, send and confirm a transaction with recent commitment level - */ -export async function sendAndConfirmRecentTransaction( - connection: Connection, - transaction: Transaction, - ...signers: Array -): Promise { - return await _sendAndConfirmTransaction( - connection, - transaction, - signers, - 'recent', - ); -} - -/** - * Sign, send and confirm a transaction + * Sign, send and confirm a transaction. + * + * If `confirmations` count is not specified, wait for transaction to be finalized. */ export async function sendAndConfirmTransaction( - connection: Connection, - transaction: Transaction, - ...signers: Array -): Promise { - return await _sendAndConfirmTransaction(connection, transaction, signers); -} - -async function _sendAndConfirmTransaction( connection: Connection, transaction: Transaction, signers: Array, - commitment: ?Commitment, + confirmations: ?number, ): Promise { - const statusCommitment = commitment || connection.commitment || 'max'; - + const start = Date.now(); let sendRetries = NUM_SEND_RETRIES; - let signature; for (;;) { - const start = Date.now(); - signature = await connection.sendTransaction(transaction, ...signers); - - // Wait up to a couple slots for a confirmation - let status = null; - let statusRetries = NUM_STATUS_RETRIES; - for (;;) { - status = (await connection.getSignatureStatus(signature)).value; - if (status) { - // Recieved a status, if not an error wait for confirmation - statusRetries = NUM_STATUS_RETRIES; - if ( - status.err || - status.confirmations === null || - (statusCommitment === 'recent' && status.confirmations >= 1) - ) { - break; - } - } - - if (--statusRetries <= 0) { - break; - } - // Sleep for approximately half a slot - await sleep(MS_PER_SLOT / 2); - } + const signature = await connection.sendTransaction(transaction, signers); + const status = ( + await connection.confirmTransaction(signature, confirmations) + ).value; if (status) { - if (!status.err) { - break; - } else if (!('AccountInUse' in status.err)) { + if (status.err) { throw new Error( `Transaction ${signature} failed (${JSON.stringify(status)})`, ); } + return signature; } - if (--sendRetries <= 0) { - const duration = (Date.now() - start) / 1000; - throw new Error( - `Transaction '${signature}' was not confirmed in ${duration.toFixed( - 2, - )} seconds (${JSON.stringify(status)})`, - ); - } + if (--sendRetries <= 0) break; // Retry in 0..100ms to try to avoid another AccountInUse collision await sleep(Math.random() * 100); } - invariant(signature !== undefined); - return signature; + const duration = (Date.now() - start) / 1000; + throw new Error( + `Transaction was not confirmed in ${duration.toFixed( + 2, + )} seconds (${JSON.stringify(status)})`, + ); } diff --git a/web3.js/test/bpf-loader.test.js b/web3.js/test/bpf-loader.test.js index 92a0ef1cd2..ba5380823d 100644 --- a/web3.js/test/bpf-loader.test.js +++ b/web3.js/test/bpf-loader.test.js @@ -44,7 +44,7 @@ test('load BPF C program', async () => { keys: [{pubkey: from.publicKey, isSigner: true, isWritable: true}], programId: program.publicKey, }); - await sendAndConfirmTransaction(connection, transaction, from); + await sendAndConfirmTransaction(connection, transaction, [from], 1); }); test('load BPF Rust program', async () => { @@ -73,5 +73,5 @@ test('load BPF Rust program', async () => { keys: [{pubkey: from.publicKey, isSigner: true, isWritable: true}], programId: program.publicKey, }); - await sendAndConfirmTransaction(connection, transaction, from); + await sendAndConfirmTransaction(connection, transaction, [from], 1); }); diff --git a/web3.js/test/connection.test.js b/web3.js/test/connection.test.js index c96479d907..94f174427c 100644 --- a/web3.js/test/connection.test.js +++ b/web3.js/test/connection.test.js @@ -14,6 +14,7 @@ import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch'; import {mockGetRecentBlockhash} from './mockrpc/get-recent-blockhash'; import {url} from './url'; import {sleep} from '../src/util/sleep'; +import type {SignatureStatus, TransactionError} from '../src/connection'; if (!mockRpcEnabled) { // Testing max commitment level takes around 20s to complete @@ -28,6 +29,29 @@ const errorResponse = { result: undefined, }; +const verifySignatureStatus = ( + status: SignatureStatus | null, + err?: TransactionError, +): SignatureStatus => { + if (status === null) { + expect(status).not.toBeNull(); + throw new Error(); // unreachable + } + + const expectedErr = err || null; + expect(status.err).toEqual(expectedErr); + expect(status.slot).toBeGreaterThanOrEqual(0); + if (expectedErr !== null) return status; + + const confirmations = status.confirmations; + if (typeof confirmations === 'number') { + expect(confirmations).toBeGreaterThan(0); + } else { + expect(confirmations).toBeNull(); + } + return status; +}; + test('get account info - not found', async () => { const account = new Account(); const connection = new Connection(url); @@ -135,7 +159,7 @@ test('get program accounts', async () => { accountPubkey: account0.publicKey, programId: programId.publicKey, }); - await sendAndConfirmTransaction(connection, transaction, account0); + await sendAndConfirmTransaction(connection, transaction, [account0], 1); mockRpc.push([ url, @@ -180,7 +204,7 @@ test('get program accounts', async () => { programId: programId.publicKey, }); - await sendAndConfirmTransaction(connection, transaction, account1); + await sendAndConfirmTransaction(connection, transaction, [account1], 1); mockGetRecentBlockhash('recent'); const {feeCalculator} = await connection.getRecentBlockhash(); @@ -493,8 +517,8 @@ test('confirm transaction - error', async () => { mockRpc.push([ url, { - method: 'confirmTransaction', - params: [badTransactionSignature], + method: 'getSignatureStatuses', + params: [[badTransactionSignature]], }, errorResponse, ]); @@ -1367,15 +1391,17 @@ test('transaction failure', async () => { toPubkey: account.publicKey, lamports: 10, }); - const signature = await connection.sendTransaction(transaction, account); + const signature = await connection.sendTransaction(transaction, [account]); + const expectedErr = {InstructionError: [0, 'AccountBorrowFailed']}; mockRpc.push([ url, { - method: 'confirmTransaction', + method: 'getSignatureStatuses', params: [ - '3WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk', - {commitment: 'recent'}, + [ + '3WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk', + ], ], }, { @@ -1384,16 +1410,23 @@ test('transaction failure', async () => { context: { slot: 11, }, - value: false, + value: [ + { + slot: 0, + confirmations: 1, + status: {Err: expectedErr}, + err: expectedErr, + }, + ], }, }, ]); // Wait for one confirmation - await sleep(1000); - expect(await connection.confirmTransaction(signature)).toEqual(false); + const confirmResult = (await connection.confirmTransaction(signature, 1)) + .value; + verifySignatureStatus(confirmResult, expectedErr); - const expectedErr = {InstructionError: [0, 'AccountBorrowFailed']}; mockRpc.push([ url, { @@ -1423,19 +1456,7 @@ test('transaction failure', async () => { ]); const response = (await connection.getSignatureStatus(signature)).value; - if (response === null) { - expect(response).not.toBeNull(); - return; - } - - expect(response.err).toEqual(expectedErr); - expect(response.slot).toBeGreaterThanOrEqual(0); - const responseConfirmations = response.confirmations; - if (typeof responseConfirmations === 'number') { - expect(responseConfirmations).toBeGreaterThan(0); - } else { - expect(responseConfirmations).toBeNull(); - } + verifySignatureStatus(response, expectedErr); }); test('transaction', async () => { @@ -1555,15 +1576,18 @@ test('transaction', async () => { toPubkey: accountTo.publicKey, lamports: 10, }); - const signature = await connection.sendTransaction(transaction, accountFrom); + const signature = await connection.sendTransaction(transaction, [ + accountFrom, + ]); mockRpc.push([ url, { - method: 'confirmTransaction', + method: 'getSignatureStatuses', params: [ - '3WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk', - {commitment: 'recent'}, + [ + '3WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk', + ], ], }, { @@ -1572,24 +1596,22 @@ test('transaction', async () => { context: { slot: 11, }, - value: true, + value: [ + { + slot: 0, + confirmations: 1, + status: {Ok: null}, + err: null, + }, + ], }, }, ]); // Wait for one confirmation - await sleep(1000); - - let i = 0; - for (;;) { - if (await connection.confirmTransaction(signature)) { - break; - } - console.log('not confirmed', signature); - expect(mockRpcEnabled).toBe(false); - expect(++i).toBeLessThan(10); - await sleep(500); - } + const confirmResult = (await connection.confirmTransaction(signature, 1)) + .value; + verifySignatureStatus(confirmResult); mockRpc.push([ url, @@ -1619,20 +1641,9 @@ test('transaction', async () => { }, ]); - const response = (await connection.getSignatureStatus(signature)).value; - if (response === null) { - expect(response).not.toBeNull(); - return; - } - - expect(response.err).toBeNull(); - expect(response.slot).toBeGreaterThanOrEqual(0); - const responseConfirmations = response.confirmations; - if (typeof responseConfirmations === 'number') { - expect(responseConfirmations).toBeGreaterThan(0); - } else { - expect(responseConfirmations).toBeNull(); - } + const response = verifySignatureStatus( + (await connection.getSignatureStatus(signature)).value, + ); const unprocessedSignature = '8WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk'; @@ -1670,28 +1681,22 @@ test('transaction', async () => { await connection.getSignatureStatuses([signature, unprocessedSignature]) ).value; expect(responses.length).toEqual(2); - - const firstResponse = responses[0]; expect(responses[1]).toBeNull(); - if (firstResponse === null) { - expect(firstResponse).not.toBeNull(); - return; - } - + const firstResponse = verifySignatureStatus(responses[0]); expect(firstResponse.slot).toBeGreaterThanOrEqual(response.slot); expect(firstResponse.err).toEqual(response.err); - const firstResponseConfirmations = firstResponse.confirmations; + const responseConfirmations = response.confirmations; if ( typeof responseConfirmations === 'number' && - typeof firstResponseConfirmations === 'number' + typeof firstResponse.confirmations === 'number' ) { - expect(firstResponseConfirmations).toBeGreaterThanOrEqual( + expect(firstResponse.confirmations).toBeGreaterThanOrEqual( responseConfirmations, ); } else { - expect(firstResponseConfirmations).toBeNull(); + expect(firstResponse.confirmations).toBeNull(); } mockRpc.push([ @@ -1775,21 +1780,12 @@ test('multi-instruction transaction', async () => { lamports: 100, }), ); - const signature = await connection.sendTransaction( - transaction, + const signature = await connection.sendTransaction(transaction, [ accountFrom, accountTo, - ); - let i = 0; - for (;;) { - if (await connection.confirmTransaction(signature)) { - break; - } + ]); - expect(mockRpcEnabled).toBe(false); - expect(++i).toBeLessThan(10); - await sleep(500); - } + await connection.confirmTransaction(signature, 1); const response = (await connection.getSignatureStatus(signature)).value; if (response !== null) { @@ -1839,7 +1835,7 @@ test('account change notification', async () => { toPubkey: programAccount.publicKey, lamports: balanceNeeded, }); - await sendAndConfirmTransaction(connection, transaction, owner); + await sendAndConfirmTransaction(connection, transaction, [owner], 1); } catch (err) { await connection.removeAccountChangeListener(subscriptionId); throw err; @@ -1903,7 +1899,7 @@ test('program account change notification', async () => { toPubkey: programAccount.publicKey, lamports: balanceNeeded, }); - await sendAndConfirmTransaction(connection, transaction, owner); + await sendAndConfirmTransaction(connection, transaction, [owner], 1); } catch (err) { await connection.removeProgramAccountChangeListener(subscriptionId); throw err; diff --git a/web3.js/test/nonce.test.js b/web3.js/test/nonce.test.js index b182c50695..8c8ecf5ab2 100644 --- a/web3.js/test/nonce.test.js +++ b/web3.js/test/nonce.test.js @@ -103,7 +103,7 @@ test('create and query nonce account', async () => { authorizedPubkey: from.publicKey, lamports: minimumAmount, }); - await connection.sendTransaction(transaction, from, nonceAccount); + await connection.sendTransaction(transaction, [from, nonceAccount]); mockRpc.push([ url, @@ -222,7 +222,7 @@ test('create and query nonce account with seed', async () => { authorizedPubkey: from.publicKey, lamports: minimumAmount, }); - await connection.sendTransaction(transaction, from); + await connection.sendTransaction(transaction, [from]); mockRpc.push([ url, diff --git a/web3.js/test/stake-program.test.js b/web3.js/test/stake-program.test.js index 3f1f94045c..4b5774b4e9 100644 --- a/web3.js/test/stake-program.test.js +++ b/web3.js/test/stake-program.test.js @@ -6,7 +6,7 @@ import { Connection, Lockup, PublicKey, - sendAndConfirmRecentTransaction, + sendAndConfirmTransaction, LAMPORTS_PER_SOL, StakeAuthorizationLayout, StakeInstruction, @@ -268,11 +268,11 @@ test('live staking actions', async () => { lamports: minimumAmount + 42, }); - await sendAndConfirmRecentTransaction( + await sendAndConfirmTransaction( connection, createAndInitialize, - from, - newStakeAccount, + [from, newStakeAccount], + 0, ); expect(await connection.getBalance(newStakeAccount.publicKey)).toEqual( minimumAmount + 42, @@ -283,7 +283,7 @@ test('live staking actions', async () => { authorizedPubkey: authorized.publicKey, votePubkey, }); - await sendAndConfirmRecentTransaction(connection, delegation, authorized); + await sendAndConfirmTransaction(connection, delegation, [authorized], 0); } // Create Stake account with seed @@ -304,10 +304,11 @@ test('live staking actions', async () => { lamports: 3 * minimumAmount + 42, }); - await sendAndConfirmRecentTransaction( + await sendAndConfirmTransaction( connection, createAndInitializeWithSeed, - from, + [from], + 0, ); let originalStakeBalance = await connection.getBalance(newAccountPubkey); expect(originalStakeBalance).toEqual(3 * minimumAmount + 42); @@ -317,7 +318,7 @@ test('live staking actions', async () => { authorizedPubkey: authorized.publicKey, votePubkey, }); - await sendAndConfirmRecentTransaction(connection, delegation, authorized); + await sendAndConfirmTransaction(connection, delegation, [authorized], 0); // Test that withdraw fails before deactivation const recipient = new Account(); @@ -328,7 +329,7 @@ test('live staking actions', async () => { lamports: 1000, }); await expect( - sendAndConfirmRecentTransaction(connection, withdraw, authorized), + sendAndConfirmTransaction(connection, withdraw, [authorized], 0), ).rejects.toThrow(); // Split stake @@ -339,12 +340,7 @@ test('live staking actions', async () => { splitStakePubkey: newStake.publicKey, lamports: minimumAmount + 20, }); - await sendAndConfirmRecentTransaction( - connection, - split, - authorized, - newStake, - ); + await sendAndConfirmTransaction(connection, split, [authorized, newStake], 0); // Authorize to new account const newAuthorized = new Account(); @@ -356,14 +352,14 @@ test('live staking actions', async () => { newAuthorizedPubkey: newAuthorized.publicKey, stakeAuthorizationType: StakeAuthorizationLayout.Withdrawer, }); - await sendAndConfirmRecentTransaction(connection, authorize, authorized); + await sendAndConfirmTransaction(connection, authorize, [authorized], 0); authorize = StakeProgram.authorize({ stakePubkey: newAccountPubkey, authorizedPubkey: authorized.publicKey, newAuthorizedPubkey: newAuthorized.publicKey, stakeAuthorizationType: StakeAuthorizationLayout.Staker, }); - await sendAndConfirmRecentTransaction(connection, authorize, authorized); + await sendAndConfirmTransaction(connection, authorize, [authorized], 0); // Test old authorized can't deactivate let deactivateNotAuthorized = StakeProgram.deactivate({ @@ -371,10 +367,11 @@ test('live staking actions', async () => { authorizedPubkey: authorized.publicKey, }); await expect( - sendAndConfirmRecentTransaction( + sendAndConfirmTransaction( connection, deactivateNotAuthorized, - authorized, + [authorized], + 0, ), ).rejects.toThrow(); @@ -383,7 +380,7 @@ test('live staking actions', async () => { stakePubkey: newAccountPubkey, authorizedPubkey: newAuthorized.publicKey, }); - await sendAndConfirmRecentTransaction(connection, deactivate, newAuthorized); + await sendAndConfirmTransaction(connection, deactivate, [newAuthorized], 0); // Test that withdraw succeeds after deactivation withdraw = StakeProgram.withdraw({ @@ -392,7 +389,7 @@ test('live staking actions', async () => { toPubkey: recipient.publicKey, lamports: minimumAmount + 20, }); - await sendAndConfirmRecentTransaction(connection, withdraw, newAuthorized); + await sendAndConfirmTransaction(connection, withdraw, [newAuthorized], 0); const balance = await connection.getBalance(newAccountPubkey); expect(balance).toEqual(minimumAmount + 2); const recipientBalance = await connection.getBalance(recipient.publicKey); diff --git a/web3.js/test/system-program.test.js b/web3.js/test/system-program.test.js index 1dc4f1d45b..1d4c09ac81 100644 --- a/web3.js/test/system-program.test.js +++ b/web3.js/test/system-program.test.js @@ -8,7 +8,7 @@ import { SystemProgram, Transaction, TransactionInstruction, - sendAndConfirmRecentTransaction, + sendAndConfirmTransaction, LAMPORTS_PER_SOL, } from '../src'; import {NONCE_ACCOUNT_LENGTH} from '../src/nonce-account'; @@ -293,11 +293,11 @@ test('live Nonce actions', async () => { authorizedPubkey: from.publicKey, lamports: minimumAmount, }); - await sendAndConfirmRecentTransaction( + await sendAndConfirmTransaction( connection, createNonceAccount, - from, - nonceAccount, + [from, nonceAccount], + 0, ); const nonceBalance = await connection.getBalance(nonceAccount.publicKey); expect(nonceBalance).toEqual(minimumAmount); @@ -325,7 +325,7 @@ test('live Nonce actions', async () => { authorizedPubkey: from.publicKey, }), ); - await sendAndConfirmRecentTransaction(connection, advanceNonce, from); + await sendAndConfirmTransaction(connection, advanceNonce, [from], 0); const nonceQuery3 = await connection.getNonce(nonceAccount.publicKey); if (nonceQuery3 === null) { expect(nonceQuery3).not.toBeNull(); @@ -344,7 +344,7 @@ test('live Nonce actions', async () => { newAuthorizedPubkey: newAuthority.publicKey, }), ); - await sendAndConfirmRecentTransaction(connection, authorizeNonce, from); + await sendAndConfirmTransaction(connection, authorizeNonce, [from], 0); let transfer = SystemProgram.transfer({ fromPubkey: from.publicKey, @@ -359,11 +359,11 @@ test('live Nonce actions', async () => { }), }; - await sendAndConfirmRecentTransaction( + await sendAndConfirmTransaction( connection, transfer, - from, - newAuthority, + [from, newAuthority], + 0, ); const toBalance = await connection.getBalance(to.publicKey); expect(toBalance).toEqual(minimumAmount); @@ -380,11 +380,7 @@ test('live Nonce actions', async () => { toPubkey: withdrawAccount.publicKey, }), ); - await sendAndConfirmRecentTransaction( - connection, - withdrawNonce, - newAuthority, - ); + await sendAndConfirmTransaction(connection, withdrawNonce, [newAuthority], 0); expect(await connection.getBalance(nonceAccount.publicKey)).toEqual(0); const withdrawBalance = await connection.getBalance( withdrawAccount.publicKey, diff --git a/web3.js/test/transaction-payer.test.js b/web3.js/test/transaction-payer.test.js index 445b1e066e..b7a7939a29 100644 --- a/web3.js/test/transaction-payer.test.js +++ b/web3.js/test/transaction-payer.test.js @@ -3,7 +3,6 @@ import {Account, Connection, SystemProgram, LAMPORTS_PER_SOL} from '../src'; import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch'; import {mockGetRecentBlockhash} from './mockrpc/get-recent-blockhash'; import {url} from './url'; -import {sleep} from '../src/util/sleep'; if (!mockRpcEnabled) { // The default of 5 seconds is too slow for live testing sometimes @@ -106,19 +105,19 @@ test('transaction-payer', async () => { lamports: 10, }); - const signature = await connection.sendTransaction( - transaction, + const signature = await connection.sendTransaction(transaction, [ accountPayer, accountFrom, - ); + ]); mockRpc.push([ url, { - method: 'confirmTransaction', + method: 'getSignatureStatuses', params: [ - '3WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk', - {commitment: 'recent'}, + [ + '3WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk', + ], ], }, { @@ -127,21 +126,19 @@ test('transaction-payer', async () => { context: { slot: 11, }, - value: true, + value: [ + { + slot: 0, + confirmations: 1, + status: {Ok: null}, + err: null, + }, + ], }, }, ]); - let i = 0; - for (;;) { - if (await connection.confirmTransaction(signature)) { - break; - } - - expect(mockRpcEnabled).toBe(false); - expect(++i).toBeLessThan(10); - await sleep(500); - } + await connection.confirmTransaction(signature, 1); mockRpc.push([ url,