Ulf Wiger ba771836fb
All checks were successful
Gajumaru Serialization Tests / tests (push) Successful in 49m9s
Document static, make anyint standard
2025-04-11 16:39:06 +02:00

84 lines
2.7 KiB
Markdown

# Static Serialization
The `gmserialization` and `gmser_chain_objects` modules implement the
static serialization support used in the Gajumaru blockchain.
The purpose is to produce fully deterministic serialization, in order
to maintain predictable hashing.
Example:
```erlang
%% deterministic canonical serialization.
-spec serialize_to_binary(signed_tx()) -> binary_signed_tx().
serialize_to_binary(#signed_tx{tx = Tx, signatures = Sigs}) ->
gmser_chain_objects:serialize(
?SIG_TX_TYPE,
?SIG_TX_VSN,
serialization_template(?SIG_TX_VSN),
[ {signatures, lists:sort(Sigs)}
, {transaction, aetx:serialize_to_binary(Tx)}
]).
-spec deserialize_from_binary(binary()) -> signed_tx().
deserialize_from_binary(SignedTxBin) when is_binary(SignedTxBin) ->
[ {signatures, Sigs}
, {transaction, TxBin}
] = gmser_chain_objects:deserialize(
?SIG_TX_TYPE,
?SIG_TX_VSN,
serialization_template(?SIG_TX_VSN),
SignedTxBin),
assert_sigs_size(Sigs),
#signed_tx{ tx = aetx:deserialize_from_binary(TxBin)
, signatures = Sigs
}.
serialization_template(?SIG_TX_VSN) ->
[ {signatures, [binary]}
, {transaction, binary}
].
```
The terms that can be encoded using these templates are given by
this type in `gmserialization.erl`:
```erlang
-type encodable_term() :: non_neg_integer()
| binary()
| boolean()
| [encodable_term()] %% Of any length
| #{atom() => encodable_term()}
| tuple() %% Any arity, containing encodable_term().
| gmser_id:id().
```
The template 'language' is defined by these types:
```erlang
-type template() :: [{field_name(), type()}].
-type field_name() :: atom().
-type type() :: 'int'
| 'bool'
| 'binary'
| 'id' %% As defined in aec_id.erl
| [type()] %% Length one in the type. This means a list of any length.
| #{items := [{field_name(), type()}]} %% Record with named fields
%% represented as a map.
%% Encoded as a list in the given
%% order.
| tuple(). %% Any arity, containing type(). This means a static size array.
```
The `gmser_chain_objects.erl` module specifies a serialization code for each
object that can go on-chain. E.g.:
```erlang
tag(signed_tx) -> 11;
...
rev_tag(11) -> signed_tx;
```
The `tag` and `vsn` are laid out in the beginning of the serialized object.