Compare commits

..

1 Commits

Author SHA1 Message Date
Ulf Wiger
a585842481 Map 'hash' as known api type, add some more tests
All checks were successful
Gajumaru Serialization Tests / tests (push) Successful in -2m53s
2026-03-24 13:24:49 +01:00
15 changed files with 18 additions and 172 deletions

View File

@ -1,6 +1,6 @@
{application,gmserialization,
[{description,"Serialization of data for the Gajumaru"},
{vsn,"0.2.0"},
{vsn,"0.1.2"},
{registered,[]},
{applications,[kernel,stdlib,crypto,base58]},
{env,[]},

View File

@ -6,20 +6,15 @@
%%% @end
%%%-------------------------------------------------------------------
-module(gmser_api_encoder).
-vsn("0.2.0").
-vsn("0.1.2").
-export([encode/2,
decode/1,
safe_decode/2,
byte_size_for_type/1]).
-export([encode_keypair/1,
safe_decode_keypair/1]).
-export([unsafe_encode/2]). %% Encode without size checks
-export_type([encoded/0,
known_type/0]).
known_type/0]).
-type known_type() :: key_block_hash
| micro_block_hash
@ -58,66 +53,14 @@
-type payload() :: binary().
-type encoded() :: binary().
-type keypair() :: #{public := <<_:(32*8)>>, secret := <<_:(64*8)>>}.
-type encoded_keypair() :: #{binary() => binary()}.
-export_type([ keypair/0
, encoded_keypair/0 ]).
-define(BASE58, 1).
-define(BASE64, 2).
-spec encode_keypair(keypair()) -> encoded_keypair().
encode_keypair(#{public := Pub, secret := Sec}) ->
case Sec of
<<Seed:32/binary, Pub1:32/binary>> when Pub1 =:= Pub ->
#{ <<"pub">> => encode(account_pubkey, Pub)
, <<"priv">> => encode(account_seckey, Seed) };
_ ->
erlang:error(invalid_keypair)
end.
-spec safe_decode_keypair(encoded_keypair()) -> {'ok', keypair()} | {'error', atom()}.
safe_decode_keypair(#{<<"pub">> := EncPub, <<"priv">> := EncPriv}) ->
case safe_decode(account_pubkey, EncPub) of
{ok, Pub} ->
case safe_decode(account_seckey, EncPriv) of
{ok, Seed} when byte_size(Seed) =:= 32 ->
case enacl:sign_seed_keypair(Seed) of
#{public := Pub, secret := _} = KP ->
{ok, KP};
_ ->
{error, illegal_encoding}
end;
{ok, <<Seed:32/binary, Pub:32/binary>>} ->
case enacl:sign_seed_keypair(Seed) of
#{public := Pub} = KP ->
{ok, KP};
_ ->
{error, illegal_encoding}
end;
{ok, _} ->
{error, illegal_encoding};
{error, _} = Error1 ->
Error1
end;
Error ->
Error
end.
-spec encode(known_type(), payload() | gmser_id:id()) -> encoded().
encode(id_hash, Payload) ->
{IdType, Val} = gmser_id:specialize(Payload),
encode(id2type(IdType), Val);
encode(Type, Payload) ->
case type_size_check(Type, Payload) of
ok ->
unsafe_encode(Type, Payload);
{error, Reason} ->
erlang:error(Reason)
end.
unsafe_encode(Type, Payload) ->
Pfx = type2pfx(Type),
Enc = case type2enc(Type) of
?BASE58 -> base58_check(Payload);
@ -125,7 +68,6 @@ unsafe_encode(Type, Payload) ->
end,
<<Pfx/binary, "_", Enc/binary>>.
-spec decode(binary()) -> {known_type(), payload()}.
decode(Bin0) ->
case split(Bin0) of
@ -141,13 +83,6 @@ decode(Bin0) ->
erlang:error(missing_prefix)
end.
type_size_check(account_seckey, Bin) ->
case byte_size(Bin) of
Sz when Sz =:= 32; Sz =:= 64 ->
ok;
_ ->
{error, incorrect_size}
end;
type_size_check(Type, Bin) ->
case byte_size_for_type(Type) of
not_applicable -> ok;

View File

@ -8,7 +8,7 @@
%%%-------------------------------------------------------------------
-module(gmser_chain_objects).
-vsn("0.2.0").
-vsn("0.1.2").
-export([ serialize/4
, deserialize/4

View File

@ -6,7 +6,7 @@
%%% @end
%%%-------------------------------------------------------------------
-module(gmser_contract_code).
-vsn("0.2.0").
-vsn("0.1.2").
-include("gmser_contract_code.hrl").

View File

@ -6,7 +6,7 @@
%%% @end
%%%-------------------------------------------------------------------
-module(gmser_delegation).
-vsn("0.2.0").
-vsn("0.1.2").
-export([ aens_preclaim_sig/3
, aens_name_sig/4

View File

@ -1,5 +1,4 @@
-module(gmser_dyn).
-vsn("0.2.0").
-export([ encode/1 %% (Term) -> rlp()
, encode/2 %% (Term, Types) -> rlp()

View File

@ -1,5 +1,4 @@
-module(gmser_dyn_types).
-vsn("0.2.0").
-export([ add_type/3 %% (Tag, Code, Template) -> Types1
, add_type/4 %% (Tag, Code, Template, Types) -> Types1

View File

@ -8,7 +8,7 @@
%%%-------------------------------------------------------------------
-module(gmser_id).
-vsn("0.2.0").
-vsn("0.1.2").
-export([ create/2
, specialize/1

View File

@ -11,7 +11,7 @@
%%%-------------------------------------------------------------------
-module(gmser_rlp).
-vsn("0.2.0").
-vsn("0.1.2").
-export([ decode/1
, decode_one/1

View File

@ -1,6 +1,6 @@
{application, gmserialization,
[{description, "Serialization of data for the Gajumaru"},
{vsn, "zomp"},
{vsn, "0.1.0"},
{registered, []},
{applications,
[kernel,

View File

@ -1,14 +0,0 @@
%% -*- erlang-mode; erlang-indent-level: 4; indent-tabs-mode: nil -*-
[{application, Name, Opts}] = CONFIG.
case lists:keyfind(vsn, 1, Opts) of
{vsn, "zomp"} ->
ZompMetaF = filename:join(filename:dirname(filename:dirname(SCRIPT)), "zomp.meta"),
{ok, ZMeta} = file:consult(ZompMetaF),
{_, {_, _, {Vmaj,Vmin,Vpatch}}} = lists:keyfind(package_id, 1, ZMeta),
VsnStr = unicode:characters_to_list(io_lib:fwrite("~w.~w.~w", [Vmaj, Vmin, Vpatch])),
Opts1 = lists:keyreplace(vsn, 1, Opts, {vsn, VsnStr}),
[{application, Name, Opts1}];
_ ->
CONFIG
end.

View File

@ -7,7 +7,7 @@
%%%-------------------------------------------------------------------
-module(gmserialization).
-vsn("0.2.0").
-vsn("0.1.2").
-export([ decode_fields/2
, decode_field/2

View File

@ -87,16 +87,15 @@ encode_decode_test_(Types) ->
lists:foreach(
fun({_Type, not_applicable}) -> ok;
({Type, ByteSize}) ->
CheckIllegalSize =
CheckIlligalSize =
fun(S) ->
Key = <<42:S/unit:8>>,
?assertError(incorrect_size, ?TEST_MODULE:encode(Type, Key)),
EncodedKey = ?TEST_MODULE:unsafe_encode(Type, Key), %% no size check
EncodedKey = ?TEST_MODULE:encode(Type, Key),
{error, invalid_encoding} = ?TEST_MODULE:safe_decode(Type, EncodedKey)
end,
CheckIllegalSize(0),
CheckIllegalSize(ByteSize - 1),
CheckIllegalSize(ByteSize + 1)
CheckIlligalSize(0),
CheckIlligalSize(ByteSize - 1),
CheckIlligalSize(ByteSize + 1)
end,
Types)
end
@ -164,30 +163,7 @@ encode_decode_test_(Types) ->
end, Types)
end,
Bins)
end},
{"Encode/decode keypairs",
fun() ->
KP1 = enacl:sign_keypair(),
Enc1 = ?TEST_MODULE:encode_keypair(KP1),
{ok, KP1} = ?TEST_MODULE:safe_decode_keypair(Enc1),
KP2 = enacl:sign_keypair(),
Enc2 = ?TEST_MODULE:encode_keypair(KP2),
{ok, KP2} = ?TEST_MODULE:safe_decode_keypair(Enc2),
BadEnc = Enc1#{~"priv" => maps:get(~"priv", Enc2)},
{error, illegal_encoding} = ?TEST_MODULE:safe_decode_keypair(BadEnc)
end
},
{"Encode AND decode both 32-byte and 64-byte account_seckey",
fun() ->
%% Originally, we could encode a 64-byte seckey, but decode would fail.
#{public := Pub, secret := Sec} = enacl:sign_keypair(),
<<Seed:32/binary, Pub:32/binary>> = Sec,
EncSeed = ?TEST_MODULE:encode(account_seckey, Seed),
EncSec = ?TEST_MODULE:encode(account_seckey, Sec),
{ok, Seed} = ?TEST_MODULE:safe_decode(account_seckey, EncSeed),
{ok, Sec} = ?TEST_MODULE:safe_decode(account_seckey, EncSec)
end
}
end}
].
known_types() ->

View File

@ -2,9 +2,9 @@
{type,lib}.
{modules,[]}.
{prefix,none}.
{desc,"Serialization helpers for the Gajumaru."}.
{author,"Hans Svensson"}.
{package_id,{"otpr","gmserialization",{0,2,0}}}.
{desc,"Serialization helpers for the Gajumaru."}.
{package_id,{"otpr","gmserialization",{0,1,2}}}.
{deps,[{"otpr","eblake2",{1,0,1}},{"otpr","base58",{0,1,1}}]}.
{key_name,none}.
{a_email,[]}.

View File

@ -1,49 +0,0 @@
#!/bin/sh
set -e
APP=$(basename "$PWD")
SRC="_build/default/lib/$APP"
DST="$PWD/_build/zomp/lib/$APP"
IGNORE_FILE="zomp.ignore"
mkdir -p "$DST"
# Remove broken symlinks
find "$SRC" -type l ! -exec test -e {} \; -delete || true
# Build ignore matcher
IGNORE_TEMP=$(mktemp)
trap "rm -f $IGNORE_TEMP" EXIT
# Expand globs in zomp.ignore to patterns suitable for grep
if [ -e "$IGNORE_FILE" ]; then
grep -v '^\s*#' "$IGNORE_FILE" | sed 's#/#\\/#g' | sed 's/\./\\./g' | sed 's/\*/.*/g' > "$IGNORE_TEMP"
fi
# Copy Git-tracked and Zomp-allowed files
git ls-files -z | while IFS= read -r -d '' file; do
# Skip if ignored
echo "$file" | grep -Eq -f "$IGNORE_TEMP" && continue
# Only copy if file exists in the build dir
if [ -e "$SRC/$file" ]; then
mkdir -p "$DST/$(dirname "$file")"
cp -a "$SRC/$file" "$DST/$file"
fi
done
rm "$IGNORE_TEMP"
# Copy metadata
cp "$PWD/zomp.meta" "$DST/"
cp "$PWD/Emakefile" "$DST/"
# copy generated schema
SCHEMA="$SRC/priv/gmhc_schema.json"
if [ -e "$SCHEMA" ]; then
mkdir -p "$DST/priv"
cp -a "$SCHEMA" "$DST/priv/$(basename "$SCHEMA")"
fi
# Clean up beam files just in case
[ -d "$DST/ebin" ] && find "$DST/ebin" -name '*.beam' -exec rm -f {} + || true