xref: /aosp_15_r20/external/federated-compute/fcp/protos/federated_api.proto (revision 14675a029014e728ec732f129a32e299b2da0601)
1/*
2 * Copyright 2019 Google LLC
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17syntax = "proto3";
18
19package google.internal.federatedml.v2;
20
21import "google/protobuf/any.proto";
22import "google/protobuf/duration.proto";
23import "fcp/secagg/shared/secagg_messages.proto";
24
25option java_package = "com.google.internal.federatedml.v2";
26option java_multiple_files = true;
27option java_outer_classname = "FederatedProto";
28
29// `FederatedTrainingApi` provides the protocol between a device and
30// cloud servers for federated computations.
31//
32// This API works as follows:
33//
34// 1. Clients are associated with *populations*. A population is
35//    uniquely identified by an opaque string which indicates the
36//    application together with additional information like a specific
37//    flavor within this application.
38//
39// 2. Periodically, clients issue an `EligibilityEvalCheckinRequest` to indicate
40//    they are interested in participating in a computation, followed by a
41//    `CheckinRequest` to actually be assigned one of the available
42//    computations they are compatible with. These requests specify the
43//    population for which the requests are issued.
44//
45// 3. The server decides whether the client shall participate in a computation,
46//    and if so returns the data (a computation description and a checkpoint)
47//    needed for the client to start executing the computation.
48//
49// 4. If the client is selected, it performs local execution. When done, the
50//    client issues a `ReportRequest`, specifying both population and phase id,
51//    and the updated checkpoint.
52service FederatedTrainingApi {
53  // Initiates client-server communication session (bidirectional stream).
54  rpc Session(stream ClientStreamMessage) returns (stream ServerStreamMessage) {
55  }
56}
57
58// Message sent from a client to a server in a bidirectional stream.
59// The message is sent either directly or (for large messages when chunking
60// is supported) split into chunk encapsulated into smaller instances of
61// ClientStreamMessage.
62message ClientStreamMessage {
63  // Different kinds of messages.
64  oneof kind {
65    // Checkin request.
66    CheckinRequest checkin_request = 1;
67
68    // Report request.
69    ReportRequest report_request = 2;
70
71    // Transfer of ClientStreamMessage in multiple chunks
72    ChunkedTransferMessage chunked_transfer = 6;
73
74    // Eligibility evaluation checkin request.
75    EligibilityEvalCheckinRequest eligibility_eval_checkin_request = 7;
76  }
77
78  // Secure Aggregation messages.  These form a parallel stream of
79  // messages, and so are outside the 'kind' oneof.
80  fcp.secagg.ClientToServerWrapperMessage secure_aggregation_client_message = 4;
81
82  repeated google.protobuf.Any serialized_side_channel_event = 5;
83
84  // Internal identifier of the connection to the client. This value isn't set
85  // by the device (ignored if set), but used by the server when forwarding
86  // requests internally within the system.
87  string internal_client_id = 3 [deprecated = true];
88}
89
90// Message sent from a server to a client in a bidirectional stream.
91// The message is sent either directly or (for large messages when chunking
92// is supported) split into chunks encapsulated into smaller instances of
93// ServerStreamMessage.
94message ServerStreamMessage {
95  // Different kinds of messages.
96  oneof kind {
97    // Checkin response.
98    CheckinResponse checkin_response = 1;
99
100    // Report response.
101    ReportResponse report_response = 2;
102
103    // Transfer of ServerStreamMessage in multiple chunks
104    ChunkedTransferMessage chunked_transfer = 4;
105
106    // Ack of a CheckinRequest or an EligibilityEvalCheckinRequest. See {@link
107    // CheckinRequest} for details.
108    CheckinRequestAck checkin_request_ack = 5;
109
110    // Eligibility evaluation checkin response.
111    EligibilityEvalCheckinResponse eligibility_eval_checkin_response = 6;
112
113    // This is expected to be extended in upcoming versions of the protocol
114  }
115
116  // Secure Aggregation messages.  These form a parallel stream of
117  // messages, and so are outside the 'kind' oneof.
118  fcp.secagg.ServerToClientWrapperMessage secure_aggregation_server_message = 3;
119}
120
121// Supported levels of compression for chunked blob transfer.
122enum CompressionLevel {
123  // Compression disabled
124  UNCOMPRESSED = 0;
125  // zlib compression with default settings; this level uses gzip-6
126  // (currently).
127  // 'Z_DEFAULT_COMPRESSION requests a default compromise between speed and
128  // compression (currently equivalent to level 6).'
129  // Source - // http://www.zlib.net/manual.html
130  ZLIB_DEFAULT = 1;
131  // zlib compression optimized for most compression; this level uses gzip-9.
132  // '9 gives best compression' Source - http://www.zlib.net/manual.html
133  ZLIB_BEST_COMPRESSION = 2;
134  // zlib compression optimized for speed; this level uses gzip-1.
135  // '1 gives best speed' Source - http://www.zlib.net/manual.html
136  ZLIB_BEST_SPEED = 3;
137}
138
139// Supported compressed file formats for HTTP downloads.
140enum HttpCompressionFormat {
141  HTTP_COMPRESSION_FORMAT_UNSPECIFIED = 0;
142  // Gzip-compressed data. If data is compressed in this way, then the
143  // "Content-Type" HTTP response header will have a "+gzip" suffix.
144  HTTP_COMPRESSION_FORMAT_GZIP = 1;
145}
146
147// A request, sent by the device to check if it should participate
148// in the current phase.
149message CheckinRequest {
150  // The name of the population this client belongs to.
151  string population_name = 1;
152
153  // Optional. Retry token (opaque to the client) passed by the server when last
154  // participated in the training or rejected. If clients have such a token
155  // available, they should provide it. If not, things are still expected to
156  // work, but providing this gives server better control on organizing
157  // participation.
158  //
159  // Note that an `EligibilityEvalCheckinRequest` and its subsequent
160  // `CheckinRequest` request will both use the same value for this field,
161  // since both requests are considered part of the same logical protocol
162  // session.
163  string retry_token = 2;
164
165  reserved 3;
166
167  // The attestation measurement providing evidence of integrity for this
168  // client. The measurement is bound to the population_name and retry_token
169  // values in this CheckinRequest.
170  //
171  // Note that an `EligibilityEvalCheckinRequest` and its subsequent
172  // `CheckinRequest` request will both use the same value for this field,
173  // since both requests are considered part of the same logical protocol
174  // session.
175  string attestation_measurement = 4;
176
177  // Protocol options supported by the client.
178  ProtocolOptionsRequest protocol_options_request = 5;
179
180  string client_version = 6 ;
181
182  // The client computes this message using the plan returned by a previous
183  // `EligibilityEvalCheckinResponse`.
184  //
185  // If this field is set, it describes to the server which tasks the client is
186  // (in)eligible. The server must take this information into account when
187  // deciding task to serve in response to this request.
188  //
189  // If this field is unset, it may indicate that the client previously received
190  // an `EligibilityEvalCheckinResponse` without an
191  // `EligibilityEvalPayload` message (i.e. the population did not
192  // have an eligibility-computing task configured at the time of the request).
193  // It may also indicate a client for which the eligibility-computing task
194  // feature has been disabled, or an old client that does not support this
195  // feature yet.
196  //
197  // If this field is unset but the population has an eligibility-computing task
198  // configured, then the server must reject this client, since the server has
199  // no way to determine which tasks the client is (in)eligible for.
200  //
201  // If this field is unset and the population does not have an
202  // eligibility-computing task configured, then the server may serve this
203  // client any task.
204  //
205  TaskEligibilityInfo task_eligibility_info = 7;
206}
207
208// Describes to the server which tasks a client is eligible for.
209message TaskEligibilityInfo {
210  // A semantic version describing how the set of eligibility descriptors should
211  // be interpreted. This fields enables assigning different semantics for how
212  // the server should interpret the descriptors, without having to change the
213  // wire format (e.g. different ways of interpreting `TaskWeight.weight`).
214  int64 version = 1;
215
216  // A list of task weights, which the server may use when assigning the client
217  // a task in response to the current request.
218  //
219  // If none of the `TaskWeight` messages match a given task, then the client
220  // must be considered ineligible for that task, and the server must not serve
221  // the client that task.
222  //
223  // Therefore, if a `TaskEligibilityInfo` message is provided but this field is
224  // empty then the client should be considered ineligible for all tasks in the
225  // population (although in practice the client will simply close the
226  // connection in that case, rather than issue a `CheckinRequest` with such an
227  // empty list of weights).
228  repeated TaskWeight task_weights = 2;
229}
230
231// Describes a weight that should be assigned to a specific task.
232message TaskWeight {
233  // Name of the task this weight applies to.
234  string task_name = 1;
235
236  // The weight that should be applied to the specified task.
237  //
238  // Must be >0.
239  //
240  // This weight may (or may not) be used by the server to implement some form
241  // of task or client prioritization.
242  float weight = 2;
243}
244
245// Response to the checkin request, sent to the device.
246message CheckinResponse {
247  // One of two outcomes, depending on server's decision on participation of the
248  // client.
249  oneof checkin_result {
250    // If the client joined the phase with this call, information how
251    // to proceed.
252    AcceptanceInfo acceptance_info = 1;
253
254    // If the client was not accepted, information how to proceed.
255    RejectionInfo rejection_info = 2;
256  }
257
258  // Instructions from server to the client how to execute protocol.
259  // While, conceptually, chunked transfer is a symmetric protocol with respect
260  // to peers (both server and client act like senders and receivers), the
261  // protocol handshake and configuration part is intentionally skewed towards
262  // the server driving the decisions on how chunking are performed on the wire,
263  // so we have a centralized way of controlling the feature.
264  //
265  // Note that if a client receives more than one `ProtocolOptionsResponse` over
266  // the life of a protocol session (e.g. in
267  // `EligibilityEvalCheckinResponse` as well as `CheckinResponse`)
268  // then the client will use the most recently-received value for further
269  // communications with the server.
270  ProtocolOptionsResponse protocol_options_response = 4;
271
272  reserved 3;
273}
274
275// Acknowledgement for a `CheckinRequest` or an `EligibilityEvalCheckinRequest`
276// from the client. This happens almost instantenously for all clients (that
277// request an ack using ProtocolRequestOptions#should_ack_checkin) as soon as
278// they issue either request, and happens *before* either a `CheckinResponse`
279// or a `EligibilityEvalCheckinResponse` is returned to the client.
280message CheckinRequestAck {
281  // Retry window to use for the next checkin attempt if this attempt ends up
282  // being subsequently accepted by the server, as in the client received a
283  // CheckinResponse with an AcceptanceInfo.
284  RetryWindow retry_window_if_accepted = 1;
285
286  // Retry window to use if this checkin attempt is not accepted by the server,
287  // as in the client doesn't receive a CheckinResponse with an AcceptanceInfo.
288  RetryWindow retry_window_if_rejected = 2;
289}
290
291// A request, sent by the device to request the eligibility-computing plan for
292// the population. This plan is run by the client to generate a
293// `TaskEligibilityInfo` proto result, which is then included with a subsequent
294// `CheckinRequest` (within the same protocol session) to inform the server
295// which tasks the client is eligible for.
296//
297// The use of an `EligibilityEvalCheckinRequest` is optional (i.e. clients
298// may simply issue a `CheckinRequest` without a preceding
299// `EligibilityEvalCheckinRequest`, in which case the
300// `CheckinRequest.task_eligibility_info` field will be left unset).
301message EligibilityEvalCheckinRequest {
302  // The name of the population this client belongs to.
303  string population_name = 1;
304
305  // Optional. This field has the same semantics as
306  // `CheckinRequest.retry_token`, see that field for details.
307  string retry_token = 2;
308
309  // This field has the same semantics as
310  // `CheckinRequest.attestation_measurement`.
311  // See that field for details.
312  string attestation_measurement = 4;
313
314  // Protocol options supported by the client.
315  ProtocolOptionsRequest protocol_options_request = 5;
316
317  // This field has the same semantics as `CheckinRequest.client_version`. See
318  // that field for details.
319  string client_version = 6 ;
320
321  // The client's capabilities when downloading and running Eligibility Eval
322  // tasks.
323  EligibilityEvalTaskCapabilities eligibility_eval_task_capabilities = 7;
324}
325
326// The client's capabilities for determining task eligibility.
327message EligibilityEvalTaskCapabilities {
328  // Whether the client supports multiple task assignment
329  // (/TaskAssignments.PerformMultipleTaskAssignments). If false, the client
330  // will not be provided information about tasks that require multiple task
331  // assignment.
332  bool supports_multiple_task_assignment = 1;
333}
334
335// Response to the `EligibilityEvalCheckinRequest`, sent to the
336// device.
337message EligibilityEvalCheckinResponse {
338  // Each response will contain one of the following results.
339  oneof checkin_result {
340    // If the population has an eligibility-computing plan configured, and if
341    // the client is compatible with that plan, then this field will be set,
342    // containing the plan's payload. The client should run the plan and include
343    // its `TaskEligibilityInfo` result in the subsequent `CheckinRequest`.
344    EligibilityEvalPayload eligibility_eval_payload = 1;
345
346    // If the population does not have an eligibility-computing plan configured,
347    // then this field will be set. The client should continue by issuing a
348    // `CheckinRequest` without the `task_eligibility_info` field set.
349    NoEligibilityEvalConfigured no_eligibility_eval_configured = 2;
350
351    // If the population has an eligibility-computing plan configured, but the
352    // client is incompatible with that plan, then this field will be set.
353    RejectionInfo rejection_info = 3;
354  }
355
356  // This field has the same semantics as
357  // `CheckinResponse.protocol_options_response`. See that field for details.
358  ProtocolOptionsResponse protocol_options_response = 4;
359}
360
361// Contains the eligibility evaluation plan payload.
362message EligibilityEvalPayload {
363  oneof init_checkpoint_type {
364    // A blob representing the checkpoint to start execution from.
365    bytes init_checkpoint = 1;
366
367    // A URI and other metadata of the checkpoint to start execution from.
368    UriResource init_checkpoint_resource = 4;
369  }
370
371  oneof plan_type {
372    // A blob representing the plan to be used for execution.
373    bytes plan = 2;
374
375    // A URI and other metadata of the plan to be used for execution.
376    UriResource plan_resource = 5;
377  }
378
379  oneof population_eligibility_spec_type {
380    // A serialized PopulationEligibilitySpec describing the eligibility
381    // criteria for tasks in the population.
382    bytes population_eligibility_spec = 6;
383
384    // A URI and other metadata of the population eligibility spec to be used.
385    UriResource population_eligibility_spec_resource = 7;
386  }
387
388  // The opaque id of the eligibility evaluation plan payload the client is
389  // being given. This is a string generated by the server and used by the
390  // client for logging purposes. This id MUST NOT contain any information that
391  // could be used to identify a specific device.
392  // Also see the similar `AcceptanceInfo.execution_phase_id`.
393  string execution_id = 3;
394}
395
396// Currently-empty message describing the case where a population does not have
397// an eligibility-computing plan configured.
398message NoEligibilityEvalConfigured {}
399
400// Per-aggregand dynamic configuration information for side channel protocols.
401message SideChannelExecutionInfo {
402  // Dynamic configuration for SecureAggregation side channels.
403  message SecureAggregandExecutionInfo {
404    // Bitwidth for secure-aggregation.  This must be wide enough to
405    // encode the sum of all client inputs, given the current number of clients
406    // participating in the protocol.
407    //
408    // This field is deprecated; use modulus instead.
409    int32 output_bitwidth = 1 [deprecated = true];
410
411    // Modulus for secure aggregation.
412    //
413    // The secure aggregation protocol will compute the sum modulo this modulus.
414    //
415    // To achieve equivalence with non-modular summation, the modulus must be
416    // larger than the sum of all client inputs, given the number of clients
417    // participating in the aggregation shard.
418    //
419    // If modulus is missing but output_bitwidth is specified, modulus will
420    // will be taken to be 2**output_bitwidth (for backwards compatibility).
421    uint64 modulus = 2;
422  }
423
424  // What type of side channel is used.
425  oneof type {
426    // Dynamic configuration for Secure Aggregation side channels.
427    SecureAggregandExecutionInfo secure_aggregand = 1;
428  }
429}
430
431// Per-protocol options information for side channel protocols.
432message SideChannelProtocolOptionsRequest {
433  // Options for SecureAggregation side channels.
434  message SecureAggregation {
435    // Protocol versions available.
436    repeated fcp.secagg.ClientVariant client_variant = 2;
437  }
438
439  // Protocol options for Secure Aggregation side channels.
440  SecureAggregation secure_aggregation = 1;
441}
442
443// Negotiated settings for side channel protocols. Side channel options may not
444// be set for channels which will not be used in the ReportRequest.
445message SideChannelProtocolOptionsResponse {
446  // Server-directed secure aggregation options to apply.
447  message SecureAggregation {
448    // The client variant to use.
449    fcp.secagg.ClientVariant client_variant = 1;
450  }
451
452  // SecureAggregation protocol options.  Only set if a SecureAggregation plan
453  // will be used.
454  SecureAggregation secure_aggregation = 1;
455}
456
457// Per-protocol dynamic configuration information for side channel protocols.
458message SideChannelProtocolExecutionInfo {
459  // Dynamic configuration for SecureAggregation side channels.
460  message SecureAggregationProtocolExecutionInfo {
461    // Number of clients that a client may exchange data with while running
462    // Secure Aggregation protocol. In the case of a full graph SecAgg protocol
463    // this is a total number of clients that started the protocol.
464    // In the case of subgraph SecAgg protocol this is a number of neighbours
465    // that each client has.
466    int32 expected_number_of_clients = 1;
467
468    // Secure Aggregation client completion threshold. This is a parameter
469    // communicated by the server side of Secure Aggregation protocol to each
470    // client to establish Shamir sharing of secrets.
471    // Additionally, at least `minimum_surviving_clients_for_reconstruction` out
472    // of the initial `expected_number_of_clients` must 'survive' in order for
473    // the protocol to continue on the client side; otherwise the client will
474    // abort its connection.
475    int32 minimum_surviving_clients_for_reconstruction = 2;
476
477    // The minimum number of clients' values that must be aggregated together
478    // before the server can gain access to the aggregate,
479    // even transiently (e.g. in RAM).
480    // This isn't needed by Secure Aggregation protocol on the client side but
481    // shared by the server with clients for transparency or policy reasons.
482    int32 minimum_clients_in_server_visible_aggregate = 3;
483  }
484
485  // Dynamic configuration for Secure Aggregation side channels.
486  SecureAggregationProtocolExecutionInfo secure_aggregation = 1;
487}
488
489// When client (device) supports HTTP download of resources, this message
490// is used to carry information about each individual downloadable resource.
491message UriResource {
492  // Resource URI e.g. fully qualified URL.
493  string uri = 1;
494
495  // Stable identifier for this resource, used by the client cache
496  // implementation. If this field is not set, the client should not attempt to
497  // cache the resource referenced by `uri`.
498  string client_cache_id = 2;
499
500  // The maximum duration for how long the resource should be cached by the
501  // client. Not set if `client_cache_id` is not set.
502  google.protobuf.Duration max_age = 3;
503}
504
505// When client (device) is accepted for the current phase, this
506// data structure carries information necessary to begin training.
507message AcceptanceInfo {
508  // The opaque id of the phase the client has joined. This is a string
509  // generated by the server and used by the client for logging purposes.
510  // This id MUST NOT contain any information that could be used to identify
511  // a specific device.
512  string execution_phase_id = 1;
513
514  // The name identifying the task for which the client was accepted.
515  string task_name = 10;
516
517  oneof init_checkpoint_type {
518    // A blob representing the checkpoint to start execution from.
519    bytes init_checkpoint = 2;
520
521    // A URI and other metadata of the checkpoint to start execution from.
522    UriResource init_checkpoint_resource = 8;
523  }
524
525  // Note: Plan fields below should be unset when included in a JoinResponse
526  // from the aggregator to the selector, and then set by the selector before
527  // sending on to the client.
528  oneof plan_type {
529    // A blob representing the plan to be used for execution.
530    bytes plan = 3;
531
532    // A URI and other metadata of the plan to be used for execution.
533    UriResource plan_resource = 9;
534  }
535
536  // Per-aggregand dynamic configuration information for side channel protocols.
537  // The keys in this map are the names of side channels, aligning with
538  // CheckpointOp.side_channel_tensors in plan.proto.
539  map<string, SideChannelExecutionInfo> side_channels = 4;
540
541  // Per-protocol dynamic configuration information for side channel protocols.
542  // This configuration applies to all aggregands configured to use each
543  // protocol.
544  SideChannelProtocolExecutionInfo side_channel_protocol_execution_info = 5;
545
546  reserved 6, 7;
547
548  // Info for how to generate URIs for fetching slices at runtime.
549  FederatedSelectUriInfo federated_select_uri_info = 11;
550
551  reserved 12, 13;
552}
553
554// Info for how to generate URIs for fetching slices that the task might request
555// to be downloaded at runtime.
556//
557// When one or more slices are requested by the task, the template specified
558// here should be used to form a URI from which the client can download the
559// slice data, by replacing the "{served_at_id}" and "{key_base10}" substrings
560// with the `google.internal.federated.plan.SlicesSelector.served_at_id` and the
561// base-10 representation of the `SlicesSelector.keys` value. The client must
562// not perform any URI escaping to the values that the substrings are replaced
563// with.
564message FederatedSelectUriInfo {
565  // The URI template to use for fetching slices.
566  //
567  // This template must always start with "https://".
568  //
569  // This template must contain the following substrings: "{served_at_id}" and
570  // "{key_base10}", as per the above documentation.
571  string uri_template = 1;
572}
573
574// This is sent when client (device) is rejected for the participation.
575message RejectionInfo {
576  // Optional. A suggestion to the client when to retry next connection to the
577  // service
578  // Deprecated in favor of `CheckinRequestAck`. If a client supports
579  // `CheckinRequestAck` then this value is ignored.
580  RetryWindow retry_window = 4 [deprecated = true];
581
582  reserved 1, 2, 3;
583}
584
585// This is sent by the client after the client finishes local (on-device)
586// training.
587//
588// If secure aggregation side channel is used, this must accompany the
589// secure aggregation commit message in the same ClientStreamMessage.
590message ReportRequest {
591  // The name of the population this client belongs to.
592  string population_name = 1;
593
594  // The id of the execution phase this client participates in.
595  string execution_phase_id = 2;
596
597  // The report.
598  Report report = 3;
599}
600
601// This is sent by the server as the final message in the reporting protocol.
602message ReportResponse {
603  // Optional. A suggestion to the client when to retry next connection to the
604  // service
605  // Deprecated in favor of `CheckinRequestAck`. If a client supports
606  // `CheckinRequestAck` then this value is ignored.
607  RetryWindow retry_window = 1 [deprecated = true];
608}
609
610// A report with results of local (on-device) training.
611message Report {
612  // A blob representing the updated checkpoint, if any.  The content
613  // is dependent of the execution method.
614  bytes update_checkpoint = 1;
615
616  // Status code reported by client.
617  // Code.OK indicates that client execution completed successfully and produced
618  // report. Any other code indicates unsuccessful execution and train events
619  // below might contain detailed diagnostic information.
620  int32 status_code = 5;
621
622  reserved 3;
623
624  // A serialized ClientExecutionStats field about stats produced during a
625  // client side execution of the plan.
626  repeated google.protobuf.Any serialized_train_event = 4;
627
628  reserved 2;
629
630  reserved 6;
631}
632
633// This message is used to report duration to the server.
634message ClientExecutionStats {
635  // The time spent on running the plan (includes I/O such as reading examples,
636  // but does not include time spent on the network for retrieving the plan
637  // or uploading results).
638  google.protobuf.Duration duration = 2;
639
640  reserved 1;
641}
642
643// A suggestion to the client when to retry the connection to the service next
644// time
645message RetryWindow {
646  // Optional. If set, the server offers the client to call back in
647  // an interval [delay_min .. delay_max].
648  // The client must pass this token back to the server to identify he is
649  // retrying. If this is not set, the client can retry for another phase at a
650  // time of his choosing.
651  string retry_token = 1;
652
653  // Required (if retry_token is set).
654  // The suggested minimal duration after which the client should
655  // retry. If the client retries earlier, it is likely he will be rejected
656  // again.
657  google.protobuf.Duration delay_min = 2;
658
659  // Required. The suggested maximal duration after which the client should
660  // retry, provided scheduling conditions allow. The client is supposed to make
661  // a best effort to callback in the min..max window, and should avoid
662  // calling before min. If he calls after max, the likelihood to be rejected
663  // again is higher.
664  google.protobuf.Duration delay_max = 3;
665}
666
667// Intermediate Representation for checkpoints after side channels and
668// quantization have been applied.  This is the input and post-aggregation
669// output of the transport-and-aggregate protocols.
670message Checkpoint {
671  // An aggregand is a (flattened) collection of checkpoint variables
672  // that will be aggregated using the same transport-and-aggregate protocol.
673  message Aggregand {
674    repeated uint64 values = 1 [packed = true];
675    int32 bitwidth = 2;
676  }
677
678  // Checkpoint variables are partitioned into multiple aggregands,
679  // each of which can use a different transport-and-aggregate protocol.
680  //
681  map<string, Aggregand> aggregands = 1;
682}
683
684// Protocol options sent from client to server inside
685// `EligibilityEvalCheckinRequest` and `CheckinRequest`.
686message ProtocolOptionsRequest {
687  // True if client supports chunked blob transfer protocol.
688  bool supports_chunked_blob_transfer = 1;
689
690  // Chunked blob transfer compression levels supported by this client.
691  repeated CompressionLevel supported_compression_levels = 2;
692
693  // Per-protocol configuration option information for side channel protocols.
694  // These options apply to all aggregands configured to use each protocol.
695  SideChannelProtocolOptionsRequest side_channels = 3;
696
697  // When this is set in a {@link CheckinRequest} or {@link
698  // EligibilityEvalCheckinRequest} message, the server should ack using
699  // a {@link CheckinRequestAck} sent back to the client.
700  //
701  // Note that if a client previously issued a
702  // `EligibilityEvalCheckinRequest` (for which this field is always set
703  // to true), then this field will not be set to true for the subsequent
704  // `CheckinRequest`.
705  bool should_ack_checkin = 4;
706
707  // True if client supports download of resources via HTTP.
708  bool supports_http_download = 5;
709
710  // True if client supports download of Eligibility Eval resources via HTTP.
711  bool supports_eligibility_eval_http_download = 6;
712
713  // HTTP download compression formats supported by this client. All clients
714  // that support HTTP downloads are assumed to support uncompressed payloads.
715  repeated HttpCompressionFormat supported_http_compression_formats = 7;
716}
717
718// Protocol options sent from server to client inside
719// `EligibilityEvalCheckinResponse` and `CheckinResponse`.
720message ProtocolOptionsResponse {
721  // Tells client what chunk size to use for uploading data, default 8192.
722  int32 chunk_size_for_upload = 1;
723
724  // Tells client how many chunks to send ahead of receiving ack, default: 2
725  int32 max_pending_chunks = 2;
726
727  // Indicates desired compression level
728  CompressionLevel compression_level = 4;
729
730  // Negotiated side channel protocol options; side channel options may not
731  // be set for channels which will not be used in the ReportRequest.
732  SideChannelProtocolOptionsResponse side_channels = 5;
733}
734
735// Allows to transmit large ClientStreamMessage or ServerStreamMessage
736// (depending on a direction of a transfer) as a stream of multiple small chunks
737// with optional compression flow control.
738message ChunkedTransferMessage {
739  // Supported types of compression scheme. Deprecated, replaced by
740  // CompressionLevel. Do not add new values.
741  enum CompressionType {
742    // Compression disabled
743    UNCOMPRESSED = 0;
744  }
745
746  // Initiation of the chunked transfer. Transmitting party starts sending
747  // chunks (Data messages) right after sending Start.
748  message Start {
749    // Uncompressed size of the blob, in bytes.
750    int32 uncompressed_size = 2;
751
752    // Level of compression.
753    CompressionLevel compression_level = 3;
754
755    // Size of the blob transferred over the wire, in bytes.
756    // This field may not be set by older clients, so readers should check the
757    // uncompressed_size field if this value is zero.
758    int32 blob_size_bytes = 4;
759
760    reserved 1;
761  }
762
763  // Carries a chunk of data. Receiving party assembles all the chunks to get
764  // a serialized form of a large ClientStreamMessage or ServerStreamMessage
765  // depending on a direction of a transfer.
766  message Data {
767    // 0-based index of the chunk
768    // All chunk messages must be ordered, the index is included for diagnostics
769    // purposes.
770    int32 chunk_index = 1;
771
772    // Next chunk of the blob.
773    bytes chunk_bytes = 2;
774  }
775
776  // Acknowledgement of receiving of Data message.
777  // Must be sent in a response of a successful receiving of a chunk. It is used
778  // for the purposes of the flow control: transmitting party limits number of
779  // of chunks speculatively sent
780  message Ack {
781    // 0-based index of received chunk
782    // All ack messages must be ordered, the index is included for diagnostic
783    // purposes.
784    int32 chunk_index = 1;
785  }
786
787  // Completion of the chunked transfer.
788  message End {
789    // Total number of chunks transferred.
790    int32 chunk_count = 1;
791
792    // TODO(team): Add checksum.
793  }
794
795  // Kind of chunked message.
796  oneof kind {
797    // Start message, sent by transmitter
798    Start start = 1;
799
800    // Data message (a single chunk), sent by transmitter.
801    Data data = 2;
802
803    // Ack of receiving of Data message, sent by receiver.
804    Ack ack = 3;
805
806    // End of the transmission, sent by transmitter.
807    End end = 4;
808  }
809}
810