FlatBuffers
The Variant type and a handful of other wire-format types are serialized via FlatBuffers. FlatBuffers is a cross-language binary format — schemas are written once in .fbs files and code-generated for C++, C#, Go, Java, JavaScript, Python, and more.
Why FlatBuffers?
| Concern | JSON | Protobuf | FlatBuffers |
|---|---|---|---|
| Cross-language | yes | yes | yes |
| Zero-copy read | no | no | yes (no parsing needed for read) |
| Schema required | no | yes | yes |
| Generated code required | no | yes | yes |
| Human-readable | yes | no | no |
| Schema evolution | ad-hoc | good | good (field IDs) |
For the trading platform, the deciding factors are: zero-copy reads (for high-throughput market data ingestion) and a single schema across C# (server) + Python + TypeScript (clients).
Schemas
The schemas live in src/Virtufin.Data/Schemas/:
| Schema | Purpose |
|---|---|
variant.fbs |
The Variant discriminated union — the wire format for all cross-process values |
cloud_event.fbs |
CloudEvent envelope used by Virtufin.Worker.DevKit |
worker_response.fbs |
Response envelope for native worker libraries |
The C# code is generated by flatc (the FlatBuffers compiler) as part of the build — see Development for the exact invocation.
The variant.fbs schema (overview)
table Variant { type: VariantType; value: VariantValue; }
table VariantValue { /* one of the cases below */ }
table NoneValue { }
table BoolValue { value: bool; }
table Int32Value { value: int; }
table StringValue { value: string; }
table DictionaryValue { entries: [KeyValuePair]; }
table ArrayValue { elements: [Variant]; }
enum VariantType : byte {
None = 0,
Bool = 1,
Int32 = 2,
String = 3,
Dictionary = 4,
Array = 5,
}
The generated C# code is in src/Virtufin.Data/Generated/ (gitignored, regenerated on build).
Usage
// Serialize
Variant v = Variant.Dictionary(new Dictionary<string, Variant>
{
["price"] = 100.5m,
["symbol"] = "BTCUSDT",
});
byte[] bytes = v.Serialize();
// Deserialize (in C#)
Variant restored = Variant.Deserialize(bytes);
// Deserialize in Python (sketch)
# pip install flatbuffers
# (Python bindings generated from variant.fbs)
# variant = Variant.tlbb_root_as_variant(bytes)
Cross-language contract
A Variant produced in C# is byte-identical to the same value produced in Python or TypeScript (assuming the same .fbs schema). The platform relies on this for:
- C#
WorkManagerproducing events → Python strategy consuming them - TypeScript UI sending
Variantconfig → C# service storing it - C#
API Gatewaydeserializing aVariantfrom a gRPC request that was serialized in TypeScript
If the schemas diverge across languages, the platform's value-flow contract breaks. Schema changes go through the virtufin-openspec change-management process.
Evolution
FlatBuffers uses field IDs (sequential numbers, starting at 0). Adding a new field is backward-compatible: old readers ignore the new field. Removing a field is breaking (don't do it). Renaming a field is safe (the ID stays the same; the name is just for code generation).
The variant.fbs schema is the contract. Any change to it must be:
1. Proposed in virtufin-openspec/openspec/changes/
2. Applied to all languages (C# / Python / TypeScript) in the same change
3. Tested for cross-language round-trip
See also
- Variant Type — the type the schema describes
- API Reference —
Variant.SerializeandVariant.Deserialize - Development — how to regenerate the schema code