diff --git a/web3.js/src/connection.js b/web3.js/src/connection.js index ee59088d82..8b285c599f 100644 --- a/web3.js/src/connection.js +++ b/web3.js/src/connection.js @@ -365,6 +365,11 @@ const GetTotalSupplyRpcResult = jsonRpcResult('number'); */ const GetMinimumBalanceForRentExemptionRpcResult = jsonRpcResult('number'); +/** + * Expected JSON RPC response for the "getBlocksSince" message + */ +const GetBlocksSinceRpcResult = jsonRpcResult(struct.list(['number'])); + /** * Expected JSON RPC response for the "getRecentBlockhash" message */ @@ -853,6 +858,19 @@ export class Connection { return res.result; } + /** + * Fetch a list of rooted blocks from the cluster + */ + async getBlocksSince(slot: number): Promise> { + const unsafeRes = await this._rpcRequest('getBlocksSince', [slot]); + const res = GetBlocksSinceRpcResult(unsafeRes); + if (res.error) { + throw new Error(res.error.message); + } + assert(typeof res.result !== 'undefined'); + return res.result; + } + /** * Request an allocation of lamports to the specified account */ diff --git a/web3.js/src/transaction.js b/web3.js/src/transaction.js index 7257fceade..804dd47535 100644 --- a/web3.js/src/transaction.js +++ b/web3.js/src/transaction.js @@ -445,7 +445,7 @@ export class Transaction { const PUBKEY_LENGTH = 32; const SIGNATURE_LENGTH = 64; - function isCreditDebit( + function isWritable( i: number, numRequiredSignatures: number, numReadonlySignedAccounts: number, @@ -530,7 +530,7 @@ export class Transaction { isSigner: transaction.signatures.some( keyObj => keyObj.publicKey.toString() === pubkey.toString(), ), - isWritable: isCreditDebit( + isWritable: isWritable( j, numRequiredSignatures, numReadonlySignedAccounts, diff --git a/web3.js/test/connection.test.js b/web3.js/test/connection.test.js index 59b6715f2b..9be8e460ea 100644 --- a/web3.js/test/connection.test.js +++ b/web3.js/test/connection.test.js @@ -419,6 +419,49 @@ test('get minimum balance for rent exemption', async () => { expect(count).toBeGreaterThanOrEqual(0); }); +test('get blocks since slot', async () => { + const connection = new Connection(url); + + const expectedBlocks = [0, 1, 3, 4, 7, 8]; + mockRpc.push([ + url, + { + method: 'getBlocksSince', + params: [0], + }, + { + error: null, + result: expectedBlocks, + }, + ]); + + const blocks = await connection.getBlocksSince(0); + + if (mockRpcEnabled) { + expect(blocks.length).toEqual(6); + } else { + // No idea how many blocks since slot 0 on a live cluster + expect(blocks.length).toBeGreaterThan(0); + } + + const errorMessage = 'Slot 10000: SlotNotRooted'; + mockRpc.push([ + url, + { + method: 'getBlocksSince', + params: [10000], + }, + { + error: { + message: errorMessage, + }, + result: undefined, + }, + ]); + + await expect(connection.getBlocksSince(10000)).rejects.toThrow(errorMessage); +}); + test('get recent blockhash', async () => { const connection = new Connection(url);