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:
@@ -4,8 +4,13 @@
|
||||
-- (the layer on top of RLP).
|
||||
--
|
||||
-- Purpose:
|
||||
-- * Provide a formal, toolable description of the data.
|
||||
-- * Enable migration from the legacy RLP-based format to DER.
|
||||
-- * Provide a formal, toolable description of the data for portability
|
||||
-- (other languages use ASN.1 compilers to get types/parsers).
|
||||
-- * Define compact canonical wire format using standard ASN.1 techniques
|
||||
-- (primarily Unaligned PER / UPER with constraints for packing).
|
||||
-- * Static encoding only (templates from gmserialization).
|
||||
-- * Legacy RLP compatibility is achieved via separate translation layer
|
||||
-- (deferred in current focus).
|
||||
--
|
||||
-- Detection of legacy vs new:
|
||||
-- Legacy data (produced by gmserialization:serialize / gmser_chain_objects:serialize
|
||||
@@ -17,15 +22,21 @@
|
||||
-- top-level SEQUENCE we define). 0x30 < 0xC0, so a single-byte prefix
|
||||
-- check reliably distinguishes the two formats.
|
||||
--
|
||||
-- Usage in Erlang (after compiling with asn1ct):
|
||||
-- {ok, Mod} = asn1ct:compile(GajumaruSerialization.asn, [ber, der]).
|
||||
-- {ok, Term} = 'GajumaruSerialization':decode('GajumaruData', DerBinary).
|
||||
-- Usage in Erlang (after compiling with asn1ct for compact wire):
|
||||
-- {ok, Mod} = asn1ct:compile(GajumaruSerialization.asn, [uper]).
|
||||
-- {ok, Bytes} = 'GajumaruSerialization':encode('GajumaruData', Asn1Value).
|
||||
-- Bytes is the compact UPER wire format (deterministic with this schema).
|
||||
-- For legacy RLP, use the model-to-RLP layer instead (see gmser_asn1_rlp).
|
||||
--
|
||||
-- Notes on type mapping from gmserialization.erl:
|
||||
-- - int -> INTEGER (new data uses canonical DER INTEGER)
|
||||
-- Notes on type mapping from gmserialization.erl (static templates):
|
||||
-- - int (bignum) -> BigInt ::= INTEGER (0..MAX)
|
||||
-- In practice used for amounts/balances in Pucks (up to 1*10^30).
|
||||
-- Encoded as non-negative bignum.
|
||||
-- - New smaller integer types will be added to templates (uint64, uint32, ...)
|
||||
-- for cases where range is known → enables tighter UPER packing.
|
||||
-- - binary -> OCTET STRING
|
||||
-- - bool -> BOOLEAN
|
||||
-- - id -> Id (SEQUENCE) (cleaner than the legacy packed 33-byte form)
|
||||
-- - id -> Id (SEQUENCE)
|
||||
-- - [T] -> SEQUENCE OF T
|
||||
-- - {T1,...} -> SEQUENCE (fixed-size, order matters)
|
||||
-- - #{items := [{K,T},...]} -> SEQUENCE with the fields in template order
|
||||
@@ -33,9 +44,6 @@
|
||||
-- - tag + vsn are preserved as the first two fields for compatibility
|
||||
-- with existing dispatch logic.
|
||||
--
|
||||
-- Legacy integers had strict unsigned-minimal no-leading-zero (except for 0)
|
||||
-- and RLP-level rules. New DER data does not need to follow those rules.
|
||||
--
|
||||
-- WARNING:
|
||||
-- Any cryptographic hash or signature computed over a serialized object
|
||||
-- will change when switching from RLP to DER for that object. Plan a
|
||||
@@ -53,11 +61,20 @@ EXPORTS ALL;
|
||||
-- ============================================================
|
||||
|
||||
GajumaruData ::= SEQUENCE {
|
||||
tag INTEGER,
|
||||
vsn INTEGER,
|
||||
-- Constrained for better PER packing
|
||||
tag INTEGER (0..65535),
|
||||
vsn INTEGER (0..255),
|
||||
content Content
|
||||
}
|
||||
|
||||
-- Preferred top-level for the compact static wire format.
|
||||
-- Avoids the extra Content CHOICE tag when the structure is known to be static.
|
||||
CompactStatic ::= SEQUENCE {
|
||||
tag INTEGER (0..65535),
|
||||
vsn INTEGER (0..255),
|
||||
fields StaticFields
|
||||
}
|
||||
|
||||
-- Content can be a specific structured type (preferred) or a generic
|
||||
-- representation of a template-driven object.
|
||||
Content ::= CHOICE {
|
||||
@@ -65,6 +82,10 @@ Content ::= CHOICE {
|
||||
-- without having a pre-defined SEQUENCE for every object.
|
||||
templateFields [0] TemplateFields,
|
||||
|
||||
-- Static-optimized: no field names on wire (matches legacy static behavior exactly)
|
||||
-- Preferred for compact wire format of known templates.
|
||||
staticFields [10] StaticFields,
|
||||
|
||||
-- Examples of concrete versioned types (extend as needed)
|
||||
account [1] Account,
|
||||
signedTx [2] SignedTx,
|
||||
@@ -87,17 +108,41 @@ TemplateField ::= SEQUENCE {
|
||||
value Value
|
||||
}
|
||||
|
||||
-- Optimized for static wire format: just the values in order, no names.
|
||||
-- This matches the legacy static encoding where maps/records are positional only.
|
||||
StaticFields ::= SEQUENCE OF Value
|
||||
|
||||
|
||||
Value ::= CHOICE {
|
||||
intValue [0] INTEGER,
|
||||
-- "int" in static templates is used for bignums in practice
|
||||
-- (e.g. balances and amounts in Pucks, up to 1*10^30).
|
||||
-- We keep it as unbounded non-negative integer.
|
||||
bigIntValue [0] BigInt,
|
||||
|
||||
boolValue [1] BOOLEAN,
|
||||
binaryValue [2] OCTET STRING,
|
||||
idValue [3] Id,
|
||||
listValue [4] SEQUENCE OF Value,
|
||||
tupleValue [5] SEQUENCE OF Value,
|
||||
mapValue [6] SEQUENCE OF KeyValue -- only needed if you want to
|
||||
-- represent dynamic-style maps
|
||||
mapValue [6] SEQUENCE OF KeyValue, -- only needed if you want to
|
||||
-- represent dynamic-style maps
|
||||
|
||||
-- Additional integer types for smaller ranges (future use in templates
|
||||
-- for better UPER packing when the range is known).
|
||||
uint64Value [7] Uint64,
|
||||
uint32Value [8] Uint32,
|
||||
uint128Value [9] Uint128
|
||||
}
|
||||
|
||||
-- Bignum integer (non-negative). Used for the traditional "int" in static
|
||||
-- templates. Max practical value mentioned: 1*10^30 (≈ 2^100 bits).
|
||||
BigInt ::= INTEGER (0..MAX)
|
||||
|
||||
-- Convenience sized unsigned integer types.
|
||||
Uint64 ::= INTEGER (0..18446744073709551615)
|
||||
Uint32 ::= INTEGER (0..4294967295)
|
||||
Uint128 ::= INTEGER (0..340282366920938463463374607431768211455)
|
||||
|
||||
KeyValue ::= SEQUENCE {
|
||||
key Value,
|
||||
val Value
|
||||
@@ -203,23 +248,20 @@ TypeInfoV3 ::= SEQUENCE {
|
||||
-- always falling back to TemplateFields. This gives you better
|
||||
-- validation and generated types.
|
||||
--
|
||||
-- 3. INTEGER in DER is signed and uses a different minimal encoding
|
||||
-- than the legacy unsigned big-endian no leading zero form. This is
|
||||
-- fine for new data.
|
||||
-- 3. For the compact wire format we use UPER (unaligned PER).
|
||||
-- It is stable/deterministic for a given schema (no extensibility
|
||||
-- markers on these types, fixed order).
|
||||
--
|
||||
-- 4. If you need to preserve exact legacy integer wire bytes inside
|
||||
-- the new format (e.g. for some hash preimage reason), you can
|
||||
-- carry selected integers as OCTET STRING (legacy unsigned minimal bytes).
|
||||
-- 4. INTEGER uses ASN.1 PER encoding (canonical for the constraints).
|
||||
-- This may differ from legacy RLP minimal unsigned; new format
|
||||
-- will have different hashes (expected when introducing new encoding).
|
||||
--
|
||||
-- 5. Dynamic encoding (gmser_dyn) is intentionally not modeled here
|
||||
-- in full, because it is runtime-schema driven (type codes 246-255,
|
||||
-- labels, alt/switch, etc.). You can still use the generic
|
||||
-- TemplateFields + Value for some dynamic cases, or model specific
|
||||
-- message schemas as additional CHOICE arms.
|
||||
-- 5. Dynamic encoding (gmser_dyn) is not in scope here.
|
||||
--
|
||||
-- 6. Compile with DER for canonical output:
|
||||
-- asn1ct:compile(GajumaruSerialization, [der]).
|
||||
-- 6. To generate the compact wire:
|
||||
-- asn1ct:compile(GajumaruSerialization, [uper]).
|
||||
-- {ok, CompactBytes} = 'GajumaruSerialization':encode('GajumaruData', Value).
|
||||
--
|
||||
-- The ber option is also accepted; der implies the stricter rules.
|
||||
-- Use staticFields (not templateFields) for best compactness on static data.
|
||||
|
||||
END
|
||||
|
||||
Reference in New Issue
Block a user