From b1387263a9e79dd2b693c593f53fe2c8b8a1fa32 Mon Sep 17 00:00:00 2001 From: huianyang Date: Tue, 28 May 2024 12:43:24 -0700 Subject: [PATCH 1/2] feat: supporting getAllDelegates in rpc --- docs/rpc_nodes_integration_test.md | 2 ++ integration-tests/__tests__/rpc/nodes.spec.ts | 9 +++++++ .../src/rpc-wrapper.ts | 7 ++++++ .../taquito-rpc/src/rpc-client-interface.ts | 3 +++ .../src/rpc-client-modules/rpc-cache.ts | 25 +++++++++++++++++++ packages/taquito-rpc/src/taquito-rpc.ts | 18 +++++++++++++ packages/taquito-rpc/src/types.ts | 7 ++++++ packages/taquito-rpc/test/rpc-cache.spec.ts | 12 +++++++++ packages/taquito-rpc/test/taquito-rpc.spec.ts | 15 +++++++++++ 9 files changed, 98 insertions(+) diff --git a/docs/rpc_nodes_integration_test.md b/docs/rpc_nodes_integration_test.md index a811b85c76..76416813ac 100644 --- a/docs/rpc_nodes_integration_test.md +++ b/docs/rpc_nodes_integration_test.md @@ -29,6 +29,7 @@ Remove `./rpc-nodes.spec.ts` from `"testPathIgnorePatterns"` in the package.json ✓ Verify that rpcClient.getManagerKey for known baker returns the manager key of the contract (30 ms) ✓ Verify that rpcClient.getDelegate for known baker returns the delegate of the contract (30 ms) ✓ Verify that rpcClient.getBigMapExpr for encoded expression returns the value associated with a key in a big map (151 ms) + ✓ Verify that rpcClient.getAllDelegates returns all delegates from RPC (132 ms) ✓ Verify that rpcClient.getDelegates for known baker returns information about a delegate from RPC (32 ms) ✓ Verify that rpc.getVotingInfo for known baker returns voting information about a delegate from RPC (30 ms) ✓ Verify that rpcClient.getConstants returns all constants from RPC (33 ms) @@ -86,6 +87,7 @@ Remove `./rpc-nodes.spec.ts` from `"testPathIgnorePatterns"` in the package.json ✓ Verify that rpcClient.getManagerKey for known baker returns the manager key of the contract (11 ms) ✓ Verify that rpcClient.getDelegate for known baker returns the delegate of the contract (8 ms) ✓ Verify that rpcClient.getBigMapExpr for encoded expression returns the value associated with a key in a big map (93 ms) + ✓ Verify that rpcClient.getAllDelegates returns all delegates from RPC (132 ms) ✓ Verify that rpcClient.getDelegates for known baker returns information about a delegate from RPC (10 ms) ✓ Verify that rpc.getVotingInfo for known baker returns voting information about a delegate from RPC (7 ms) ✓ Verify that rpcClient.getConstants returns all constants from RPC (10 ms) diff --git a/integration-tests/__tests__/rpc/nodes.spec.ts b/integration-tests/__tests__/rpc/nodes.spec.ts index 5a0fd6acf3..b3a5a1b304 100644 --- a/integration-tests/__tests__/rpc/nodes.spec.ts +++ b/integration-tests/__tests__/rpc/nodes.spec.ts @@ -152,6 +152,15 @@ CONFIGS().forEach( expect(bigMapValue).toBeDefined(); }); + it(`Verify that rpcClient.getAllDelegates returns all delegates from RPC`, async () => { + const allDelegates = await rpcClient.getAllDelegates(); + expect(allDelegates).toBeDefined(); + console.log(allDelegates) + const allViableDelegates = await rpcClient.getAllDelegates({active: true, with_minimal_stake: true}); + expect(allViableDelegates).toBeDefined(); + expect(allViableDelegates.length).toBeLessThanOrEqual(allDelegates.length); + }); + it(`Verify that rpcClient.getDelegates for known baker returns information about a delegate from RPC`, async () => { const delegates = await rpcClient.getDelegates(knownBaker); expect(delegates).toBeDefined(); diff --git a/packages/taquito-contracts-library/src/rpc-wrapper.ts b/packages/taquito-contracts-library/src/rpc-wrapper.ts index eb026ade9a..2b035d9249 100644 --- a/packages/taquito-contracts-library/src/rpc-wrapper.ts +++ b/packages/taquito-contracts-library/src/rpc-wrapper.ts @@ -50,6 +50,7 @@ import { PendingOperationsQueryArguments, RPCSimulateOperationParam, AILaunchCycleResponse, + AllDelegatesQueryArguments, } from '@taquito/rpc'; import { ContractsLibrary } from './taquito-contracts-library'; @@ -174,6 +175,12 @@ export class RpcWrapperContractsLibrary implements RpcClientInterface { ): Promise { return this.rpc.getBigMapExpr(id, expr, { block }); } + async getAllDelegates( + args: AllDelegatesQueryArguments, + { block }: RPCOptions = defaultRPCOptions + ): Promise { + return this.rpc.getAllDelegates(args, { block }); + } async getDelegates( address: string, { block }: RPCOptions = defaultRPCOptions diff --git a/packages/taquito-rpc/src/rpc-client-interface.ts b/packages/taquito-rpc/src/rpc-client-interface.ts index 72e56d5f02..e0d58341c6 100644 --- a/packages/taquito-rpc/src/rpc-client-interface.ts +++ b/packages/taquito-rpc/src/rpc-client-interface.ts @@ -50,6 +50,7 @@ import { PendingOperationsQueryArguments, RPCSimulateOperationParam, AILaunchCycleResponse, + AllDelegatesQueryArguments, } from './types'; export interface RPCOptions { @@ -81,6 +82,7 @@ export interface RpcClientInterface { getDelegate(address: string, options?: RPCOptions): Promise; getBigMapKey(address: string, key: BigMapKey, options?: RPCOptions): Promise; getBigMapExpr(id: string, expr: string, options?: RPCOptions): Promise; + getAllDelegates(args: AllDelegatesQueryArguments, options?: RPCOptions): Promise; getDelegates(address: string, options?: RPCOptions): Promise; getVotingInfo(address: string, options?: RPCOptions): Promise; getConstants(options?: RPCOptions): Promise; @@ -161,6 +163,7 @@ export enum RPCMethodName { GET_CURRENT_PROPOSAL = 'getCurrentProposal', GET_CURRENT_QUORUM = 'getCurrentQuorum', GET_DELEGATE = 'getDelegate', + GET_ALL_DELEGATES = 'getAllDelegates', GET_DELEGATES = 'getDelegates', GET_VOTING_INFO = 'getVotingInfo', GET_ATTESTATION_RIGHTS = 'getAttestationRights', diff --git a/packages/taquito-rpc/src/rpc-client-modules/rpc-cache.ts b/packages/taquito-rpc/src/rpc-client-modules/rpc-cache.ts index 1b4eea2eda..fe28642e2e 100644 --- a/packages/taquito-rpc/src/rpc-client-modules/rpc-cache.ts +++ b/packages/taquito-rpc/src/rpc-client-modules/rpc-cache.ts @@ -52,6 +52,7 @@ import { PendingOperationsV2, RPCSimulateOperationParam, AILaunchCycleResponse, + AllDelegatesQueryArguments, } from '../types'; import { InvalidAddressError, InvalidContractAddressError } from '@taquito/core'; import { @@ -73,6 +74,7 @@ type RpcMethodParam = | UnparsingMode | BigMapKey | BakingRightsQueryArguments + | AllDelegatesQueryArguments | PendingOperationsQueryArguments | AttestationRightsQueryArguments; @@ -546,6 +548,29 @@ export class RpcClientCache implements RpcClientInterface { } } + /** + * @param args contains optional query arguments (active, inactive, with_minimal_stake, without_minimal_stake) + * @param options contains generic configuration for rpc calls to specified block (default to head) + * @description Lists all registered delegates by default with query arguments to filter unneeded values. + * @see https://tezos.gitlab.io/active/rpc.html#get-block-id-context-delegates-pkh + */ + async getAllDelegates( + args: AllDelegatesQueryArguments = {}, + { block }: { block: string } = defaultRPCOptions + ): Promise { + const key = this.formatCacheKey(this.rpcClient.getRpcUrl(), RPCMethodName.GET_ALL_DELEGATES, [ + block, + args, + ]); + if (this.has(key)) { + return this.get(key); + } else { + const response = this.rpcClient.getAllDelegates(args, { block }); + this.put(key, response); + return response; + } + } + /** * @param address delegate address which we want to retrieve * @param options contains generic configuration for rpc calls to specified block (default to head) diff --git a/packages/taquito-rpc/src/taquito-rpc.ts b/packages/taquito-rpc/src/taquito-rpc.ts index cb67f97100..fb862c0af1 100644 --- a/packages/taquito-rpc/src/taquito-rpc.ts +++ b/packages/taquito-rpc/src/taquito-rpc.ts @@ -68,6 +68,7 @@ import { PendingOperationsV2, RPCSimulateOperationParam, AILaunchCycleResponse, + AllDelegatesQueryArguments, } from './types'; import { castToBigNumber } from './utils/utils'; import { @@ -477,6 +478,23 @@ export class RpcClient implements RpcClientInterface { }); } + /** + * @param args contains optional query arguments (active, inactive, with_minimal_stake, without_minimal_stake) + * @param options contains generic configuration for rpc calls to specified block (default to head) + * @description Lists all registered delegates by default with query arguments to filter unneeded values. + * @see https://tezos.gitlab.io/active/rpc.html#get-block-id-context-delegates-pkh + */ + async getAllDelegates( + args: AllDelegatesQueryArguments = {}, + { block }: { block: string } = defaultRPCOptions + ): Promise { + return await this.httpBackend.createRequest({ + url: this.createURL(`/chains/${this.chain}/blocks/${block}/context/delegates`), + method: 'GET', + query: args, + }); + } + /** * @param address delegate address which we want to retrieve * @param options contains generic configuration for rpc calls to specified block (default to head) diff --git a/packages/taquito-rpc/src/types.ts b/packages/taquito-rpc/src/types.ts index 7e6d789df2..930905bfe4 100644 --- a/packages/taquito-rpc/src/types.ts +++ b/packages/taquito-rpc/src/types.ts @@ -1125,6 +1125,13 @@ export type BakingRightsArgumentsDelegate = string | string[]; export type BakingRightsArgumentsCycle = number | number[]; export type BakingRightsArgumentsLevel = number | number[]; +export type AllDelegatesQueryArguments = { + active?: boolean; + inactive?: boolean; + with_minimal_stake?: boolean; + without_minimal_stake?: boolean; +}; + export type BakingRightsQueryArguments = BakingRightsQueryArgumentsBase; export interface BakingRightsQueryArgumentsBase { diff --git a/packages/taquito-rpc/test/rpc-cache.spec.ts b/packages/taquito-rpc/test/rpc-cache.spec.ts index 2a6c775a3f..d06ffc1d89 100644 --- a/packages/taquito-rpc/test/rpc-cache.spec.ts +++ b/packages/taquito-rpc/test/rpc-cache.spec.ts @@ -72,6 +72,7 @@ describe('RpcClientCache test', () => { getManagerKey: jest.fn(), getDelegate: jest.fn(), getBigMapExpr: jest.fn(), + getAllDelegates: jest.fn(), getDelegates: jest.fn(), getVotingInfo: jest.fn(), getConstants: jest.fn(), @@ -117,6 +118,7 @@ describe('RpcClientCache test', () => { mockRpcClient.getManagerKey.mockReturnValue(managerKey); mockRpcClient.getDelegate.mockReturnValue(delegate); mockRpcClient.getBigMapExpr.mockReturnValue(bigmapValue); + mockRpcClient.getAllDelegates.mockReturnValue([delegate]); mockRpcClient.getDelegates.mockReturnValue(delegates); mockRpcClient.getVotingInfo.mockReturnValue(votingInfo); mockRpcClient.getConstants.mockReturnValue(constants); @@ -167,6 +169,7 @@ describe('RpcClientCache test', () => { await rpcCache.getManagerKey(contractAddress); await rpcCache.getDelegate(address); await rpcCache.getBigMapExpr('72', 'expruPtxxirR4BVqFH43VcmEFZqHaQHJhZQDRVTMgSYAGGgBhBRxfp'); + await rpcCache.getAllDelegates(); await rpcCache.getDelegates(address); await rpcCache.getVotingInfo(address); await rpcCache.getConstants(); @@ -250,6 +253,9 @@ describe('RpcClientCache test', () => { 'rpcTest/getBigMapExpr/head/72/expruPtxxirR4BVqFH43VcmEFZqHaQHJhZQDRVTMgSYAGGgBhBRxfp/' ].response ).toEqual(bigmapValue); + expect(rpcCache.getAllCachedData()[`rpcTest/getAllDelegates/head/{}/`].response).toEqual([ + delegate, + ]); expect(rpcCache.getAllCachedData()[`rpcTest/getDelegates/head/${address}/`].response).toEqual( delegates ); @@ -335,6 +341,7 @@ describe('RpcClientCache test', () => { 'expruPtxxirR4BVqFH43VcmEFZqHaQHJhZQDRVTMgSYAGGgBhBRxfp', block ); + await rpcCache.getAllDelegates({}, block); await rpcCache.getDelegates(address, block); await rpcCache.getVotingInfo(address, block); await rpcCache.getConstants(block); @@ -433,6 +440,10 @@ describe('RpcClientCache test', () => { `rpcTest/getBigMapExpr/${block.block}/72/expruPtxxirR4BVqFH43VcmEFZqHaQHJhZQDRVTMgSYAGGgBhBRxfp/` ].response ).toEqual(bigmapValue); + console.log(`rpcTest/getAllDelegates/${block.block}/{}`); + expect( + rpcCache.getAllCachedData()[`rpcTest/getAllDelegates/${block.block}/{}/`].response + ).toEqual([delegate]); expect( rpcCache.getAllCachedData()[`rpcTest/getDelegates/${block.block}/${address}/`].response ).toEqual(delegates); @@ -520,6 +531,7 @@ describe('RpcClientCache test', () => { await rpcCache.getManagerKey(contractAddress); await rpcCache.getDelegate(address); await rpcCache.getBigMapExpr('72', 'expruPtxxirR4BVqFH43VcmEFZqHaQHJhZQDRVTMgSYAGGgBhBRxfp'); + await rpcCache.getAllDelegates(); await rpcCache.getDelegates(address); await rpcCache.getVotingInfo(address); await rpcCache.getConstants(); diff --git a/packages/taquito-rpc/test/taquito-rpc.spec.ts b/packages/taquito-rpc/test/taquito-rpc.spec.ts index e35bc95caa..97ad9451d2 100644 --- a/packages/taquito-rpc/test/taquito-rpc.spec.ts +++ b/packages/taquito-rpc/test/taquito-rpc.spec.ts @@ -323,6 +323,21 @@ describe('RpcClient test', () => { }); }); + describe('getAllDelegates', () => { + it('should query the right url and data', async () => { + httpBackend.createRequest.mockResolvedValue(['tz1cjyja1TU6fiyiFav3mFAdnDsCReJ12hPD']); + const result = await client.getAllDelegates({ active: true, with_minimal_stake: true }); + await client.getAllDelegates({ active: true, with_minimal_stake: true }); + expect(httpBackend.createRequest.mock.calls[0][0]).toEqual({ + method: 'GET', + url: 'root/chains/test/blocks/head/context/delegates', + query: { active: true, with_minimal_stake: true }, + }); + + expect(result).toEqual(['tz1cjyja1TU6fiyiFav3mFAdnDsCReJ12hPD']); + }); + }); + describe('getDelegates', () => { const sampleResponse = { full_balance: new BigNumber('10289576365'), From a0eb8b5c3b0a33ec16b0dc9ce4ff034681137d8b Mon Sep 17 00:00:00 2001 From: huianyang Date: Tue, 28 May 2024 13:34:09 -0700 Subject: [PATCH 2/2] test: remove unneeded logging --- integration-tests/__tests__/rpc/nodes.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/integration-tests/__tests__/rpc/nodes.spec.ts b/integration-tests/__tests__/rpc/nodes.spec.ts index b3a5a1b304..55024b52d4 100644 --- a/integration-tests/__tests__/rpc/nodes.spec.ts +++ b/integration-tests/__tests__/rpc/nodes.spec.ts @@ -155,9 +155,10 @@ CONFIGS().forEach( it(`Verify that rpcClient.getAllDelegates returns all delegates from RPC`, async () => { const allDelegates = await rpcClient.getAllDelegates(); expect(allDelegates).toBeDefined(); - console.log(allDelegates) + const allViableDelegates = await rpcClient.getAllDelegates({active: true, with_minimal_stake: true}); expect(allViableDelegates).toBeDefined(); + expect(allViableDelegates.length).toBeLessThanOrEqual(allDelegates.length); });