Skip to main content

rs_dapi_client/transport/
grpc.rs

1//! Listing of gRPC requests used in DAPI.
2
3use std::time::Duration;
4
5use super::create_channel;
6use super::{CanRetry, TransportClient, TransportError, TransportRequest};
7use super::{CoreGrpcClient, PlatformGrpcClient};
8use crate::connection_pool::{ConnectionPool, PoolPrefix};
9use crate::{request_settings::AppliedRequestSettings, RequestSettings, Uri};
10use dapi_grpc::core::v0::{self as core_proto};
11use dapi_grpc::platform::v0::{self as platform_proto};
12use dapi_grpc::tonic::{IntoRequest, Streaming};
13use futures::{future::BoxFuture, FutureExt, TryFutureExt};
14
15impl TransportClient for PlatformGrpcClient {
16    fn with_uri(uri: Uri, pool: &ConnectionPool) -> Result<Self, TransportError> {
17        Ok(pool
18            .get_or_create(PoolPrefix::Platform, &uri, None, || {
19                match create_channel(uri.clone(), None) {
20                    Ok(channel) => Ok(Self::new(channel).into()),
21                    Err(e) => Err(dapi_grpc::tonic::Status::invalid_argument(format!(
22                        "channel creation failed: {}",
23                        e
24                    ))),
25                }
26            })?
27            .into())
28    }
29
30    fn with_uri_and_settings(
31        uri: Uri,
32        settings: &AppliedRequestSettings,
33        pool: &ConnectionPool,
34    ) -> Result<Self, TransportError> {
35        Ok(pool
36            .get_or_create(
37                PoolPrefix::Platform,
38                &uri,
39                Some(settings),
40                || match create_channel(uri.clone(), Some(settings)) {
41                    Ok(channel) => {
42                        let mut client = Self::new(channel);
43                        if let Some(max_size) = settings.max_decoding_message_size {
44                            client = client.max_decoding_message_size(max_size);
45                        }
46                        Ok(client.into())
47                    }
48                    Err(e) => Err(dapi_grpc::tonic::Status::invalid_argument(format!(
49                        "Channel creation failed: {}",
50                        e
51                    ))),
52                },
53            )?
54            .into())
55    }
56}
57
58impl TransportClient for CoreGrpcClient {
59    fn with_uri(uri: Uri, pool: &ConnectionPool) -> Result<Self, TransportError> {
60        Ok(pool
61            .get_or_create(PoolPrefix::Core, &uri, None, || {
62                match create_channel(uri.clone(), None) {
63                    Ok(channel) => Ok(Self::new(channel).into()),
64                    Err(e) => Err(dapi_grpc::tonic::Status::invalid_argument(format!(
65                        "Channel creation failed: {}",
66                        e
67                    ))),
68                }
69            })?
70            .into())
71    }
72
73    fn with_uri_and_settings(
74        uri: Uri,
75        settings: &AppliedRequestSettings,
76        pool: &ConnectionPool,
77    ) -> Result<Self, TransportError> {
78        Ok(pool
79            .get_or_create(
80                PoolPrefix::Core,
81                &uri,
82                Some(settings),
83                || match create_channel(uri.clone(), Some(settings)) {
84                    Ok(channel) => {
85                        let mut client = Self::new(channel);
86                        if let Some(max_size) = settings.max_decoding_message_size {
87                            client = client.max_decoding_message_size(max_size);
88                        }
89                        Ok(client.into())
90                    }
91                    Err(e) => Err(dapi_grpc::tonic::Status::invalid_argument(format!(
92                        "Channel creation failed: {}",
93                        e
94                    ))),
95                },
96            )?
97            .into())
98    }
99}
100
101impl CanRetry for dapi_grpc::tonic::Status {
102    fn can_retry(&self) -> bool {
103        let code = self.code();
104
105        use dapi_grpc::tonic::Code::*;
106
107        matches!(
108            code,
109            Ok | DataLoss
110                | Cancelled
111                | Unknown
112                | DeadlineExceeded
113                | ResourceExhausted
114                | Aborted
115                | Internal
116                | Unavailable
117                // During a mixed-version network rollout, Unimplemented means this
118                // particular node runs an older build that doesn't expose the method
119                // yet; another node may serve it. Marking it retryable makes the
120                // executor ban the node (see `update_address_ban_status`) and retry
121                // elsewhere.
122                //
123                // When NO node implements the method, how the failure surfaces depends
124                // on which of `DapiClient::execute`'s two caps trips first:
125                //   * `live_addresses <= settings.retries` — the address list is
126                //     exhausted before the retry budget, so the error surfaces as the
127                //     non-retryable `NoAvailableAddressesToRetry`.
128                //   * `live_addresses > settings.retries` — the per-call retry budget
129                //     trips first, banning `settings.retries + 1` nodes and surfacing
130                //     the raw (still-retryable) `Unimplemented`. A caller that honors
131                //     `CanRetry` then re-enters and bans more nodes each round,
132                //     converging on the exhausted-addresses case above; rs-sdk also
133                //     bounds this via its own `total_retries` cap (see
134                //     `rs-sdk/src/sync.rs`). Either way the loop is bounded — it never
135                //     retries the same node forever.
136                //
137                // Caveat: bans are address-scoped, not (address, method)-scoped, and
138                // Unimplemented is also returned deliberately for genuinely unsupported
139                // / feature-gated endpoints (e.g. rs-drive-abci's
140                // broadcast_state_transition / wait_for_state_transition_result /
141                // get_consensus_params, and any rs-dapi `MethodNotFound`). Calling such
142                // an endpoint bans an otherwise-healthy node across ALL methods for the
143                // ban window. Acceptable for the targeted rollout case; per-method ban
144                // granularity is left as a follow-up so optional endpoints can't poison
145                // the shared address list. TODO(per-method-ban).
146                | Unimplemented
147        )
148    }
149
150    /// Returns the Envoy-advertised ban duration for a `ResourceExhausted`
151    /// response, or `None` if this is not a rate-limit or carries no usable
152    /// `RateLimit-Reset` header.
153    ///
154    /// Envoy's global rate-limit filter emits `RateLimit-Reset: <seconds>` when
155    /// `LIMIT_RESPONSE_HEADERS_ENABLED=true` is set on the Lyft RLS container
156    /// (see `packages/dashmate/docker-compose.rate_limiter.yml`).  The value is
157    /// the whole-second count until the per-IP window resets.
158    ///
159    /// Parse rules (adversarial-input safe):
160    /// * Non-`ResourceExhausted` code → `None`.
161    /// * Header absent, non-numeric, or `0` → `None` (caller uses normal ban
162    ///   ladder).
163    /// * Valid positive integer → clamped to
164    ///   [`[MIN_RATE_LIMIT_BAN_SECS, MAX_RATE_LIMIT_BAN_SECS]`]
165    ///   (`dapi_client.rs`) and returned as `Some(Duration)`.
166    fn rate_limit_ban_duration(&self) -> Option<std::time::Duration> {
167        use crate::dapi_client::{MAX_RATE_LIMIT_BAN_SECS, MIN_RATE_LIMIT_BAN_SECS};
168        use dapi_grpc::tonic::Code;
169        if self.code() != Code::ResourceExhausted {
170            return None;
171        }
172        let secs = self
173            .metadata()
174            .get("ratelimit-reset")
175            .and_then(|v| v.to_str().ok())
176            .and_then(|s| s.trim().parse::<u64>().ok())
177            .filter(|&s| s > 0)?;
178        Some(std::time::Duration::from_secs(
179            secs.clamp(MIN_RATE_LIMIT_BAN_SECS, MAX_RATE_LIMIT_BAN_SECS),
180        ))
181    }
182}
183
184/// Macro to implement the `TransportRequest` trait for a given request type, response type, client type, and settings.
185///
186/// # Parameters
187///
188/// - `$request:ty`: The request type for which the `TransportRequest` trait will be implemented.
189/// - `$response:ty`: The response type returned by the transport request.
190/// - `$client:ty`: The client type used to execute the transport request (eg. generated by `tonic` crate).
191/// - `$settings:expr`: The settings to be used for the transport request; these settings will override client's
192///   default settings, but can still be overridden by arguments to
193///   the [`DapiRequestExecutor::execute`](crate::DapiRequestExecutor::execute) method.
194/// - `$($method:tt)+`: The method of `$client` to be called to execute the request.
195///
196/// # Example
197///
198/// ```compile_fail
199/// impl_transport_request_grpc!(
200///     MyRequestType,
201///     MyResponseType,
202///     MyClientType,
203///     my_settings,
204///     my_method
205/// );
206/// ```
207///
208/// This will generate an implementation of the `TransportRequest` trait for `MyRequestType`
209/// that uses `MyClientType` to execute the `my_method` method, with the specified `my_settings`.
210///
211/// The generated implementation will:
212/// - Define the associated types `Client` and `Response`.
213/// - Set the `SETTINGS_OVERRIDES` constant to the provided settings.
214/// - Implement the `method_name` function to return the name of the method as a string.
215/// - Implement the `execute_transport` function to execute the transport request using the provided client and settings.
216macro_rules! impl_transport_request_grpc {
217    ($request:ty, $response:ty, $client:ty, $settings:expr, $($method:tt)+) => {
218        impl TransportRequest for $request {
219            type Client = $client;
220
221            type Response = $response;
222
223            const SETTINGS_OVERRIDES: RequestSettings = $settings;
224
225            fn method_name(&self) -> &'static str {
226                stringify!($($method)+)
227            }
228
229            fn execute_transport<'c>(
230                self,
231                client: &'c mut Self::Client,
232                settings: &AppliedRequestSettings,
233            ) -> BoxFuture<'c, Result<Self::Response, TransportError>>
234            {
235                let mut grpc_request = self.into_request();
236
237                if !settings.timeout.is_zero() {
238                    grpc_request.set_timeout(settings.timeout);
239                }
240
241                client
242                    .$($method)+(grpc_request)
243                    .map_err(TransportError::Grpc)
244                    .map_ok(|response| response.into_inner())
245                    .boxed()
246            }
247        }
248    };
249}
250
251// Link to each platform gRPC request what client and method to use:
252
253const STREAMING_TIMEOUT: Duration = Duration::from_secs(5 * 60);
254
255impl_transport_request_grpc!(
256    platform_proto::GetIdentityRequest,
257    platform_proto::GetIdentityResponse,
258    PlatformGrpcClient,
259    RequestSettings::default(),
260    get_identity
261);
262
263impl_transport_request_grpc!(
264    platform_proto::GetDocumentsRequest,
265    platform_proto::GetDocumentsResponse,
266    PlatformGrpcClient,
267    RequestSettings::default(),
268    get_documents
269);
270
271impl_transport_request_grpc!(
272    platform_proto::GetDataContractRequest,
273    platform_proto::GetDataContractResponse,
274    PlatformGrpcClient,
275    RequestSettings::default(),
276    get_data_contract
277);
278
279// rpc getDataContractsByRange(GetDataContractsByRangeRequest) returns (GetDataContractsResponse);
280impl_transport_request_grpc!(
281    platform_proto::GetDataContractsByRangeRequest,
282    platform_proto::GetDataContractsResponse,
283    PlatformGrpcClient,
284    RequestSettings::default(),
285    get_data_contracts_by_range
286);
287
288// rpc getDataContractsLatestVersions(GetDataContractsLatestVersionsRequest) returns (GetDataContractsLatestVersionsResponse);
289impl_transport_request_grpc!(
290    platform_proto::GetDataContractsLatestVersionsRequest,
291    platform_proto::GetDataContractsLatestVersionsResponse,
292    PlatformGrpcClient,
293    RequestSettings::default(),
294    get_data_contracts_latest_versions
295);
296
297// rpc getContractGroupInfo(GetContractGroupInfoRequest) returns (GetContractGroupInfoResponse);
298impl_transport_request_grpc!(
299    platform_proto::GetContractGroupInfoRequest,
300    platform_proto::GetContractGroupInfoResponse,
301    PlatformGrpcClient,
302    RequestSettings::default(),
303    get_contract_group_info
304);
305
306// rpc getContractGroupMembers(GetContractGroupMembersRequest) returns (GetContractGroupMembersResponse);
307impl_transport_request_grpc!(
308    platform_proto::GetContractGroupMembersRequest,
309    platform_proto::GetContractGroupMembersResponse,
310    PlatformGrpcClient,
311    RequestSettings::default(),
312    get_contract_group_members
313);
314
315// rpc getContractGroupsForContract(GetContractGroupsForContractRequest) returns (GetContractGroupsForContractResponse);
316impl_transport_request_grpc!(
317    platform_proto::GetContractGroupsForContractRequest,
318    platform_proto::GetContractGroupsForContractResponse,
319    PlatformGrpcClient,
320    RequestSettings::default(),
321    get_contract_groups_for_contract
322);
323
324impl_transport_request_grpc!(
325    platform_proto::GetConsensusParamsRequest,
326    platform_proto::GetConsensusParamsResponse,
327    PlatformGrpcClient,
328    RequestSettings::default(),
329    get_consensus_params
330);
331
332impl_transport_request_grpc!(
333    platform_proto::GetDataContractHistoryRequest,
334    platform_proto::GetDataContractHistoryResponse,
335    PlatformGrpcClient,
336    RequestSettings::default(),
337    get_data_contract_history
338);
339
340impl_transport_request_grpc!(
341    platform_proto::GetDocumentHistoryRequest,
342    platform_proto::GetDocumentHistoryResponse,
343    PlatformGrpcClient,
344    RequestSettings::default(),
345    get_document_history
346);
347
348impl_transport_request_grpc!(
349    platform_proto::BroadcastStateTransitionRequest,
350    platform_proto::BroadcastStateTransitionResponse,
351    PlatformGrpcClient,
352    RequestSettings::default(),
353    broadcast_state_transition
354);
355
356impl_transport_request_grpc!(
357    platform_proto::WaitForStateTransitionResultRequest,
358    platform_proto::WaitForStateTransitionResultResponse,
359    PlatformGrpcClient,
360    RequestSettings {
361        timeout: Some(Duration::from_secs(30)),
362        retries: Some(3),
363        ban_failed_address: None,
364        connect_timeout: None,
365        max_decoding_message_size: None,
366    },
367    wait_for_state_transition_result
368);
369
370impl_transport_request_grpc!(
371    platform_proto::GetIdentityByPublicKeyHashRequest,
372    platform_proto::GetIdentityByPublicKeyHashResponse,
373    PlatformGrpcClient,
374    RequestSettings::default(),
375    get_identity_by_public_key_hash
376);
377
378impl_transport_request_grpc!(
379    platform_proto::GetIdentityBalanceRequest,
380    platform_proto::GetIdentityBalanceResponse,
381    PlatformGrpcClient,
382    RequestSettings::default(),
383    get_identity_balance
384);
385
386impl_transport_request_grpc!(
387    platform_proto::GetIdentitiesBalancesRequest,
388    platform_proto::GetIdentitiesBalancesResponse,
389    PlatformGrpcClient,
390    RequestSettings::default(),
391    get_identities_balances
392);
393
394impl_transport_request_grpc!(
395    platform_proto::GetIdentityNonceRequest,
396    platform_proto::GetIdentityNonceResponse,
397    PlatformGrpcClient,
398    RequestSettings::default(),
399    get_identity_nonce
400);
401
402impl_transport_request_grpc!(
403    platform_proto::GetIdentityContractNonceRequest,
404    platform_proto::GetIdentityContractNonceResponse,
405    PlatformGrpcClient,
406    RequestSettings::default(),
407    get_identity_contract_nonce
408);
409
410impl_transport_request_grpc!(
411    platform_proto::GetIdentityKeysRemainingBudgetsRequest,
412    platform_proto::GetIdentityKeysRemainingBudgetsResponse,
413    PlatformGrpcClient,
414    RequestSettings::default(),
415    get_identity_keys_remaining_budgets
416);
417
418impl_transport_request_grpc!(
419    platform_proto::GetIdentityBalanceAndRevisionRequest,
420    platform_proto::GetIdentityBalanceAndRevisionResponse,
421    PlatformGrpcClient,
422    RequestSettings::default(),
423    get_identity_balance_and_revision
424);
425
426impl_transport_request_grpc!(
427    platform_proto::GetIdentitiesContractKeysRequest,
428    platform_proto::GetIdentitiesContractKeysResponse,
429    PlatformGrpcClient,
430    RequestSettings::default(),
431    get_identities_contract_keys
432);
433
434impl_transport_request_grpc!(
435    platform_proto::GetIdentityKeysRequest,
436    platform_proto::GetIdentityKeysResponse,
437    PlatformGrpcClient,
438    RequestSettings::default(),
439    get_identity_keys
440);
441
442impl_transport_request_grpc!(
443    platform_proto::GetEpochsInfoRequest,
444    platform_proto::GetEpochsInfoResponse,
445    PlatformGrpcClient,
446    RequestSettings::default(),
447    get_epochs_info
448);
449
450impl_transport_request_grpc!(
451    platform_proto::GetFinalizedEpochInfosRequest,
452    platform_proto::GetFinalizedEpochInfosResponse,
453    PlatformGrpcClient,
454    RequestSettings::default(),
455    get_finalized_epoch_infos
456);
457
458impl_transport_request_grpc!(
459    platform_proto::GetProtocolVersionUpgradeStateRequest,
460    platform_proto::GetProtocolVersionUpgradeStateResponse,
461    PlatformGrpcClient,
462    RequestSettings::default(),
463    get_protocol_version_upgrade_state
464);
465
466impl_transport_request_grpc!(
467    platform_proto::GetProtocolVersionUpgradeVoteStatusRequest,
468    platform_proto::GetProtocolVersionUpgradeVoteStatusResponse,
469    PlatformGrpcClient,
470    RequestSettings::default(),
471    get_protocol_version_upgrade_vote_status
472);
473
474impl_transport_request_grpc!(
475    platform_proto::GetDataContractsRequest,
476    platform_proto::GetDataContractsResponse,
477    PlatformGrpcClient,
478    RequestSettings::default(),
479    get_data_contracts
480);
481
482// rpc getContestedResources(GetContestedResourcesRequest) returns (GetContestedResourcesResponse);
483impl_transport_request_grpc!(
484    platform_proto::GetContestedResourcesRequest,
485    platform_proto::GetContestedResourcesResponse,
486    PlatformGrpcClient,
487    RequestSettings::default(),
488    get_contested_resources
489);
490
491//  rpc getContestedResourceVoteState(GetContestedResourceVoteStateRequest) returns (GetContestedResourceVoteStateResponse);
492impl_transport_request_grpc!(
493    platform_proto::GetContestedResourceVoteStateRequest,
494    platform_proto::GetContestedResourceVoteStateResponse,
495    PlatformGrpcClient,
496    RequestSettings::default(),
497    get_contested_resource_vote_state
498);
499
500// rpc getContestedResourceVotersForIdentity(GetContestedResourceVotersForIdentityRequest) returns (GetContestedResourceVotersForIdentityResponse);
501impl_transport_request_grpc!(
502    platform_proto::GetContestedResourceVotersForIdentityRequest,
503    platform_proto::GetContestedResourceVotersForIdentityResponse,
504    PlatformGrpcClient,
505    RequestSettings::default(),
506    get_contested_resource_voters_for_identity
507);
508// rpc getContestedResourceIdentityVoteStatus(GetContestedResourceIdentityVoteStatusRequest) returns (GetContestedResourceIdentityVoteStatusResponse);
509impl_transport_request_grpc!(
510    platform_proto::GetContestedResourceIdentityVotesRequest,
511    platform_proto::GetContestedResourceIdentityVotesResponse,
512    PlatformGrpcClient,
513    RequestSettings::default(),
514    get_contested_resource_identity_votes
515);
516// rpc GetVotePollsByEndDateRequest(GetVotePollsByEndDateRequest) returns (GetVotePollsByEndDateResponse);
517impl_transport_request_grpc!(
518    platform_proto::GetVotePollsByEndDateRequest,
519    platform_proto::GetVotePollsByEndDateResponse,
520    PlatformGrpcClient,
521    RequestSettings::default(),
522    get_vote_polls_by_end_date
523);
524
525// rpc GetEvonodesProposedEpochBlocksByIdsRequest(GetEvonodesProposedEpochBlocksByIdsRequest) returns (GetEvonodesProposedEpochBlocksResponse);
526impl_transport_request_grpc!(
527    platform_proto::GetEvonodesProposedEpochBlocksByIdsRequest,
528    platform_proto::GetEvonodesProposedEpochBlocksResponse,
529    PlatformGrpcClient,
530    RequestSettings::default(),
531    get_evonodes_proposed_epoch_blocks_by_ids
532);
533
534// rpc GetEvonodesProposedEpochBlocksByRangeRequest(GetEvonodesProposedEpochBlocksByRangeRequest) returns (GetEvonodesProposedEpochBlocksResponse);
535impl_transport_request_grpc!(
536    platform_proto::GetEvonodesProposedEpochBlocksByRangeRequest,
537    platform_proto::GetEvonodesProposedEpochBlocksResponse,
538    PlatformGrpcClient,
539    RequestSettings::default(),
540    get_evonodes_proposed_epoch_blocks_by_range
541);
542
543// rpc getPrefundedSpecializedBalance(GetPrefundedSpecializedBalanceRequest) returns (GetPrefundedSpecializedBalanceResponse);
544impl_transport_request_grpc!(
545    platform_proto::GetPrefundedSpecializedBalanceRequest,
546    platform_proto::GetPrefundedSpecializedBalanceResponse,
547    PlatformGrpcClient,
548    RequestSettings::default(),
549    get_prefunded_specialized_balance
550);
551
552// rpc getPathElements(GetPathElementsRequest) returns (GetPathElementsResponse);
553impl_transport_request_grpc!(
554    platform_proto::GetPathElementsRequest,
555    platform_proto::GetPathElementsResponse,
556    PlatformGrpcClient,
557    RequestSettings::default(),
558    get_path_elements
559);
560
561// rpc getTotalCreditsInPlatform(GetTotalCreditsInPlatformRequest) returns (GetTotalCreditsInPlatformResponse);
562impl_transport_request_grpc!(
563    platform_proto::GetTotalCreditsInPlatformRequest,
564    platform_proto::GetTotalCreditsInPlatformResponse,
565    PlatformGrpcClient,
566    RequestSettings::default(),
567    get_total_credits_in_platform
568);
569
570// rpc getCurrentQuorumsInfo(GetCurrentQuorumsInfoRequest) returns (GetCurrentQuorumsInfoResponse);
571impl_transport_request_grpc!(
572    platform_proto::GetCurrentQuorumsInfoRequest,
573    platform_proto::GetCurrentQuorumsInfoResponse,
574    PlatformGrpcClient,
575    RequestSettings::default(),
576    get_current_quorums_info
577);
578
579// rpc getShieldedEncryptedNotes(GetShieldedEncryptedNotesRequest) returns (GetShieldedEncryptedNotesResponse);
580impl_transport_request_grpc!(
581    platform_proto::GetShieldedEncryptedNotesRequest,
582    platform_proto::GetShieldedEncryptedNotesResponse,
583    PlatformGrpcClient,
584    RequestSettings::default(),
585    get_shielded_encrypted_notes
586);
587
588// rpc getShieldedAnchors(GetShieldedAnchorsRequest) returns (GetShieldedAnchorsResponse);
589impl_transport_request_grpc!(
590    platform_proto::GetShieldedAnchorsRequest,
591    platform_proto::GetShieldedAnchorsResponse,
592    PlatformGrpcClient,
593    RequestSettings::default(),
594    get_shielded_anchors
595);
596
597// rpc getMostRecentShieldedAnchor(GetMostRecentShieldedAnchorRequest) returns (GetMostRecentShieldedAnchorResponse);
598impl_transport_request_grpc!(
599    platform_proto::GetMostRecentShieldedAnchorRequest,
600    platform_proto::GetMostRecentShieldedAnchorResponse,
601    PlatformGrpcClient,
602    RequestSettings::default(),
603    get_most_recent_shielded_anchor
604);
605
606// rpc getShieldedPoolState(GetShieldedPoolStateRequest) returns (GetShieldedPoolStateResponse);
607impl_transport_request_grpc!(
608    platform_proto::GetShieldedPoolStateRequest,
609    platform_proto::GetShieldedPoolStateResponse,
610    PlatformGrpcClient,
611    RequestSettings::default(),
612    get_shielded_pool_state
613);
614
615// rpc getShieldedNotesCount(GetShieldedNotesCountRequest) returns (GetShieldedNotesCountResponse);
616impl_transport_request_grpc!(
617    platform_proto::GetShieldedNotesCountRequest,
618    platform_proto::GetShieldedNotesCountResponse,
619    PlatformGrpcClient,
620    RequestSettings::default(),
621    get_shielded_notes_count
622);
623
624// rpc getShieldedNullifiers(GetShieldedNullifiersRequest) returns (GetShieldedNullifiersResponse);
625impl_transport_request_grpc!(
626    platform_proto::GetShieldedNullifiersRequest,
627    platform_proto::GetShieldedNullifiersResponse,
628    PlatformGrpcClient,
629    RequestSettings::default(),
630    get_shielded_nullifiers
631);
632
633// Link to each core gRPC request what client and method to use:
634
635impl_transport_request_grpc!(
636    core_proto::GetTransactionRequest,
637    core_proto::GetTransactionResponse,
638    CoreGrpcClient,
639    RequestSettings::default(),
640    get_transaction
641);
642
643impl_transport_request_grpc!(
644    core_proto::GetBlockchainStatusRequest,
645    core_proto::GetBlockchainStatusResponse,
646    CoreGrpcClient,
647    RequestSettings::default(),
648    get_blockchain_status
649);
650
651impl_transport_request_grpc!(
652    core_proto::BroadcastTransactionRequest,
653    core_proto::BroadcastTransactionResponse,
654    CoreGrpcClient,
655    RequestSettings::default(),
656    broadcast_transaction
657);
658
659impl_transport_request_grpc!(
660    core_proto::TransactionsWithProofsRequest,
661    Streaming<core_proto::TransactionsWithProofsResponse>,
662    CoreGrpcClient,
663    RequestSettings {
664        timeout: Some(STREAMING_TIMEOUT),
665        ban_failed_address: None,
666        connect_timeout: None,
667        retries: None,
668        max_decoding_message_size: None,
669    },
670    subscribe_to_transactions_with_proofs
671);
672
673impl_transport_request_grpc!(
674    core_proto::MasternodeListRequest,
675    Streaming<core_proto::MasternodeListResponse>,
676    CoreGrpcClient,
677    RequestSettings {
678        timeout: Some(STREAMING_TIMEOUT),
679        ..RequestSettings::default()
680    },
681    subscribe_to_masternode_list
682);
683
684// rpc getStatus(GetStatusRequest) returns (GetStatusResponse);
685impl_transport_request_grpc!(
686    platform_proto::GetStatusRequest,
687    platform_proto::GetStatusResponse,
688    PlatformGrpcClient,
689    RequestSettings::default(),
690    get_status
691);
692
693//   rpc getIdentityByNonUniquePublicKeyHash(GetIdentityByNonUniquePublicKeyHashRequest) returns (GetIdentityByNonUniquePublicKeyHashResponse);
694impl_transport_request_grpc!(
695    platform_proto::GetIdentityByNonUniquePublicKeyHashRequest,
696    platform_proto::GetIdentityByNonUniquePublicKeyHashResponse,
697    PlatformGrpcClient,
698    RequestSettings::default(),
699    get_identity_by_non_unique_public_key_hash
700);
701
702// rpc getIdentityTokenBalances(GetIdentityTokenBalancesRequest) returns (GetIdentityTokenBalancesResponse);
703impl_transport_request_grpc!(
704    platform_proto::GetIdentityTokenBalancesRequest,
705    platform_proto::GetIdentityTokenBalancesResponse,
706    PlatformGrpcClient,
707    RequestSettings::default(),
708    get_identity_token_balances
709);
710
711// rpc getIdentitiesTokenBalances(GetIdentitiesTokenBalancesRequest) returns (GetIdentitiesTokenBalancesResponse);
712impl_transport_request_grpc!(
713    platform_proto::GetIdentitiesTokenBalancesRequest,
714    platform_proto::GetIdentitiesTokenBalancesResponse,
715    PlatformGrpcClient,
716    RequestSettings::default(),
717    get_identities_token_balances
718);
719
720// rpc getIdentityTokenInfos(GetIdentityTokenInfosRequest) returns (GetIdentityTokenInfosResponse);
721impl_transport_request_grpc!(
722    platform_proto::GetIdentityTokenInfosRequest,
723    platform_proto::GetIdentityTokenInfosResponse,
724    PlatformGrpcClient,
725    RequestSettings::default(),
726    get_identity_token_infos
727);
728
729// rpc getIdentitiesTokenInfos(GetIdentitiesTokenInfosRequest) returns (GetIdentitiesTokenInfosResponse);
730impl_transport_request_grpc!(
731    platform_proto::GetIdentitiesTokenInfosRequest,
732    platform_proto::GetIdentitiesTokenInfosResponse,
733    PlatformGrpcClient,
734    RequestSettings::default(),
735    get_identities_token_infos
736);
737
738// rpc getTokenStatuses(GetTokenStatusesRequest) returns (GetTokenStatusesResponse);
739impl_transport_request_grpc!(
740    platform_proto::GetTokenStatusesRequest,
741    platform_proto::GetTokenStatusesResponse,
742    PlatformGrpcClient,
743    RequestSettings::default(),
744    get_token_statuses
745);
746
747// rpc getTokenPreProgrammedDistributions(GetTokenPreProgrammedDistributionsRequest) returns (GetTokenPreProgrammedDistributionsResponse);
748impl_transport_request_grpc!(
749    platform_proto::GetTokenPreProgrammedDistributionsRequest,
750    platform_proto::GetTokenPreProgrammedDistributionsResponse,
751    PlatformGrpcClient,
752    RequestSettings::default(),
753    get_token_pre_programmed_distributions
754);
755
756// rpc getTokenTotalSupply(GetTokenTotalSupplyRequest) returns (GetTokenTotalSupplyResponse);
757impl_transport_request_grpc!(
758    platform_proto::GetTokenTotalSupplyRequest,
759    platform_proto::GetTokenTotalSupplyResponse,
760    PlatformGrpcClient,
761    RequestSettings::default(),
762    get_token_total_supply
763);
764
765// rpc getGroupInfo(GetGroupInfoRequest) returns (GetGroupInfoResponse);
766impl_transport_request_grpc!(
767    platform_proto::GetGroupInfoRequest,
768    platform_proto::GetGroupInfoResponse,
769    PlatformGrpcClient,
770    RequestSettings::default(),
771    get_group_info
772);
773
774// rpc getGroupInfos(GetGroupInfosRequest) returns (GetGroupInfosResponse);
775impl_transport_request_grpc!(
776    platform_proto::GetGroupInfosRequest,
777    platform_proto::GetGroupInfosResponse,
778    PlatformGrpcClient,
779    RequestSettings::default(),
780    get_group_infos
781);
782
783// rpc getGroupActions(GetGroupActionsRequest) returns (GetGroupActionsResponse);
784impl_transport_request_grpc!(
785    platform_proto::GetGroupActionsRequest,
786    platform_proto::GetGroupActionsResponse,
787    PlatformGrpcClient,
788    RequestSettings::default(),
789    get_group_actions
790);
791
792// rpc getGroupActionSigners(GetGroupActionSignersRequest) returns (GetGroupActionSignersResponse);
793impl_transport_request_grpc!(
794    platform_proto::GetGroupActionSignersRequest,
795    platform_proto::GetGroupActionSignersResponse,
796    PlatformGrpcClient,
797    RequestSettings::default(),
798    get_group_action_signers
799);
800
801// rpc getTokenDirectPurchasePrices(GetTokenDirectPurchasePricesRequest) returns (GetTokenDirectPurchasePricesResponse);
802impl_transport_request_grpc!(
803    platform_proto::GetTokenDirectPurchasePricesRequest,
804    platform_proto::GetTokenDirectPurchasePricesResponse,
805    PlatformGrpcClient,
806    RequestSettings::default(),
807    get_token_direct_purchase_prices
808);
809
810// rpc getTokenContractInfo(GetTokenContractInfoRequest) returns (GetTokenContractInfoResponse);
811impl_transport_request_grpc!(
812    platform_proto::GetTokenContractInfoRequest,
813    platform_proto::GetTokenContractInfoResponse,
814    PlatformGrpcClient,
815    RequestSettings::default(),
816    get_token_contract_info
817);
818
819// rpc getTokenPerpetualDistributionLastClaimRequest(GetTokenPerpetualDistributionLastClaimRequest) returns (GetTokenPerpetualDistributionLastClaimResponse);
820impl_transport_request_grpc!(
821    platform_proto::GetTokenPerpetualDistributionLastClaimRequest,
822    platform_proto::GetTokenPerpetualDistributionLastClaimResponse,
823    PlatformGrpcClient,
824    RequestSettings::default(),
825    get_token_perpetual_distribution_last_claim
826);
827
828// rpc getAddressInfo(GetAddressInfoRequest) returns (GetAddressInfoResponse);
829impl_transport_request_grpc!(
830    platform_proto::GetAddressInfoRequest,
831    platform_proto::GetAddressInfoResponse,
832    PlatformGrpcClient,
833    RequestSettings::default(),
834    get_address_info
835);
836
837// rpc getAddressesInfos(GetAddressesInfosRequest) returns (GetAddressesInfosResponse);
838impl_transport_request_grpc!(
839    platform_proto::GetAddressesInfosRequest,
840    platform_proto::GetAddressesInfosResponse,
841    PlatformGrpcClient,
842    RequestSettings::default(),
843    get_addresses_infos
844);
845
846// rpc getAddressesTrunkState(GetAddressesTrunkStateRequest) returns (GetAddressesTrunkStateResponse);
847impl_transport_request_grpc!(
848    platform_proto::GetAddressesTrunkStateRequest,
849    platform_proto::GetAddressesTrunkStateResponse,
850    PlatformGrpcClient,
851    RequestSettings::default(),
852    get_addresses_trunk_state
853);
854
855// rpc getAddressesBranchState(GetAddressesBranchStateRequest) returns (GetAddressesBranchStateResponse);
856impl_transport_request_grpc!(
857    platform_proto::GetAddressesBranchStateRequest,
858    platform_proto::GetAddressesBranchStateResponse,
859    PlatformGrpcClient,
860    RequestSettings::default(),
861    get_addresses_branch_state
862);
863
864// rpc getRecentAddressBalanceChanges(GetRecentAddressBalanceChangesRequest) returns (GetRecentAddressBalanceChangesResponse);
865impl_transport_request_grpc!(
866    platform_proto::GetRecentAddressBalanceChangesRequest,
867    platform_proto::GetRecentAddressBalanceChangesResponse,
868    PlatformGrpcClient,
869    RequestSettings::default(),
870    get_recent_address_balance_changes
871);
872
873// rpc getRecentCompactedAddressBalanceChanges(GetRecentCompactedAddressBalanceChangesRequest) returns (GetRecentCompactedAddressBalanceChangesResponse);
874impl_transport_request_grpc!(
875    platform_proto::GetRecentCompactedAddressBalanceChangesRequest,
876    platform_proto::GetRecentCompactedAddressBalanceChangesResponse,
877    PlatformGrpcClient,
878    RequestSettings {
879        // GetRecentCompactedAddressBalanceChangesResponse can have 100 values * 2048 addresses * ~44  bytes each = ~9MB
880        // We set it to 16MB to be safe
881        max_decoding_message_size: Some(16 * 1024 * 1024),
882        ..RequestSettings::default()
883    },
884    get_recent_compacted_address_balance_changes
885);