From 68e6a2163ee13bc08aa4cae046bd47a24ac4b6b7 Mon Sep 17 00:00:00 2001 From: Thomas Arts Date: Mon, 8 Apr 2019 11:50:01 +0200 Subject: [PATCH 01/13] fate_type_type should be {variant, List} without explicitly storing the size --- src/aeb_fate_data.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aeb_fate_data.erl b/src/aeb_fate_data.erl index dcc40f2..1586e83 100644 --- a/src/aeb_fate_data.erl +++ b/src/aeb_fate_data.erl @@ -34,7 +34,7 @@ | name | channel | bits - | {variant, list(), integer()}. + | {variant, list()}. -type fate_type() :: -- 2.30.2 From 15ee836ddb36f8716beaaa7834acd19b258ee8d2 Mon Sep 17 00:00:00 2001 From: Thomas Arts Date: Mon, 8 Apr 2019 11:50:12 +0200 Subject: [PATCH 02/13] Explanatory comment --- src/aeb_fate_data.erl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/aeb_fate_data.erl b/src/aeb_fate_data.erl index 1586e83..531ec9f 100644 --- a/src/aeb_fate_data.erl +++ b/src/aeb_fate_data.erl @@ -120,6 +120,9 @@ make_string(S) when is_list(S) -> ?FATE_STRING(list_to_binary(lists:flatten(S))); make_string(S) when is_binary(S) -> ?FATE_STRING(S). +%% Tag points to the selected variant (zero based) +%% The arity of this variant is read from the list of provided arities +%% and should match the size of the given tuple. make_variant(Arities, Tag, Values) -> Arities = [A || A <- Arities, is_integer(A), A < 256], Size = length(Arities), -- 2.30.2 From d2c70509dd5051c67823e139405bcd1a7d3ab7ce Mon Sep 17 00:00:00 2001 From: Thomas Arts Date: Mon, 8 Apr 2019 11:52:43 +0200 Subject: [PATCH 03/13] ignore more --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 3892b31..b43c201 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ src/aeb_fate_pp.erl *.erl~ *.hrl~ *.aes~ +doc +cover -- 2.30.2 From fe7e3a638a9bd531f95b6289d82647f807576090 Mon Sep 17 00:00:00 2001 From: Thomas Arts Date: Mon, 8 Apr 2019 12:29:18 +0200 Subject: [PATCH 04/13] Fix scan error --- src/aeb_fate_asm_scan.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aeb_fate_asm_scan.template b/src/aeb_fate_asm_scan.template index b5da2b7..9f4d73e 100644 --- a/src/aeb_fate_asm_scan.template +++ b/src/aeb_fate_asm_scan.template @@ -18,7 +18,7 @@ INT = {DIGIT}+ HEX = 0x{HEXDIGIT}+ OBJECT = @[a-z][a-z]_{BASE58}+ HASH = #{BASE64}+ -SIG = \$\sg_{BASE58}+ +SIG = \$sg_{BASE58}+ WS = [\000-\s] ID = {LOWER}[a-zA-Z0-9_]* STRING = "[^"]*" -- 2.30.2 From fa64bbb56cde5c0eba54107eaaf50233cb97588f Mon Sep 17 00:00:00 2001 From: Thomas Arts Date: Mon, 8 Apr 2019 13:41:23 +0200 Subject: [PATCH 05/13] Don't forget z --- src/aeb_fate_asm_scan.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aeb_fate_asm_scan.template b/src/aeb_fate_asm_scan.template index 9f4d73e..390975f 100644 --- a/src/aeb_fate_asm_scan.template +++ b/src/aeb_fate_asm_scan.template @@ -13,7 +13,7 @@ HEXDIGIT = [0-9a-fA-F] LOWER = [a-z_] UPPER = [A-Z] BASE58 = [123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz] -BASE64 = [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy0123456789+/=] +BASE64 = [A-Za-z0-9+/=] INT = {DIGIT}+ HEX = 0x{HEXDIGIT}+ OBJECT = @[a-z][a-z]_{BASE58}+ -- 2.30.2 From 0c01215b6ad9894f0ea27634b160d95f73764d12 Mon Sep 17 00:00:00 2001 From: Thomas Arts Date: Mon, 8 Apr 2019 14:49:17 +0200 Subject: [PATCH 06/13] fix arities formatting --- src/aeb_fate_data.erl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/aeb_fate_data.erl b/src/aeb_fate_data.erl index 531ec9f..644d9de 100644 --- a/src/aeb_fate_data.erl +++ b/src/aeb_fate_data.erl @@ -216,7 +216,7 @@ format(?FATE_BITS(B)) when B < 0 -> format(?FATE_VARIANT(Arities, Tag, T)) -> ["(| ", lists:join("| ", - [io_lib:format("~p", [Arities]), + [format_arities(Arities), integer_to_list(Tag) | [format(make_tuple(T))]]), " |)"]; @@ -247,6 +247,9 @@ format_nbits(N, Acc) -> Bit = $1 - (N band 1), format_nbits(N bsr 1, [Bit|Acc]). +format_arities(Arities) -> + ["[ ", lists:join(", ", [integer_to_list(E) || E <- Arities]), " ]"]. + format_list(List) -> ["[ ", lists:join(", ", [format(E) || E <- List]), " ]"]. -- 2.30.2 From f5f007e74d3351ea8e2deec09016d7acf47722ef Mon Sep 17 00:00:00 2001 From: Thomas Arts Date: Mon, 8 Apr 2019 16:29:31 +0200 Subject: [PATCH 07/13] Since the binaries are likely to be strings, unicode conversion makes more sense. --- src/aeb_fate_asm_scan.template | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/aeb_fate_asm_scan.template b/src/aeb_fate_asm_scan.template index 390975f..ba125e6 100644 --- a/src/aeb_fate_asm_scan.template +++ b/src/aeb_fate_asm_scan.template @@ -52,7 +52,7 @@ FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}. -{INT} : {token, {int, TokenLine, parse_int(TokenChars)}}. {STRING} : - {token, {string, TokenLine, list_to_binary(TokenChars)}}. + {token, {string, TokenLine, unicode:characters_to_binary(TokenChars)}}. {BITS} : {token, {bits, TokenLine, bits(TokenChars)}}. @@ -112,7 +112,7 @@ parse_hash("#" ++ Chars) -> base64:decode(Chars). parse_object([_|Chars]) -> - case aeser_api_encoder:decode(list_to_binary(Chars)) of + case aeser_api_encoder:decode(unicode:characters_to_binary(Chars)) of {account_pubkey, Bin} -> {address, Bin}; {contract_pubkey, Bin} -> {contract, Bin}; {oracle_pubkey, Bin} -> {oracle, Bin}; -- 2.30.2 From f88fe008bf1896a8378b4bf02e00eff08fe4fbae Mon Sep 17 00:00:00 2001 From: Thomas Arts Date: Mon, 8 Apr 2019 16:29:45 +0200 Subject: [PATCH 08/13] Add fate_bits as type --- src/aeb_fate_data.erl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/aeb_fate_data.erl b/src/aeb_fate_data.erl index 644d9de..e5c3ced 100644 --- a/src/aeb_fate_data.erl +++ b/src/aeb_fate_data.erl @@ -20,6 +20,7 @@ -type fate_signature() :: ?FATE_SIGNATURE_T. -type fate_variant() :: ?FATE_VARIANT_T. -type fate_tuple() :: ?FATE_TUPLE_T. +-type fate_bits() :: ?FATE_BITS_T. -type fate_type_type() :: integer | boolean @@ -54,6 +55,7 @@ | fate_channel() | fate_variant() | fate_map() + | fate_bits() | fate_type_type(). -export_type([fate_type/0 @@ -73,6 +75,7 @@ , fate_channel/0 , fate_variant/0 , fate_map/0 + , fate_bits/0 , fate_type_type/0 ]). -- 2.30.2 From 90659342c052ee3eddb933f94b4261fb177a225c Mon Sep 17 00:00:00 2001 From: Thomas Arts Date: Mon, 8 Apr 2019 16:29:55 +0200 Subject: [PATCH 09/13] Quote the string --- src/aeb_fate_data.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aeb_fate_data.erl b/src/aeb_fate_data.erl index e5c3ced..91523fb 100644 --- a/src/aeb_fate_data.erl +++ b/src/aeb_fate_data.erl @@ -211,7 +211,7 @@ format(L) when ?IS_FATE_LIST(L) -> format_list(?FATE_LIST_VALUE(L)); format(?FATE_UNIT) -> "()"; format(?FATE_TUPLE(T)) -> ["( ", lists:join(", ", [ format(E) || E <- erlang:tuple_to_list(T)]), " )"]; -format(S) when ?IS_FATE_STRING(S) -> [S]; +format(S) when ?IS_FATE_STRING(S) -> ["\"", S, "\""]; format(?FATE_BITS(B)) when B >= 0 -> ["<", format_bits(B, "") , ">"]; format(?FATE_BITS(B)) when B < 0 -> -- 2.30.2 From 96c0fab3ab8cdde48f796cd89522ecfc1b0fc26e Mon Sep 17 00:00:00 2001 From: Thomas Arts Date: Tue, 9 Apr 2019 08:29:55 +0200 Subject: [PATCH 10/13] Remove fate_type_type is not a fate_type --- src/aeb_fate_data.erl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/aeb_fate_data.erl b/src/aeb_fate_data.erl index 91523fb..37e9cd0 100644 --- a/src/aeb_fate_data.erl +++ b/src/aeb_fate_data.erl @@ -55,8 +55,7 @@ | fate_channel() | fate_variant() | fate_map() - | fate_bits() - | fate_type_type(). + | fate_bits(). -export_type([fate_type/0 , fate_boolean/0 -- 2.30.2 From a670d1ca6c90acc79610f79996f7bb492e3fe4ce Mon Sep 17 00:00:00 2001 From: Thomas Arts Date: Tue, 9 Apr 2019 09:05:26 +0200 Subject: [PATCH 11/13] Remove the quotes from scanned string --- src/aeb_fate_asm_scan.template | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/aeb_fate_asm_scan.template b/src/aeb_fate_asm_scan.template index ba125e6..cd0bb5f 100644 --- a/src/aeb_fate_asm_scan.template +++ b/src/aeb_fate_asm_scan.template @@ -51,8 +51,11 @@ FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}. {token, {int, TokenLine, parse_int(TokenChars)}}. -{INT} : {token, {int, TokenLine, parse_int(TokenChars)}}. + +%% Due to the definition of STRING the tokens start and end with a quote ". {STRING} : - {token, {string, TokenLine, unicode:characters_to_binary(TokenChars)}}. + {token, {string, TokenLine, unicode:characters_to_binary( + lists:sublist(TokenChars, 2, length(TokenChars) - 2))}}. {BITS} : {token, {bits, TokenLine, bits(TokenChars)}}. -- 2.30.2 From 75f3eeffa7b06f406eb992266833b623e1664850 Mon Sep 17 00:00:00 2001 From: Thomas Arts Date: Tue, 9 Apr 2019 10:32:08 +0200 Subject: [PATCH 12/13] Add quickcheck properties --- quickcheck/aefate_eqc.erl | 107 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 quickcheck/aefate_eqc.erl diff --git a/quickcheck/aefate_eqc.erl b/quickcheck/aefate_eqc.erl new file mode 100644 index 0000000..3049c41 --- /dev/null +++ b/quickcheck/aefate_eqc.erl @@ -0,0 +1,107 @@ +%%% @author Thomas Arts +%%% @copyright (C) 2018, Thomas Arts +%%% @doc Use `rebar3 as eqc shell` to run properties in the shell +%%% +%%% +%%% @end +%%% Created : 13 Dec 2018 by Thomas Arts + +-module(aefate_eqc). + +-include_lib("eqc/include/eqc.hrl"). + +-compile([export_all, nowarn_export_all]). + +prop_roundtrip() -> + ?FORALL(FateData, fate_type(), + measure(bytes, size(term_to_binary(FateData)), + begin + Serialized = aeb_fate_encoding:serialize(FateData), + ?WHENFAIL(eqc:format("Serialized ~p to ~p~n", [FateData, Serialized]), + equals(aeb_fate_encoding:deserialize(Serialized), FateData)) + end + )). + +prop_format() -> + ?FORALL(FateData, fate_type(), + ?WHENFAIL(eqc:format("Trying to format ~p failed~n",[FateData]), + begin + String = aeb_fate_data:format(FateData), + collect([FateData, unicode:characters_to_binary(String, latin1)], true) + end)). + +prop_format_scan() -> + ?FORALL(FateData, fate_type(), + ?WHENFAIL(eqc:format("Trying to format ~p failed~n~p~n", [FateData, catch unicode:characters_to_list(aeb_fate_data:format(FateData), utf8) ]), + begin + String = aeb_fate_data:format(FateData), + {ok, _Scanned, _} = aeb_fate_asm_scan:scan(unicode:characters_to_list(String)), + true + end)). + +fate_type() -> + ?SIZED(Size, fate_type(Size, [map])). + +fate_type(0, _Options) -> + ?LAZY( + oneof([fate_integer(), + fate_boolean(), + fate_nil(), + fate_unit(), + fate_string(), + fate_address(), + fate_hash(), + fate_signature(), + fate_contract(), + fate_oracle(), + fate_name(), + fate_bits(), + fate_channel()])); +fate_type(Size, Options) -> + ?LETSHRINK([Smaller], [?LAZY(fate_type(Size div 5, Options))], + oneof([?LAZY(fate_type(Size - 1, Options)), + ?LAZY(fate_list( Smaller )), + ?LAZY(fate_tuple( list( Smaller ))), + ?LAZY(fate_variant(?LET(L, list( Smaller), list_to_tuple(L))))] ++ + [ + ?LAZY(fate_map( fate_type(Size div 3, Options -- [map]), + Smaller)) + || lists:member(map, Options) + ])). + + +fate_integer() -> oneof([int(), largeint()]). +fate_bits() -> {bits, oneof([int(), largeint()])}. +fate_boolean() -> elements([true, false]). +fate_nil() -> []. +fate_unit() -> {tuple, {}}. +fate_string() -> ?SUCHTHAT(S, utf8(), string:find(S, "\"") == nomatch). +fate_address() -> {address, non_zero_binary(256 div 8)}. +fate_hash() -> {hash, non_zero_binary(32)}. +fate_signature() -> {signature, non_zero_binary(64)}. +fate_contract() -> {contract, non_zero_binary(256 div 8)}. +fate_oracle() -> {oracle, non_zero_binary(256 div 8)}. +fate_name() -> {name, non_zero_binary(256 div 8)}. +fate_channel() -> {channel, non_zero_binary(256 div 8)}. + +%% May shrink to fate_unit +fate_tuple(ListGen) -> + {tuple, ?LET(Elements, ListGen, list_to_tuple(Elements))}. + +fate_variant(TupleGen) -> + ?LET({L1, L2, Tuple}, {list(choose(0, 255)), list(choose(0,255)), TupleGen}, + {variant, L1 ++ [size(Tuple)] ++ L2, length(L1), Tuple}). + +fate_list(Gen) -> + oneof([fate_nil(), ?SHRINK(list(Gen), [fate_nil()])]). + +fate_map(KeyGen, ValGen) -> + map(KeyGen, ValGen). + + +non_zero_binary(N) -> + Bits = N*8, + ?SUCHTHAT(Bin, binary(N), begin <> = Bin, V =/= 0 end). + +char() -> + choose(1, 255). -- 2.30.2 From 6466ddb8661a587845ac94d8be962f13a7540efb Mon Sep 17 00:00:00 2001 From: Thomas Arts Date: Tue, 9 Apr 2019 14:02:21 +0200 Subject: [PATCH 13/13] Bump version --- src/aebytecode.app.src | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aebytecode.app.src b/src/aebytecode.app.src index 7116b7e..56d1c0a 100644 --- a/src/aebytecode.app.src +++ b/src/aebytecode.app.src @@ -1,6 +1,6 @@ {application, aebytecode, [{description, "Bytecode definitions, serialization and deserialization for aeternity."}, - {vsn, "2.0.1"}, + {vsn, "2.1.0"}, {registered, []}, {applications, [kernel, -- 2.30.2