{% set rfcid = “RFC-0032” %} {% include “docs/contribute/governance/rfcs/_common/_rfc_header.md” %}
Note: A version of this RFC was resubmitted and accepted as RFC-0113
Note: Formerly known as FTP-032.
“Turning Envelopes into Postcards”
On February 21, 2019, this RFC was initially accepted. The FIDL team worked to stabilize the wire format for most of 2019, culminating in an all-hands-on-deck effort which spanned Q3 and Q4. The migration completed on Dec 1st, 2019.
The stabilization effort spanned multiple changes:
However, as the work unfolded, and the Dec 1st deadline loomed, the FIDL team decided to punt on implementing the efficient envelopes change, preferring to push this work to 2020. Unlike the other changes which were part of the stabilization effort, efficient envelopes was simply an in-memory size saving, which was very small, especially when compared to other aspects of the FIDL wire format (e.g. tables' dense format). Deferring was a project risk reduction calculation, by reducing the scope, the odds of completing all the work on time were improved. So was the FIDL team's work schedule.
We're now close to 18 months after the deferral, and efficient envelopes are long forgotten. Significant performance work in 2020 demonstrated that this change would have no material impact.
It‘s time to face the truth, this ain’t going to happen. Rejected.
In June 2021, this topic was revisited and performance was measured with targeted benchmarks. This was conclusive and RFC-0113 proposed reintroducing the change, which was accepted.
This FTP proposes a more compact encoding for envelopes[^1].
Envelopes are the foundation for extensible, evolvable data structures (tables and extensible unions). A more compact and efficient wire format for envelopes enables those extensible structures to be used in more contexts where performance and wire size matter.
The proposed envelope format is:
Compared with the existing envelope format:
vector<string>
includes the size of the outer vector's inner string sub-objects.FIDL_ALLOC_ABSENT
.UINT32_MAX
and handle count of 0
is special: it represents envelope content that is present, but has zero size.FIDL_ALLOC_ABSENT
, that's OK. Happy to go with consensus.Decoders MAY overwrite the envelope with a pointer to the envelope data, assuming they know the static type (schema) of the envelope‘s contents. See the Unknown Data section for recommendations on how to process an envelope if the content’s type is unknown.
The encoded form of an envelope can be represented by a union of the encoded or decoded form.
typedef union { struct { uint32_t size; uint16_t handle_count; uint16_t reserved; } encoded; void* data; } fidl_envelope_t; static_assert(sizeof(fidl_envelope_t) == sizeof(void*));
Receivers — validators & decoders — may not know the type of an envelope when they‘re used in an evolvable data structure. If a receiver doesn’t know the type, an envelope can be minimally parsed and skipped.
This FTP is a breaking wire format change.
Both FIDL peers need to understand the new envelope format — and communicate that understanding to its peer — for both parties to use the new format. As such, this would typically be considered as a hard transition. Since this FTP adds no new functionality, if we decide to land this as a hard transition, the authors recommended that this change is grouped with other wire format changes (e.g. a proposed ordinal size change).
That said, a soft transition is possible. Two approaches are:
uint32
reserved/flags field in the transactional message header. We can reserve 1 bit for the initiating peer to indicate that it understands the new wire format, and soft transition in stages:[WireFormat=EnvelopeV2]
” attribute (or similar) that indicates that the message/interface should use the new wire format.[WireFormat]
attribute affect the wire format of the interface‘s method arguments only, without recursively affecting the argument’s structs.[WireFormat]
attribute, we can drop the old wire format, assume all structs & interfaces use the new wire format, and ignore the attribute.Both these soft transition approaches involve a lot of development time, testing time, and room for error. Implementing the code to do either approach correctly, executing on the plan, and following up successfully to remove old code is a large effort.
It is likely that we will have code to handle both the old & new wire format at the same time; otherwise, it would not be possible to progressively land CLs as we implement support for the new wire format. Given that the code to handle both wire formats will exist, we recommend prototyping whether a soft transition is feasible using one of the above soft transition approaches. Such prototyping work may also lead to general strategies for landing future breaking wire format changes, which may be valuable. If not, c'est la vie; hard transition it is.
For either a soft or hard transition, any instances in Fuchsia where FIDL messages are hand-rolled would need to also be upgraded to the new wire format.
The proposed wire format change should be API (source) compatible. Any hand-rolled FIDL code would need to be updated to handle the new wire format.
The wire format change is ABI-incompatible. It may be possible to achieve ABI compatibility via the strategies outlined in the Implementation Strategy section.
This FTP significantly shrinks the size required for envelopes, which seems like it would be an overall significant net benefit. However, if extensible data structures become more pervasive due to their better efficiency, this may be outweighed by their increased usage, which may result in less compact messages overall and more dynamic allocation, vs. using non-extensible data structures.
There should no significant security implications from this FTP.
One minor security advantage is that this FTP removes information that is otherwise duplicated in the size and pointer in the old format. Previously, an envelope may be received with non-zero size/handles and FIDL_ALLOC_ABSENT
, or zero size/handles and FIDL_ALLOC_PRESENT
. This required extra validation checks, which will no longer be needed.
We can keep the existing wire format if we believe the efficiency gains in this proposal are not worth the implementation cost.
While this FTP makes recommendations, we are actively seeking input and consensus on the following decisions:
This FTP is a slimmed-down version of rfc-0026, which was rejected since there wasn't enough consensus around the whole FTP.
[^1]: This FTP is based on rfc-0026, but with only the out-of-line envelope proposal. Inlining, envelopes everywhere, and moving the string/vector count out-of-line, have all been removed.
[^2]: Note that today, empty (zero-field) structs occupy one byte on-the-wire.