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