Compare commits
3 Commits
v0.9.1
...
0caf5a61c7
| Author | SHA1 | Date | |
|---|---|---|---|
| 0caf5a61c7 | |||
| 7704d82c6f | |||
| a6f58a95e2 |
+71
-26
@@ -1524,16 +1524,34 @@ opaque_type(Params, Pair) when is_map(Pair) ->
|
||||
[{Name, TypeArgs}] = maps:to_list(Pair),
|
||||
{opaque_type_name(Name), [opaque_type(Params, Arg) || Arg <- TypeArgs]}.
|
||||
|
||||
% atoms for builtins, strings (lists) for user-defined types
|
||||
opaque_type_name(<<"int">>) -> integer;
|
||||
opaque_type_name(<<"address">>) -> address;
|
||||
opaque_type_name(<<"contract">>) -> contract;
|
||||
opaque_type_name(<<"bool">>) -> boolean;
|
||||
opaque_type_name(<<"option">>) -> option;
|
||||
opaque_type_name(<<"list">>) -> list;
|
||||
opaque_type_name(<<"map">>) -> map;
|
||||
opaque_type_name(<<"string">>) -> string;
|
||||
opaque_type_name(Name) -> binary_to_list(Name).
|
||||
% Atoms for builtins, strings (lists) for user-defined types.
|
||||
%
|
||||
% There are some magic built in types that may or may not also need atoms to
|
||||
% represent them, and may or may not need to be handled explicitly in
|
||||
% coerce/3, if we can't flatten them directly
|
||||
%
|
||||
% These types represent some FATE variant:
|
||||
% Chain.ttl, AENS.pointee, AENS.name, AENSv2.pointee, AENSv2.name,
|
||||
% Chain.ga_meta_tx, Chain.paying_for_tx, Chain.base_tx,
|
||||
%
|
||||
% And then MCL_BLS12_381.fr represent bytes(32), and MCL_BLS12_381.fp
|
||||
% represents bytes(48).
|
||||
opaque_type_name(<<"int">>) -> integer;
|
||||
opaque_type_name(<<"bool">>) -> boolean;
|
||||
opaque_type_name(<<"bits">>) -> bits;
|
||||
opaque_type_name(<<"char">>) -> integer;
|
||||
opaque_type_name(<<"string">>) -> string;
|
||||
opaque_type_name(<<"address">>) -> address;
|
||||
opaque_type_name(<<"hash">>) -> hash;
|
||||
opaque_type_name(<<"signature">>) -> signature;
|
||||
opaque_type_name(<<"bytes">>) -> bytes;
|
||||
opaque_type_name(<<"contract">>) -> contract;
|
||||
opaque_type_name(<<"list">>) -> list;
|
||||
opaque_type_name(<<"map">>) -> map;
|
||||
opaque_type_name(<<"option">>) -> option;
|
||||
opaque_type_name(<<"name">>) -> name;
|
||||
opaque_type_name(<<"channel">>) -> channel;
|
||||
opaque_type_name(Name) -> binary_to_list(Name).
|
||||
|
||||
% Type preparation has two goals. First, we need a data structure that can be
|
||||
% traversed quickly, to take sophia-esque erlang expressions and turn them into
|
||||
@@ -1788,33 +1806,28 @@ coerce({O, N, integer}, S, to_fate) when is_list(S) ->
|
||||
error:badarg -> single_error({invalid, O, N, S})
|
||||
end;
|
||||
coerce({O, N, address}, S, to_fate) ->
|
||||
try
|
||||
case gmser_api_encoder:decode(unicode:characters_to_binary(S)) of
|
||||
{account_pubkey, Key} -> {ok, {address, Key}};
|
||||
_ -> single_error({invalid, O, N, S})
|
||||
end
|
||||
catch
|
||||
error:_ -> single_error({invalid, O, N, S})
|
||||
end;
|
||||
coerce_chain_object(O, N, address, account_pubkey, S);
|
||||
coerce({_, _, address}, {address, Bin}, from_fate) ->
|
||||
Address = gmser_api_encoder:encode(account_pubkey, Bin),
|
||||
{ok, unicode:characters_to_list(Address)};
|
||||
coerce({O, N, contract}, S, to_fate) ->
|
||||
try
|
||||
case gmser_api_encoder:decode(unicode:characters_to_binary(S)) of
|
||||
{contract_pubkey, Key} -> {ok, {contract, Key}};
|
||||
_ -> single_error({invalid, O, N, S})
|
||||
end
|
||||
catch
|
||||
error:_ -> single_error({invalid, O, N, S})
|
||||
end;
|
||||
coerce_chain_object(O, N, contract, contract_pubkey, S);
|
||||
coerce({_, _, contract}, {contract, Bin}, from_fate) ->
|
||||
Address = gmser_api_encoder:encode(contract_pubkey, Bin),
|
||||
{ok, unicode:characters_to_list(Address)};
|
||||
coerce({O, N, signature}, S, to_fate) ->
|
||||
coerce_chain_object(O, N, signature, signature, S);
|
||||
coerce({_, _, signature}, Bin, from_fate) ->
|
||||
Address = gmser_api_encoder:encode(signature, Bin),
|
||||
{ok, unicode:characters_to_list(Address)};
|
||||
coerce({_, _, boolean}, true, _) ->
|
||||
{ok, true};
|
||||
coerce({_, _, boolean}, "true", _) ->
|
||||
{ok, true};
|
||||
coerce({_, _, boolean}, false, _) ->
|
||||
{ok, false};
|
||||
coerce({_, _, boolean}, "false", _) ->
|
||||
{ok, false};
|
||||
coerce({O, N, boolean}, S, _) ->
|
||||
single_error({invalid, O, N, S});
|
||||
coerce({O, N, string}, Str, Direction) ->
|
||||
@@ -1879,6 +1892,27 @@ coerce({O, N, _}, Data, from_fate) ->
|
||||
{ok, Data};
|
||||
coerce({O, N, _}, Data, _) -> single_error({invalid, O, N, Data}).
|
||||
|
||||
coerce_chain_object(O, N, T, Tag, S) ->
|
||||
case decode_chain_object(Tag, S) of
|
||||
{ok, Data} -> {ok, coerce_chain_object2(T, Data)};
|
||||
{error, Reason} -> single_error({Reason, O, N, S})
|
||||
end.
|
||||
|
||||
coerce_chain_object2(address, Data) -> {address, Data};
|
||||
coerce_chain_object2(contract, Data) -> {contract, Data};
|
||||
coerce_chain_object2(signature, Data) -> Data.
|
||||
|
||||
decode_chain_object(Tag, S) ->
|
||||
try
|
||||
case gmser_api_encoder:decode(unicode:characters_to_binary(S)) of
|
||||
{Tag, Data} -> {ok, Data};
|
||||
{_, _} -> {error, wrong_prefix}
|
||||
end
|
||||
catch
|
||||
error:missing_prefix -> {error, missing_prefix};
|
||||
error:incorrect_size -> {error, incorrect_size}
|
||||
end.
|
||||
|
||||
coerce_list(Type, Elements, Direction) ->
|
||||
% 0 index since it represents a sophia list
|
||||
coerce_list(Type, Elements, Direction, 0, [], []).
|
||||
@@ -2409,6 +2443,8 @@ try_coerce(Type, Sophia, Fate) ->
|
||||
_ ->
|
||||
erlang:error({from_fate_failed, Sophia, SophiaActual})
|
||||
end,
|
||||
% Finally, check that the FATE result is something that gmb understands.
|
||||
gmb_fate_encoding:serialize(Fate),
|
||||
ok.
|
||||
|
||||
coerce_int_test() ->
|
||||
@@ -2431,6 +2467,15 @@ coerce_contract_test() ->
|
||||
167,208,53,78,40,235,2,163,132,36,47,183,228,151,9,
|
||||
210,39,214>>}).
|
||||
|
||||
coerce_signature_test() ->
|
||||
{ok, Type} = annotate_type(signature, #{}),
|
||||
try_coerce(Type,
|
||||
"sg_XDyF8LJC4tpMyAySvpaG1f5V9F2XxAbRx9iuVjvvdNMwVracLhzAuXhRM5kXAFtpwW1DCHuz5jGehUayCah4jub32Ti2n",
|
||||
<<231,4,97,129,16,173,37,42,194,249,28,94,134,163,208,84,22,135,
|
||||
169,85,212,142,14,12,233,252,97,50,193,158,229,51,123,206,222,
|
||||
249,2,3,85,173,106,150,243,253,89,128,248,52,195,140,95,114,
|
||||
233,110,119,143,206,137,124,36,63,154,85,7>>).
|
||||
|
||||
coerce_bool_test() ->
|
||||
{ok, Type} = annotate_type(boolean, #{}),
|
||||
try_coerce(Type, true, true),
|
||||
|
||||
Reference in New Issue
Block a user