Updated asn1 experiment, now exploring PER and OER
Gajumaru Serialization Tests / tests (push) Successful in 12s
Gajumaru Serialization Tests / tests (push) Successful in 12s
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# ASN.1 for Static Serialization - Compact Wire Format
|
||||
|
||||
## Goal
|
||||
Use portable ASN.1 techniques to produce the most compact *deterministic* (stable/idempotent for hashing) wire format for gmserialization **static** encoding, based on existing templates.
|
||||
|
||||
Focus is on the wire format itself (not RLP translation for legacy, which is deferred).
|
||||
|
||||
## Approach
|
||||
- The `asn1/GajumaruSerialization.asn` is the single source of truth (abstract syntax).
|
||||
- Use **Unaligned PER (UPER)** as the standard compact canonical encoding rule provided by the ASN.1 framework.
|
||||
- Portable across languages/tools that support ASN.1 UPER.
|
||||
- Deterministic for a fixed schema (no extensibility, consistent packing).
|
||||
- Optimize the schema for packing:
|
||||
- Constrain INTEGER ranges.
|
||||
- Provide `staticFields` (SEQUENCE OF Value) -- no field names (names are never on the wire for static case).
|
||||
- Provide `CompactStatic` top-level type to avoid unnecessary CHOICE overhead for the common static path.
|
||||
- Concrete SEQUENCEs for well-known objects (SignedTx, ContractV* etc.) when possible.
|
||||
- Encode with the generated ASN.1 module: ` 'GajumaruSerialization':encode('CompactStatic', Value) `.
|
||||
|
||||
## Results (example sizes)
|
||||
|
||||
Using current optimized UPER:
|
||||
|
||||
- Tiny object (tag/vsn + int + 1-byte bin): 9 bytes (legacy RLP = 5)
|
||||
- List of 3 ints: 13 bytes (legacy = 7)
|
||||
- Signed tx example: 11 bytes (legacy = 7)
|
||||
- 256-byte payload: ~263 bytes (legacy ~264) -- matches or slightly better
|
||||
|
||||
PER/UPER overhead is mainly the structural tags for the generic case. Concrete types and `staticFields` + `CompactStatic` minimize it.
|
||||
|
||||
Compared to DER (previous orientation): dramatically better (e.g. tiny case was ~36B in DER).
|
||||
|
||||
## Usage in Erlang (for the compact format)
|
||||
|
||||
```erlang
|
||||
% Build value according to schema (using staticFields for best compactness)
|
||||
Value = {'CompactStatic', Tag, Vsn, [
|
||||
{'intValue', 42},
|
||||
{'binaryValue', <<"data">>}
|
||||
% ...
|
||||
]},
|
||||
|
||||
{ok, CompactBytes} = 'GajumaruSerialization':encode('CompactStatic', Value).
|
||||
```
|
||||
|
||||
Compile the schema with:
|
||||
```
|
||||
asn1ct:compile("GajumaruSerialization.asn", [uper]).
|
||||
```
|
||||
|
||||
## Schema Notes
|
||||
- `staticFields` should be used for generic static templates (mirrors legacy positional encoding).
|
||||
- Concrete types (e.g. `signedTx`) are preferred when the structure is fixed.
|
||||
- `TemplateFields` (with names) is kept for debug/transition but not optimal for wire size.
|
||||
- The model directly reflects the static `template()` types from `gmserialization.erl`.
|
||||
|
||||
## Portability
|
||||
Any language with an ASN.1 UPER codec can produce and consume the exact same bytes by using the schema and the same value construction rules.
|
||||
|
||||
## Stability
|
||||
- UPER encoding of this schema is stable (tested roundtrip + re-encode identical).
|
||||
- No random/padding choices.
|
||||
- Same input value always produces identical bytes.
|
||||
|
||||
## Limitations / Future
|
||||
- For very small objects, hand-crafted RLP is still smaller because it has almost no structural overhead.
|
||||
- If an even more compact custom encoding is desired while keeping the model, a custom "encoding rule" can be implemented driven by the schema (similar to how the RLP layer works, but targeting a new bit-packed format).
|
||||
- Dynamic encoder (gmser_dyn) is out of scope.
|
||||
|
||||
See also: `asn1/GajumaruSerialization.asn`, `asn1_compact/`, tests in `src/gmser_asn1_rlp.erl` (for value shapes), `doc/static.md`.
|
||||
+2
-1
@@ -59,7 +59,8 @@ The template 'language' is defined by these types:
|
||||
```erlang
|
||||
-type template() :: [{field_name(), type()}].
|
||||
-type field_name() :: atom().
|
||||
-type type() :: 'int'
|
||||
-type type() :: 'int' % bignum (non-negative, for amounts etc. up to 10^30 Pucks)
|
||||
| 'uint128' | 'uint64' | 'uint32' | 'uint16' | 'uint8'
|
||||
| 'bool'
|
||||
| 'binary'
|
||||
| 'id' %% As defined in aec_id.erl
|
||||
|
||||
Reference in New Issue
Block a user