Merge pull request #56 from aeternity/PT-166788837-bytes
PT-166788837 bytes
This commit is contained in:
commit
59af12bf34
@ -7,8 +7,7 @@
|
|||||||
-define(FATE_MAP_T, #{ fate_type() => fate_type() }).
|
-define(FATE_MAP_T, #{ fate_type() => fate_type() }).
|
||||||
-define(FATE_STRING_T, binary()).
|
-define(FATE_STRING_T, binary()).
|
||||||
-define(FATE_ADDRESS_T, {address, <<_:256>>}).
|
-define(FATE_ADDRESS_T, {address, <<_:256>>}).
|
||||||
-define(FATE_HASH_T, {hash, binary()}).
|
-define(FATE_BYTES_T(N), {bytes, binary()}).
|
||||||
-define(FATE_SIGNATURE_T, {signature, binary()}).
|
|
||||||
-define(FATE_CONTRACT_T, {contract, <<_:256>>}).
|
-define(FATE_CONTRACT_T, {contract, <<_:256>>}).
|
||||||
-define(FATE_ORACLE_T, {oracle, <<_:256>>}).
|
-define(FATE_ORACLE_T, {oracle, <<_:256>>}).
|
||||||
-define(FATE_ORACLE_Q_T, {oracle_query, <<_:256>>}).
|
-define(FATE_ORACLE_Q_T, {oracle_query, <<_:256>>}).
|
||||||
@ -25,8 +24,8 @@
|
|||||||
-define(IS_FATE_MAP(X), (is_map(X))).
|
-define(IS_FATE_MAP(X), (is_map(X))).
|
||||||
-define(IS_FATE_TUPLE(X), (is_tuple(X) andalso (tuple == element(1, X) andalso is_tuple(element(2, X))))).
|
-define(IS_FATE_TUPLE(X), (is_tuple(X) andalso (tuple == element(1, X) andalso is_tuple(element(2, X))))).
|
||||||
-define(IS_FATE_ADDRESS(X), (is_tuple(X) andalso (address == element(1, X) andalso is_binary(element(2, X))))).
|
-define(IS_FATE_ADDRESS(X), (is_tuple(X) andalso (address == element(1, X) andalso is_binary(element(2, X))))).
|
||||||
-define(IS_FATE_HASH(X), (is_tuple(X) andalso (hash == element(1, X) andalso is_binary(element(2, X))))).
|
-define(IS_FATE_BYTES(X), (is_tuple(X) andalso (bytes == element(1, X) andalso is_binary(element(2, X))))).
|
||||||
-define(IS_FATE_SIGNATURE(X), (is_tuple(X) andalso (signature == element(1, X) andalso is_binary(element(2, X))))).
|
-define(IS_FATE_BYTES(N, X), (?IS_FATE_BYTES(X) andalso byte_size(element(2, X)) == (N))).
|
||||||
-define(IS_FATE_CONTRACT(X), (is_tuple(X) andalso (contract == element(1, X) andalso is_binary(element(2, X))))).
|
-define(IS_FATE_CONTRACT(X), (is_tuple(X) andalso (contract == element(1, X) andalso is_binary(element(2, X))))).
|
||||||
-define(IS_FATE_ORACLE(X), (is_tuple(X) andalso (oracle == element(1, X) andalso is_binary(element(2, X))))).
|
-define(IS_FATE_ORACLE(X), (is_tuple(X) andalso (oracle == element(1, X) andalso is_binary(element(2, X))))).
|
||||||
-define(IS_FATE_ORACLE_Q(X), (is_tuple(X) andalso (oracle_query == element(1, X) andalso is_binary(element(2, X))))).
|
-define(IS_FATE_ORACLE_Q(X), (is_tuple(X) andalso (oracle_query == element(1, X) andalso is_binary(element(2, X))))).
|
||||||
@ -46,8 +45,7 @@
|
|||||||
-define(FATE_UNIT, {tuple, {}}).
|
-define(FATE_UNIT, {tuple, {}}).
|
||||||
-define(FATE_TUPLE(T), {tuple, T}).
|
-define(FATE_TUPLE(T), {tuple, T}).
|
||||||
-define(FATE_ADDRESS(A), {address, A}).
|
-define(FATE_ADDRESS(A), {address, A}).
|
||||||
-define(FATE_HASH(X), {hash, X}).
|
-define(FATE_BYTES(X), {bytes, X}).
|
||||||
-define(FATE_SIGNATURE(S), {signature, S}).
|
|
||||||
-define(FATE_CONTRACT(X), {contract, X}).
|
-define(FATE_CONTRACT(X), {contract, X}).
|
||||||
-define(FATE_ORACLE(X), {oracle, X}).
|
-define(FATE_ORACLE(X), {oracle, X}).
|
||||||
-define(FATE_ORACLE_Q(X), {oracle_query, X}).
|
-define(FATE_ORACLE_Q(X), {oracle_query, X}).
|
||||||
@ -62,8 +60,7 @@
|
|||||||
-define(FATE_TUPLE_ELEMENTS(X), (tuple_to_list(element(2, X)))).
|
-define(FATE_TUPLE_ELEMENTS(X), (tuple_to_list(element(2, X)))).
|
||||||
-define(FATE_STRING_VALUE(X), (X)).
|
-define(FATE_STRING_VALUE(X), (X)).
|
||||||
-define(FATE_ADDRESS_VALUE(X), (element(2, X))).
|
-define(FATE_ADDRESS_VALUE(X), (element(2, X))).
|
||||||
-define(FATE_HASH_VALUE(X), (element(2, X))).
|
-define(FATE_BYTES_VALUE(X), (element(2, X))).
|
||||||
-define(FATE_SIGNATURE_VALUE(X), (element(2, X))).
|
|
||||||
-define(FATE_CONTRACT_VALUE(X), (element(2, X))).
|
-define(FATE_CONTRACT_VALUE(X), (element(2, X))).
|
||||||
-define(FATE_ORACLE_VALUE(X), (element(2, X))).
|
-define(FATE_ORACLE_VALUE(X), (element(2, X))).
|
||||||
-define(FATE_NAME_VALUE(X), (element(2, X))).
|
-define(FATE_NAME_VALUE(X), (element(2, X))).
|
||||||
|
@ -27,35 +27,41 @@
|
|||||||
prop_serializes() ->
|
prop_serializes() ->
|
||||||
in_parallel(
|
in_parallel(
|
||||||
?FORALL(FateCode, fate_code(0),
|
?FORALL(FateCode, fate_code(0),
|
||||||
?WHENFAIL(eqc:format("Trying to serialize/deserialize ~p failed~n", [FateCode]),
|
|
||||||
begin
|
begin
|
||||||
Binary = aeb_fate_code:serialize(FateCode),
|
{T0, Binary} = timer:tc(fun() -> aeb_fate_code:serialize(FateCode) end),
|
||||||
?WHENFAIL(eqc:format("serialized: ~p~n", [Binary]),
|
?WHENFAIL(eqc:format("serialized:\n ~120p~n", [Binary]),
|
||||||
begin
|
begin
|
||||||
Decoded = aeb_fate_code:deserialize(Binary),
|
{T1, Decoded} = timer:tc(fun() -> aeb_fate_code:deserialize(Binary) end),
|
||||||
measure(binary_size, size(Binary),
|
measure(binary_size, size(Binary),
|
||||||
equals(Decoded, FateCode))
|
measure(serialize, T0 / 1000,
|
||||||
|
measure(deserialize, T1 / 1000,
|
||||||
|
conjunction([{equal, equals(Decoded, FateCode)},
|
||||||
|
{serialize_time, T0 / 1000 < 500},
|
||||||
|
{deserialize_time, T1 / 1000 < 500}]))))
|
||||||
end)
|
end)
|
||||||
end))).
|
end)).
|
||||||
|
|
||||||
prop_fail_serializes() ->
|
prop_fail_serializes() ->
|
||||||
conjunction([{Failure, eqc:counterexample(
|
conjunction([{Failure, eqc:counterexample(
|
||||||
?FORALL(FateCode, fate_code(Failure),
|
?FORALL(FateCode, fate_code(Failure),
|
||||||
?FORALL(Binary, catch aeb_fate_code:serialize(FateCode),
|
?FORALL(Binary, catch aeb_fate_code:serialize(FateCode),
|
||||||
is_binary(aeb_fate_code:serialize(FateCode)))))
|
is_binary(Binary))))
|
||||||
=/= true} || Failure <- [1,2,3,4, 5] ]).
|
=/= true} || Failure <- [1, 2, 3, 4, 5] ]).
|
||||||
|
|
||||||
prop_fuzz() ->
|
prop_fuzz() ->
|
||||||
in_parallel(
|
in_parallel(
|
||||||
?FORALL(Binary, ?LET(FateCode, fate_code(0), aeb_fate_code:serialize(FateCode)),
|
?FORALL(Binary, ?LET(FateCode, fate_code(0), aeb_fate_code:serialize(FateCode)),
|
||||||
?FORALL(InjectedBin, injection(Binary),
|
?FORALL(FuzzedBin, fuzz(Binary),
|
||||||
try Org = aeb_fate_code:deserialize(InjectedBin),
|
try aeb_fate_code:deserialize(FuzzedBin) of
|
||||||
NewBin = aeb_fate_code:serialize(Org),
|
Code ->
|
||||||
NewOrg = aeb_fate_code:deserialize(NewBin),
|
?WHENFAIL(eqc:format("Code:\n ~p\n", [Code]),
|
||||||
?WHENFAIL(eqc:format("Deserialize ~p gives\n~p\nSerializes to ~p\n", [InjectedBin, Org, NewOrg]),
|
begin
|
||||||
equals(NewBin, InjectedBin))
|
Bin1 = aeb_fate_code:serialize(Code),
|
||||||
catch _:_ ->
|
Code1 = aeb_fate_code:deserialize(Bin1),
|
||||||
true
|
?WHENFAIL(eqc:format("Reserialized\n ~120p\n", [Bin1]),
|
||||||
|
equals(Code, Code1))
|
||||||
|
end)
|
||||||
|
catch _:_ -> true
|
||||||
end))).
|
end))).
|
||||||
|
|
||||||
prop_opcodes() ->
|
prop_opcodes() ->
|
||||||
@ -80,16 +86,23 @@ fate_code(Failure) ->
|
|||||||
{non_empty(map(if Failure == 1 -> binary(1);
|
{non_empty(map(if Failure == 1 -> binary(1);
|
||||||
true -> binary(4) end,
|
true -> binary(4) end,
|
||||||
{{list(aefate_type_eqc:fate_type(Size div 3)), aefate_type_eqc:fate_type(Size div 3)}, bbs_code(Failure)})),
|
{{list(aefate_type_eqc:fate_type(Size div 3)), aefate_type_eqc:fate_type(Size div 3)}, bbs_code(Failure)})),
|
||||||
map(small_fate_data_key(5), small_fate_data(4)),
|
small_map(small_fate_data_key(5), small_fate_data(4)),
|
||||||
map(small_fate_data_key(5), small_fate_data(4))},
|
small_map(small_fate_data_key(5), small_fate_data(4))},
|
||||||
aeb_fate_code:update_annotations(
|
aeb_fate_code:update_annotations(
|
||||||
aeb_fate_code:update_symbols(
|
aeb_fate_code:update_symbols(
|
||||||
aeb_fate_code:update_functions(
|
aeb_fate_code:update_functions(
|
||||||
aeb_fate_code:new(), FMap), SMap), AMap))).
|
aeb_fate_code:new(), FMap), SMap), AMap))).
|
||||||
|
|
||||||
|
short_list(Max, Gen) ->
|
||||||
|
?LET(N, choose(0, Max), eqc_gen:list(N, Gen)).
|
||||||
|
|
||||||
|
small_map(KeyGen, ValGen) ->
|
||||||
|
?LET(KeyVals, short_list(6, {KeyGen, ValGen}),
|
||||||
|
return(maps:from_list(KeyVals))).
|
||||||
|
|
||||||
bbs_code(Failure) ->
|
bbs_code(Failure) ->
|
||||||
frequency([{if Failure == 2 -> 5; true -> 0 end, #{0 => []}},
|
frequency([{if Failure == 2 -> 5; true -> 0 end, #{0 => []}},
|
||||||
{10, ?LET(BBs, list(bb_code(Failure)),
|
{10, ?LET(BBs, short_list(6, bb_code(Failure)),
|
||||||
maps:from_list(
|
maps:from_list(
|
||||||
lists:zip(lists:seq(0, length(BBs)-1), BBs)))}]).
|
lists:zip(lists:seq(0, length(BBs)-1), BBs)))}]).
|
||||||
|
|
||||||
@ -97,9 +110,9 @@ bb_code(Failure) ->
|
|||||||
EndBB = [ Op || Op <- valid_opcodes(), aeb_fate_opcodes:end_bb(Op) ],
|
EndBB = [ Op || Op <- valid_opcodes(), aeb_fate_opcodes:end_bb(Op) ],
|
||||||
NonEndBB = valid_opcodes() -- EndBB,
|
NonEndBB = valid_opcodes() -- EndBB,
|
||||||
frequency(
|
frequency(
|
||||||
[{if Failure == 3 -> 5; true -> 0 end, ?LET(Ops, non_empty(list(elements(NonEndBB))), bblock(Failure, Ops))},
|
[{if Failure == 3 -> 5; true -> 0 end, ?LET(Ops, non_empty(short_list(6, elements(NonEndBB))), bblock(Failure, Ops))},
|
||||||
{if Failure == 4 -> 5; true -> 0 end, ?LET({Ops, Op}, {list(elements(valid_opcodes())), elements(EndBB)}, bblock(Failure, Ops ++ [Op]))},
|
{if Failure == 4 -> 5; true -> 0 end, ?LET({Ops, Op}, {short_list(6, elements(valid_opcodes())), elements(EndBB)}, bblock(Failure, Ops ++ [Op]))},
|
||||||
{10, ?LET({Ops, Op}, {list(elements(NonEndBB)), elements(EndBB)},
|
{10, ?LET({Ops, Op}, {short_list(6, elements(NonEndBB)), elements(EndBB)},
|
||||||
bblock(Failure, Ops ++ [Op]))}]).
|
bblock(Failure, Ops ++ [Op]))}]).
|
||||||
|
|
||||||
bblock(Failure, Ops) ->
|
bblock(Failure, Ops) ->
|
||||||
@ -118,14 +131,34 @@ bblock(Failure, Ops) ->
|
|||||||
end
|
end
|
||||||
end || Op <- Ops ].
|
end || Op <- Ops ].
|
||||||
|
|
||||||
injection(Binary) ->
|
fuzz(Binary) ->
|
||||||
?LET({N, Inj}, {choose(0, byte_size(Binary) - 1), choose(0,255)},
|
?LET({N, Inj}, {choose(0, byte_size(Binary) - 1), choose(0, 255)},
|
||||||
begin
|
begin
|
||||||
M = N * 8,
|
M = N * 8,
|
||||||
<<X:M, _:8, Z/binary>> = Binary,
|
<<X:M, _:8, Z/binary>> = Binary,
|
||||||
<<X:M, Inj:8, Z/binary>>
|
<<X:M, Inj:8, Z/binary>>
|
||||||
end).
|
end).
|
||||||
|
|
||||||
|
prop_small() ->
|
||||||
|
?FORALL(Value, small_fate_data(4),
|
||||||
|
begin
|
||||||
|
Bin = aeb_fate_encoding:serialize(Value),
|
||||||
|
Size = byte_size(Bin),
|
||||||
|
measure(size, Size,
|
||||||
|
?WHENFAIL(eqc:format("Size: ~p\n", [Size]),
|
||||||
|
Size < 1000))
|
||||||
|
end).
|
||||||
|
|
||||||
|
prop_small_type() ->
|
||||||
|
?FORALL(Type, ?SIZED(Size, aefate_type_eqc:fate_type(Size div 3)),
|
||||||
|
begin
|
||||||
|
Bin = iolist_to_binary(aeb_fate_encoding:serialize_type(Type)),
|
||||||
|
Size = byte_size(Bin),
|
||||||
|
measure(size, Size,
|
||||||
|
?WHENFAIL(eqc:format("Size: ~p\n", [Size]),
|
||||||
|
Size < 1000))
|
||||||
|
end).
|
||||||
|
|
||||||
small_fate_data(N) ->
|
small_fate_data(N) ->
|
||||||
?SIZED(Size, resize(Size div N, aefate_eqc:fate_data())).
|
?SIZED(Size, resize(Size div N, aefate_eqc:fate_data())).
|
||||||
|
|
||||||
|
@ -32,21 +32,15 @@ prop_format_scan() ->
|
|||||||
end)).
|
end)).
|
||||||
|
|
||||||
prop_serializes() ->
|
prop_serializes() ->
|
||||||
?FORALL(FateDatas, non_empty(?SIZED(Size, resize(Size div 2, list(fate_data())))),
|
?FORALL({Data, Garbage}, {fate_data(), binary()},
|
||||||
?WHENFAIL(eqc:format("Trying to serialize/deserialize ~p failed~n", [FateDatas]),
|
?WHENFAIL(eqc:format("Trying to serialize/deserialize ~p failed~n", [Data]),
|
||||||
begin
|
begin
|
||||||
{T1, Binary} =
|
Binary = <<(aeb_fate_encoding:serialize(Data))/binary, Garbage/binary>>,
|
||||||
timer:tc( fun() ->
|
{FateData, Rest} = aeb_fate_encoding:deserialize_one(Binary),
|
||||||
<< begin B = aeb_fate_encoding:serialize(Data),
|
|
||||||
<<B/binary>> end || Data <- FateDatas >>
|
|
||||||
end),
|
|
||||||
{T2, {FateData, _}} =
|
|
||||||
timer:tc(fun() -> aeb_fate_encoding:deserialize_one(Binary) end),
|
|
||||||
measure(binary_size, size(Binary),
|
measure(binary_size, size(Binary),
|
||||||
measure(encode, T1,
|
conjunction([{equal, equals(Data, FateData)},
|
||||||
measure(decode, T2,
|
{rest, equals(Garbage, Rest)},
|
||||||
conjunction([{equal, equals(hd(FateDatas), FateData)},
|
{size, size(Binary) < 500000}]))
|
||||||
{size, size(Binary) < 500000}]))))
|
|
||||||
end)).
|
end)).
|
||||||
|
|
||||||
prop_fuzz() ->
|
prop_fuzz() ->
|
||||||
@ -98,74 +92,65 @@ fate_data() ->
|
|||||||
?SIZED(Size, ?LET(Data, fate_data(Size, [map, variant]), eqc_symbolic:eval(Data))).
|
?SIZED(Size, ?LET(Data, fate_data(Size, [map, variant]), eqc_symbolic:eval(Data))).
|
||||||
|
|
||||||
fate_data_key() ->
|
fate_data_key() ->
|
||||||
?SIZED(Size, ?LET(Data, fate_data(Size div 4, []), eqc_symbolic:eval(Data))).
|
?SIZED(Size, ?LET(Data, fate_data(Size div 4, [variant]), eqc_symbolic:eval(Data))).
|
||||||
|
|
||||||
fate_data(0, _Options) ->
|
fate_data(0, _Options) ->
|
||||||
?LAZY(
|
?LAZY(
|
||||||
oneof([fate_integer(),
|
frequency(
|
||||||
fate_boolean(),
|
[{5, oneof([fate_integer(), fate_boolean(), fate_nil(), fate_unit()])},
|
||||||
fate_nil(),
|
{1, oneof([fate_string(), fate_address(), fate_bytes(), fate_contract(),
|
||||||
fate_unit(),
|
fate_oracle(), fate_oracle_q(), fate_name(), fate_bits(), fate_channel()])}]));
|
||||||
fate_string(),
|
|
||||||
fate_address(),
|
|
||||||
fate_hash(),
|
|
||||||
fate_signature(),
|
|
||||||
fate_contract(),
|
|
||||||
fate_oracle(),
|
|
||||||
fate_oracle_q(),
|
|
||||||
fate_name(),
|
|
||||||
fate_bits(),
|
|
||||||
fate_channel()]));
|
|
||||||
fate_data(Size, Options) ->
|
fate_data(Size, Options) ->
|
||||||
oneof([?LAZY(fate_data(Size - 1, Options)),
|
?LAZY(
|
||||||
?LAZY(fate_list( fate_data(Size div 5, Options) )),
|
oneof([fate_data(0, Options),
|
||||||
?LAZY(fate_tuple( list(fate_data(Size div 5, Options)) ))] ++
|
fate_list(Size, Options),
|
||||||
[?LAZY(fate_variant( list(fate_data(Size div 5, Options))))
|
fate_tuple(Size, Options)] ++
|
||||||
|| lists:member(variant, Options)
|
[fate_variant(Size, Options)
|
||||||
] ++
|
|| lists:member(variant, Options)] ++
|
||||||
[
|
[fate_map(Size, Options)
|
||||||
?LAZY(fate_map( fate_data(Size div 8, Options -- [map, variant]),
|
|| lists:member(map, Options)])).
|
||||||
fate_data(Size div 5, Options)))
|
|
||||||
|| lists:member(map, Options)
|
|
||||||
]).
|
|
||||||
|
|
||||||
|
|
||||||
fate_integer() -> {call, aeb_fate_data, make_integer, [oneof([int(), largeint()])]}.
|
fate_integer() -> ?LET(X, oneof([int(), largeint()]), return(aeb_fate_data:make_integer(X))).
|
||||||
fate_bits() -> {call, aeb_fate_data, make_bits, [oneof([int(), largeint()])]}.
|
fate_bits() -> ?LET(X, oneof([int(), largeint()]), return(aeb_fate_data:make_bits(X))).
|
||||||
fate_boolean() -> {call, aeb_fate_data, make_boolean, [elements([true, false])]}.
|
fate_boolean() -> ?LET(X, elements([true, false]), return(aeb_fate_data:make_boolean(X))).
|
||||||
fate_nil() -> {call, aeb_fate_data, make_list, [[]]}.
|
fate_nil() -> aeb_fate_data:make_list([]).
|
||||||
fate_unit() -> {call, aeb_fate_data, make_unit, []}.
|
fate_unit() -> aeb_fate_data:make_unit().
|
||||||
fate_string() -> {call, aeb_fate_data, make_string,
|
fate_string() -> ?LET(X, frequency([{10, non_quote_string()}, {2, list(non_quote_string())},
|
||||||
[frequency([{10, non_quote_string()}, {2, list(non_quote_string())},
|
{1, ?LET(N, choose(64-3, 64+3), vector(N, $a))}]),
|
||||||
{1, ?LET(N, choose(64-3, 64+3), vector(N, $a))}])]}.
|
return(aeb_fate_data:make_string(X))).
|
||||||
fate_address() -> {call, aeb_fate_data, make_address, [non_zero_binary(256 div 8)]}.
|
fate_address() -> ?LET(X, binary(256 div 8), return(aeb_fate_data:make_address(X))).
|
||||||
fate_hash() -> {call, aeb_fate_data, make_hash, [non_zero_binary(32)]}.
|
fate_bytes() -> ?LET(X, non_empty(binary()), return(aeb_fate_data:make_bytes(X))).
|
||||||
fate_signature() -> {call, aeb_fate_data, make_signature, [non_zero_binary(64)]}.
|
fate_contract() -> ?LET(X, binary(256 div 8), return(aeb_fate_data:make_contract(X))).
|
||||||
fate_contract() -> {call, aeb_fate_data, make_contract, [non_zero_binary(256 div 8)]}.
|
fate_oracle() -> ?LET(X, binary(256 div 8), return(aeb_fate_data:make_oracle(X))).
|
||||||
fate_oracle() -> {call, aeb_fate_data, make_oracle, [non_zero_binary(256 div 8)]}.
|
fate_oracle_q() -> ?LET(X, binary(256 div 8), return(aeb_fate_data:make_oracle_query(X))).
|
||||||
fate_oracle_q() -> {call, aeb_fate_data, make_oracle_query, [non_zero_binary(256 div 8)]}.
|
fate_name() -> ?LET(X, binary(256 div 8), return(aeb_fate_data:make_name(X))).
|
||||||
fate_name() -> {call, aeb_fate_data, make_name, [non_zero_binary(256 div 8)]}.
|
fate_channel() -> ?LET(X, binary(256 div 8), return(aeb_fate_data:make_channel(X))).
|
||||||
fate_channel() -> {call, aeb_fate_data, make_channel, [non_zero_binary(256 div 8)]}.
|
|
||||||
|
fate_values(Size, N, Options) ->
|
||||||
|
eqc_gen:list(N, fate_data(Size div max(1, N), Options)).
|
||||||
|
|
||||||
%% May shrink to fate_unit
|
%% May shrink to fate_unit
|
||||||
fate_tuple(ListGen) ->
|
fate_tuple(Size, Options) ->
|
||||||
{call, aeb_fate_data, make_tuple, [?LET(Elements, ListGen, list_to_tuple(Elements))]}.
|
?LET(N, choose(0, 6),
|
||||||
|
?LETSHRINK(Elements, fate_values(Size, N, Options),
|
||||||
|
return(aeb_fate_data:make_tuple(list_to_tuple(Elements))))).
|
||||||
|
|
||||||
fate_variant(ListGen) ->
|
fate_variant(Size, Options) ->
|
||||||
?LET({L1, L2, TupleAsList}, {list(choose(0, 255)), list(choose(0,255)), ListGen},
|
?LET({L1, L2, {tuple, Args}}, {list(choose(0, 255)), list(choose(0,255)), fate_tuple(Size, Options)},
|
||||||
{call, aeb_fate_data, make_variant,
|
return(aeb_fate_data:make_variant(L1 ++ [tuple_size(Args)] ++ L2,
|
||||||
[L1 ++ [length(TupleAsList)] ++ L2, length(L1), list_to_tuple(TupleAsList)]}).
|
length(L1), Args))).
|
||||||
|
|
||||||
fate_list(Gen) ->
|
fate_list(Size, Options) ->
|
||||||
{call, aeb_fate_data, make_list, [frequency([{20, list(Gen)}, {1, ?LET(N, choose(64-3, 64+3), vector(N, Gen))}])]}.
|
?LET(N, frequency([{20, choose(0, 6)}, {1, choose(64 - 3, 64 + 3)}]),
|
||||||
|
?LETSHRINK(Vs, fate_values(Size, N, Options),
|
||||||
|
return(aeb_fate_data:make_list(Vs)))).
|
||||||
|
|
||||||
fate_map(KeyGen, ValGen) ->
|
fate_map(Size, Options) ->
|
||||||
{call, aeb_fate_data, make_map, [map(KeyGen, ValGen)]}.
|
?LET(N, choose(0, 6),
|
||||||
|
?LETSHRINK(Values, fate_values(Size, N, Options),
|
||||||
|
?LET(Keys, vector(length(Values), fate_data(Size div max(1, N * 2), Options -- [map])),
|
||||||
non_zero_binary(N) ->
|
return(aeb_fate_data:make_map(maps:from_list(lists:zip(Keys, Values))))))).
|
||||||
Bits = N*8,
|
|
||||||
?SUCHTHAT(Bin, binary(N), begin <<V:Bits>> = Bin, V =/= 0 end).
|
|
||||||
|
|
||||||
non_quote_string() ->
|
non_quote_string() ->
|
||||||
?SUCHTHAT(S, utf8(), [ quote || <<34>> <= S ] == []).
|
?SUCHTHAT(S, utf8(), [ quote || <<34>> <= S ] == []).
|
||||||
|
@ -11,9 +11,12 @@
|
|||||||
|
|
||||||
-compile([export_all, nowarn_export_all]).
|
-compile([export_all, nowarn_export_all]).
|
||||||
|
|
||||||
|
kind(X) when is_atom(X) -> X;
|
||||||
|
kind(T) when is_tuple(T) -> element(1, T).
|
||||||
|
|
||||||
prop_roundtrip() ->
|
prop_roundtrip() ->
|
||||||
?FORALL(FateType, fate_type(),
|
?FORALL(FateType, fate_type(),
|
||||||
collect(FateType,
|
collect(kind(FateType),
|
||||||
begin
|
begin
|
||||||
Serialized = aeb_fate_encoding:serialize_type(FateType),
|
Serialized = aeb_fate_encoding:serialize_type(FateType),
|
||||||
BinSerialized = list_to_binary(Serialized),
|
BinSerialized = list_to_binary(Serialized),
|
||||||
@ -32,8 +35,7 @@ fate_type(0) ->
|
|||||||
oneof([integer,
|
oneof([integer,
|
||||||
boolean,
|
boolean,
|
||||||
address,
|
address,
|
||||||
hash,
|
{bytes, nat()},
|
||||||
signature,
|
|
||||||
contract,
|
contract,
|
||||||
oracle,
|
oracle,
|
||||||
name,
|
name,
|
||||||
@ -41,9 +43,15 @@ fate_type(0) ->
|
|||||||
bits,
|
bits,
|
||||||
string]);
|
string]);
|
||||||
fate_type(Size) ->
|
fate_type(Size) ->
|
||||||
oneof([?LAZY(fate_type(Size div 2)),
|
?LAZY(
|
||||||
{list, ?LAZY(fate_type(Size div 2))},
|
oneof([fate_type(0),
|
||||||
{tuple, list(?LAZY(fate_type(Size div 2)))},
|
{list, fate_type(Size div 2)},
|
||||||
{variant, list(?LAZY(fate_type(Size div 2)))},
|
?LETSHRINK(Ts, fate_types(Size), {tuple, Ts}),
|
||||||
?LETSHRINK([T1, T2], [?LAZY(fate_type(Size div 2)), ?LAZY(fate_type(Size div 2))],
|
?LETSHRINK(Ts, fate_types(Size), {variant, Ts}),
|
||||||
{map, T1, T2})]).
|
?LETSHRINK([T1, T2], vector(2, fate_type(Size div 2)),
|
||||||
|
{map, T1, T2})])).
|
||||||
|
|
||||||
|
fate_types(Size) ->
|
||||||
|
?LET(N, choose(0, 6),
|
||||||
|
eqc_gen:list(N, fate_type(Size div max(2, N)))).
|
||||||
|
|
||||||
|
@ -282,15 +282,10 @@ to_bytecode([{object,_line, {channel, Value}}|Rest],
|
|||||||
to_bytecode(Rest, Address, Env,
|
to_bytecode(Rest, Address, Env,
|
||||||
[{immediate, aeb_fate_data:make_contract(Value)}|Code],
|
[{immediate, aeb_fate_data:make_contract(Value)}|Code],
|
||||||
Opts);
|
Opts);
|
||||||
to_bytecode([{hash,_line, Value}|Rest],
|
to_bytecode([{bytes,_line, Value}|Rest],
|
||||||
Address, Env, Code, Opts) ->
|
Address, Env, Code, Opts) ->
|
||||||
to_bytecode(Rest, Address, Env,
|
to_bytecode(Rest, Address, Env,
|
||||||
[{immediate, aeb_fate_data:make_hash(Value)}|Code],
|
[{immediate, aeb_fate_data:make_bytes(Value)}|Code],
|
||||||
Opts);
|
|
||||||
to_bytecode([{signature,_line, {signature, Value}}|Rest],
|
|
||||||
Address, Env, Code, Opts) ->
|
|
||||||
to_bytecode(Rest, Address, Env,
|
|
||||||
[{immediate, aeb_fate_data:make_signature(Value)}|Code],
|
|
||||||
Opts);
|
Opts);
|
||||||
to_bytecode([{id,_line, ID}|Rest], Address, Env, Code, Opts) ->
|
to_bytecode([{id,_line, ID}|Rest], Address, Env, Code, Opts) ->
|
||||||
{Env2, Id} = insert_symbol(list_to_binary(ID), Env),
|
{Env2, Id} = insert_symbol(list_to_binary(ID), Env),
|
||||||
|
@ -17,8 +17,7 @@ BASE64 = [A-Za-z0-9+/=]
|
|||||||
INT = {DIGIT}+
|
INT = {DIGIT}+
|
||||||
HEX = 0x{HEXDIGIT}+
|
HEX = 0x{HEXDIGIT}+
|
||||||
OBJECT = @[a-z][a-z]_{BASE58}+
|
OBJECT = @[a-z][a-z]_{BASE58}+
|
||||||
HASH = #{BASE64}+
|
BYTES = #{BASE64}+
|
||||||
SIG = \$sg_{BASE58}+
|
|
||||||
WS = [\000-\s]
|
WS = [\000-\s]
|
||||||
ID = {LOWER}[a-zA-Z0-9_]*
|
ID = {LOWER}[a-zA-Z0-9_]*
|
||||||
STRING = "[^"]*"
|
STRING = "[^"]*"
|
||||||
@ -36,10 +35,8 @@ false : {token, {boolean, TokenLine, false}}.
|
|||||||
|
|
||||||
FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}.
|
FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}.
|
||||||
|
|
||||||
{HASH} :
|
{BYTES} :
|
||||||
{token, {hash, TokenLine, parse_hash(TokenChars)}}.
|
{token, {bytes, TokenLine, parse_hash(TokenChars)}}.
|
||||||
{SIG} :
|
|
||||||
{token, {signature, TokenLine, parse_object(TokenChars)}}.
|
|
||||||
{OBJECT} :
|
{OBJECT} :
|
||||||
{token, {object, TokenLine, parse_object(TokenChars)}}.
|
{token, {object, TokenLine, parse_object(TokenChars)}}.
|
||||||
{ID} :
|
{ID} :
|
||||||
|
@ -100,6 +100,7 @@ serialize(#fcode{} = F) ->
|
|||||||
serialize(F, []).
|
serialize(F, []).
|
||||||
|
|
||||||
serialize(#fcode{} = F, Options) ->
|
serialize(#fcode{} = F, Options) ->
|
||||||
|
sanity_check(F),
|
||||||
serialize(F, serialize_functions(F), Options).
|
serialize(F, serialize_functions(F), Options).
|
||||||
|
|
||||||
serialize(#fcode{} = F, Functions, Options) ->
|
serialize(#fcode{} = F, Functions, Options) ->
|
||||||
@ -127,10 +128,8 @@ to_hexstring(ByteList) ->
|
|||||||
serialize_functions(#fcode{ functions = Functions }) ->
|
serialize_functions(#fcode{ functions = Functions }) ->
|
||||||
%% Sort the functions on name to get a canonical serialisation.
|
%% Sort the functions on name to get a canonical serialisation.
|
||||||
iolist_to_binary(
|
iolist_to_binary(
|
||||||
lists:foldr(fun({Id, {Sig, C}}, Acc) when byte_size(Id) == 4 ->
|
lists:foldr(fun({Id, {Sig, C}}, Acc) ->
|
||||||
[[?FUNCTION, Id, serialize_signature(Sig), serialize_bbs(C)] | Acc];
|
[[?FUNCTION, Id, serialize_signature(Sig), serialize_bbs(C)] | Acc]
|
||||||
({Id, _}, _) ->
|
|
||||||
error({illegal_function_id, Id})
|
|
||||||
end, [], lists:sort(maps:to_list(Functions)))).
|
end, [], lists:sort(maps:to_list(Functions)))).
|
||||||
|
|
||||||
serialize_signature({Args, RetType}) ->
|
serialize_signature({Args, RetType}) ->
|
||||||
@ -148,46 +147,70 @@ serialize_bbs(#{} = BBs) ->
|
|||||||
|
|
||||||
serialize_bbs(BBs, N, Acc) ->
|
serialize_bbs(BBs, N, Acc) ->
|
||||||
case maps:get(N, BBs, none) of
|
case maps:get(N, BBs, none) of
|
||||||
none ->
|
none -> lists:reverse(Acc);
|
||||||
%% Assert that the BBs were contiguous
|
BB -> serialize_bbs(BBs, N + 1, [serialize_bb(BB, [])|Acc])
|
||||||
Size = maps:size(BBs),
|
|
||||||
case Size =:= N of
|
|
||||||
true ->
|
|
||||||
lists:reverse(Acc);
|
|
||||||
false ->
|
|
||||||
error({not_contiguous_labels, lists:sort(maps:keys(BBs))})
|
|
||||||
end;
|
|
||||||
[] ->
|
|
||||||
error({empty_code_block, N});
|
|
||||||
BB ->
|
|
||||||
serialize_bbs(BBs, N + 1, [serialize_bb(BB, [])|Acc])
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
serialize_bb([Op], Acc) ->
|
serialize_bb([Op], Acc) ->
|
||||||
lists:reverse([serialize_op(true, Op)|Acc]);
|
lists:reverse([serialize_op(Op)|Acc]);
|
||||||
serialize_bb([Op|Rest], Acc) ->
|
serialize_bb([Op|Rest], Acc) ->
|
||||||
serialize_bb(Rest, [serialize_op(false, Op)|Acc]).
|
serialize_bb(Rest, [serialize_op(Op)|Acc]).
|
||||||
%% serialize_bb([], Acc) ->
|
|
||||||
%% lists:reverse(Acc).
|
|
||||||
|
|
||||||
serialize_op(Kind, Op) ->
|
serialize_op(Op) ->
|
||||||
[Mnemonic|Args] =
|
[Mnemonic|Args] =
|
||||||
case is_tuple(Op) of
|
case is_tuple(Op) of
|
||||||
true -> tuple_to_list(Op);
|
true -> tuple_to_list(Op);
|
||||||
false -> [Op]
|
false -> [Op]
|
||||||
end,
|
end,
|
||||||
safe_serialize(Kind, aeb_fate_opcodes:m_to_op(Mnemonic), Args).
|
[aeb_fate_opcodes:m_to_op(Mnemonic) | serialize_code(Args)].
|
||||||
|
|
||||||
safe_serialize(Last, Op, Args) ->
|
sanity_check(#fcode{ functions = Funs }) ->
|
||||||
|
_ = [ case Def of
|
||||||
|
{_, BBs} when byte_size(Id) == 4 -> sanity_check_bbs(BBs);
|
||||||
|
_ -> error({illegal_function_id, Id})
|
||||||
|
end || {Id, Def} <- maps:to_list(Funs) ],
|
||||||
|
ok.
|
||||||
|
|
||||||
|
sanity_check_bbs(#{} = BBs) ->
|
||||||
|
sanity_check_bbs(BBs, 0).
|
||||||
|
|
||||||
|
sanity_check_bbs(BBs, N) ->
|
||||||
|
case maps:get(N, BBs, none) of
|
||||||
|
none ->
|
||||||
|
%% Assert that the BBs were contiguous
|
||||||
|
case maps:size(BBs) =:= N of
|
||||||
|
true -> ok;
|
||||||
|
false -> error({not_contiguous_labels, lists:sort(maps:keys(BBs))})
|
||||||
|
end;
|
||||||
|
[] ->
|
||||||
|
error({empty_code_block, N});
|
||||||
|
BB ->
|
||||||
|
sanity_check_bb(BB),
|
||||||
|
sanity_check_bbs(BBs, N + 1)
|
||||||
|
end.
|
||||||
|
|
||||||
|
sanity_check_bb([Op]) ->
|
||||||
|
sanity_check_op(true, Op);
|
||||||
|
sanity_check_bb([Op|Rest]) ->
|
||||||
|
sanity_check_op(false, Op),
|
||||||
|
sanity_check_bb(Rest).
|
||||||
|
|
||||||
|
sanity_check_op(IsLast, Op) ->
|
||||||
|
[Mnemonic|Args] =
|
||||||
|
case is_tuple(Op) of
|
||||||
|
true -> tuple_to_list(Op);
|
||||||
|
false -> [Op]
|
||||||
|
end,
|
||||||
|
safe_sanity_check(IsLast, aeb_fate_opcodes:m_to_op(Mnemonic), Args).
|
||||||
|
|
||||||
|
safe_sanity_check(IsLast, Op, Args) ->
|
||||||
case length(Args) == aeb_fate_opcodes:args(Op) of
|
case length(Args) == aeb_fate_opcodes:args(Op) of
|
||||||
true ->
|
true ->
|
||||||
case Last == aeb_fate_opcodes:end_bb(Op) of
|
case IsLast == aeb_fate_opcodes:end_bb(Op) of
|
||||||
true -> [Op|serialize_code(Args)];
|
true -> ok;
|
||||||
false ->
|
false -> error({wrong_opcode_in_bb, Op})
|
||||||
error({wrong_opcode_in_bb, Op})
|
|
||||||
end;
|
end;
|
||||||
false ->
|
false -> error({wrong_nr_args_opcode, Op})
|
||||||
error({wrong_nr_args_opcode, Op})
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
@ -266,10 +289,13 @@ deserialize(Bytes) ->
|
|||||||
, functions => #{}
|
, functions => #{}
|
||||||
, code => #{}
|
, code => #{}
|
||||||
},
|
},
|
||||||
|
Fcode =
|
||||||
#fcode{ functions = deserialize_functions(ByteCode, Env)
|
#fcode{ functions = deserialize_functions(ByteCode, Env)
|
||||||
, annotations = deserialize_annotations(Annotations)
|
, annotations = deserialize_annotations(Annotations)
|
||||||
, symbols = deserialize_symbols(SymbolTable)
|
, symbols = deserialize_symbols(SymbolTable)
|
||||||
}.
|
},
|
||||||
|
sanity_check(Fcode),
|
||||||
|
Fcode.
|
||||||
|
|
||||||
|
|
||||||
deserialize_functions(<<?FUNCTION:8, A, B, C, D, Rest/binary>>,
|
deserialize_functions(<<?FUNCTION:8, A, B, C, D, Rest/binary>>,
|
||||||
|
@ -12,12 +12,12 @@
|
|||||||
-type fate_map() :: ?FATE_MAP_T.
|
-type fate_map() :: ?FATE_MAP_T.
|
||||||
-type fate_string() :: ?FATE_STRING_T.
|
-type fate_string() :: ?FATE_STRING_T.
|
||||||
-type fate_address() :: ?FATE_ADDRESS_T.
|
-type fate_address() :: ?FATE_ADDRESS_T.
|
||||||
-type fate_hash() :: ?FATE_HASH_T.
|
-type fate_hash() :: ?FATE_BYTES_T(32).
|
||||||
|
-type fate_signature() :: ?FATE_BYTES_T(64).
|
||||||
-type fate_contract() :: ?FATE_CONTRACT_T.
|
-type fate_contract() :: ?FATE_CONTRACT_T.
|
||||||
-type fate_oracle() :: ?FATE_ORACLE_T.
|
-type fate_oracle() :: ?FATE_ORACLE_T.
|
||||||
-type fate_name() :: ?FATE_NAME_T.
|
-type fate_name() :: ?FATE_NAME_T.
|
||||||
-type fate_channel() :: ?FATE_CHANNEL_T.
|
-type fate_channel() :: ?FATE_CHANNEL_T.
|
||||||
-type fate_signature() :: ?FATE_SIGNATURE_T.
|
|
||||||
-type fate_variant() :: ?FATE_VARIANT_T.
|
-type fate_variant() :: ?FATE_VARIANT_T.
|
||||||
-type fate_tuple() :: ?FATE_TUPLE_T.
|
-type fate_tuple() :: ?FATE_TUPLE_T.
|
||||||
-type fate_bits() :: ?FATE_BITS_T.
|
-type fate_bits() :: ?FATE_BITS_T.
|
||||||
@ -87,6 +87,7 @@
|
|||||||
, make_string/1
|
, make_string/1
|
||||||
, make_map/1
|
, make_map/1
|
||||||
, make_address/1
|
, make_address/1
|
||||||
|
, make_bytes/1
|
||||||
, make_hash/1
|
, make_hash/1
|
||||||
, make_signature/1
|
, make_signature/1
|
||||||
, make_contract/1
|
, make_contract/1
|
||||||
@ -113,8 +114,9 @@ make_unit() -> ?FATE_UNIT.
|
|||||||
make_tuple(T) -> ?FATE_TUPLE(T).
|
make_tuple(T) -> ?FATE_TUPLE(T).
|
||||||
make_map(M) -> ?MAKE_FATE_MAP(M).
|
make_map(M) -> ?MAKE_FATE_MAP(M).
|
||||||
make_address(X) -> ?FATE_ADDRESS(X).
|
make_address(X) -> ?FATE_ADDRESS(X).
|
||||||
make_hash(X) -> ?FATE_HASH(X).
|
make_bytes(X) -> ?FATE_BYTES(X).
|
||||||
make_signature(X) -> ?FATE_SIGNATURE(X).
|
make_hash(X) -> make_bytes(X).
|
||||||
|
make_signature(X) -> make_bytes(X).
|
||||||
make_contract(X) -> ?FATE_CONTRACT(X).
|
make_contract(X) -> ?FATE_CONTRACT(X).
|
||||||
make_oracle(X) -> ?FATE_ORACLE(X).
|
make_oracle(X) -> ?FATE_ORACLE(X).
|
||||||
make_oracle_query(X) -> ?FATE_ORACLE_Q(X).
|
make_oracle_query(X) -> ?FATE_ORACLE_Q(X).
|
||||||
@ -168,11 +170,9 @@ format(?FATE_VARIANT(Arities, Tag, T)) ->
|
|||||||
" |)"];
|
" |)"];
|
||||||
format(M) when ?IS_FATE_MAP(M) ->
|
format(M) when ?IS_FATE_MAP(M) ->
|
||||||
["{ ", format_kvs(maps:to_list(?FATE_MAP_VALUE(M))), " }"];
|
["{ ", format_kvs(maps:to_list(?FATE_MAP_VALUE(M))), " }"];
|
||||||
format(?FATE_HASH(X)) -> ["#", base64:encode(X)];
|
format(?FATE_BYTES(X)) -> ["#", base64:encode(X)];
|
||||||
format(?FATE_ADDRESS(X)) ->
|
format(?FATE_ADDRESS(X)) ->
|
||||||
["@", aeser_api_encoder:encode(account_pubkey, X)];
|
["@", aeser_api_encoder:encode(account_pubkey, X)];
|
||||||
format(?FATE_SIGNATURE(X)) ->
|
|
||||||
["$", aeser_api_encoder:encode(signature, X)];
|
|
||||||
format(?FATE_CONTRACT(X)) ->
|
format(?FATE_CONTRACT(X)) ->
|
||||||
["@", aeser_api_encoder:encode(contract_pubkey, X)];
|
["@", aeser_api_encoder:encode(contract_pubkey, X)];
|
||||||
format(?FATE_ORACLE(X)) ->
|
format(?FATE_ORACLE(X)) ->
|
||||||
@ -218,8 +218,8 @@ ordinal(T) when ?IS_FATE_CHANNEL(T) -> 3;
|
|||||||
ordinal(T) when ?IS_FATE_CONTRACT(T) -> 4;
|
ordinal(T) when ?IS_FATE_CONTRACT(T) -> 4;
|
||||||
ordinal(T) when ?IS_FATE_NAME(T) -> 5;
|
ordinal(T) when ?IS_FATE_NAME(T) -> 5;
|
||||||
ordinal(T) when ?IS_FATE_ORACLE(T) -> 6;
|
ordinal(T) when ?IS_FATE_ORACLE(T) -> 6;
|
||||||
ordinal(T) when ?IS_FATE_HASH(T) -> 7;
|
ordinal(T) when ?IS_FATE_BYTES(T) -> 7;
|
||||||
ordinal(T) when ?IS_FATE_SIGNATURE(T) -> 8;
|
%% 8;
|
||||||
ordinal(T) when ?IS_FATE_BITS(T) -> 9;
|
ordinal(T) when ?IS_FATE_BITS(T) -> 9;
|
||||||
ordinal(T) when ?IS_FATE_STRING(T) -> 10;
|
ordinal(T) when ?IS_FATE_STRING(T) -> 10;
|
||||||
ordinal(T) when ?IS_FATE_TUPLE(T) -> 11;
|
ordinal(T) when ?IS_FATE_TUPLE(T) -> 11;
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
-define(TYPE_MAP , 2#01100111). %% 0110 0111 | Type | Type
|
-define(TYPE_MAP , 2#01100111). %% 0110 0111 | Type | Type
|
||||||
-define(TYPE_STRING , 2#01110111). %% 0111 0111 - string typedef
|
-define(TYPE_STRING , 2#01110111). %% 0111 0111 - string typedef
|
||||||
-define(TYPE_VARIANT , 2#10000111). %% 1000 0111 | [Arities] | [Type]
|
-define(TYPE_VARIANT , 2#10000111). %% 1000 0111 | [Arities] | [Type]
|
||||||
%% 1001 0111
|
-define(TYPE_BYTES , 2#10010111). %% 1001 0111 - Bytes typedef
|
||||||
%% 1010 0111
|
%% 1010 0111
|
||||||
%% 1011 0111
|
%% 1011 0111
|
||||||
%% 1100 0111
|
%% 1100 0111
|
||||||
@ -108,13 +108,12 @@
|
|||||||
|
|
||||||
%% Object types
|
%% Object types
|
||||||
-define(OTYPE_ADDRESS, 0).
|
-define(OTYPE_ADDRESS, 0).
|
||||||
-define(OTYPE_HASH, 1).
|
-define(OTYPE_BYTES, 1).
|
||||||
-define(OTYPE_SIGNATURE, 2).
|
-define(OTYPE_CONTRACT, 2).
|
||||||
-define(OTYPE_CONTRACT, 3).
|
-define(OTYPE_ORACLE, 3).
|
||||||
-define(OTYPE_ORACLE, 4).
|
-define(OTYPE_ORACLE_Q, 4).
|
||||||
-define(OTYPE_ORACLE_Q, 5).
|
-define(OTYPE_NAME, 5).
|
||||||
-define(OTYPE_NAME, 6).
|
-define(OTYPE_CHANNEL, 6).
|
||||||
-define(OTYPE_CHANNEL, 7).
|
|
||||||
|
|
||||||
-define(IS_TYPE_TAG(X), (X =:= ?TYPE_INTEGER orelse
|
-define(IS_TYPE_TAG(X), (X =:= ?TYPE_INTEGER orelse
|
||||||
X =:= ?TYPE_BOOLEAN orelse
|
X =:= ?TYPE_BOOLEAN orelse
|
||||||
@ -153,12 +152,10 @@ serialize(String) when ?IS_FATE_STRING(String),
|
|||||||
<<?LONG_STRING,
|
<<?LONG_STRING,
|
||||||
(serialize_integer(?FATE_STRING_SIZE(String) - ?SHORT_STRING_SIZE))/binary
|
(serialize_integer(?FATE_STRING_SIZE(String) - ?SHORT_STRING_SIZE))/binary
|
||||||
, Bytes/binary>>;
|
, Bytes/binary>>;
|
||||||
|
serialize(?FATE_BYTES(Bytes)) when is_binary(Bytes) ->
|
||||||
|
<<?OBJECT, ?OTYPE_BYTES, (serialize(?FATE_STRING(Bytes)))/binary>>;
|
||||||
serialize(?FATE_ADDRESS(Address)) when is_binary(Address) ->
|
serialize(?FATE_ADDRESS(Address)) when is_binary(Address) ->
|
||||||
<<?OBJECT, ?OTYPE_ADDRESS, (aeser_rlp:encode(Address))/binary>>;
|
<<?OBJECT, ?OTYPE_ADDRESS, (aeser_rlp:encode(Address))/binary>>;
|
||||||
serialize(?FATE_HASH(Address)) when is_binary(Address) ->
|
|
||||||
<<?OBJECT, ?OTYPE_HASH, (aeser_rlp:encode(Address))/binary>>;
|
|
||||||
serialize(?FATE_SIGNATURE(Address)) when is_binary(Address) ->
|
|
||||||
<<?OBJECT, ?OTYPE_SIGNATURE, (aeser_rlp:encode(Address))/binary>>;
|
|
||||||
serialize(?FATE_CONTRACT(Address)) when is_binary(Address) ->
|
serialize(?FATE_CONTRACT(Address)) when is_binary(Address) ->
|
||||||
<<?OBJECT, ?OTYPE_CONTRACT, (aeser_rlp:encode(Address))/binary>>;
|
<<?OBJECT, ?OTYPE_CONTRACT, (aeser_rlp:encode(Address))/binary>>;
|
||||||
serialize(?FATE_ORACLE(Address)) when is_binary(Address) ->
|
serialize(?FATE_ORACLE(Address)) when is_binary(Address) ->
|
||||||
@ -233,9 +230,9 @@ serialize_type({tuple, Ts}) ->
|
|||||||
N when N =< 255 ->
|
N when N =< 255 ->
|
||||||
[?TYPE_TUPLE, N | [serialize_type(T) || T <- Ts]]
|
[?TYPE_TUPLE, N | [serialize_type(T) || T <- Ts]]
|
||||||
end;
|
end;
|
||||||
|
serialize_type({bytes, N}) when 0 =< N ->
|
||||||
|
[?TYPE_BYTES | binary_to_list(serialize_integer(N))];
|
||||||
serialize_type(address) -> [?TYPE_OBJECT, ?OTYPE_ADDRESS];
|
serialize_type(address) -> [?TYPE_OBJECT, ?OTYPE_ADDRESS];
|
||||||
serialize_type(hash) -> [?TYPE_OBJECT, ?OTYPE_HASH];
|
|
||||||
serialize_type(signature) -> [?TYPE_OBJECT, ?OTYPE_SIGNATURE];
|
|
||||||
serialize_type(contract) -> [?TYPE_OBJECT, ?OTYPE_CONTRACT];
|
serialize_type(contract) -> [?TYPE_OBJECT, ?OTYPE_CONTRACT];
|
||||||
serialize_type(oracle) -> [?TYPE_OBJECT, ?OTYPE_ORACLE];
|
serialize_type(oracle) -> [?TYPE_OBJECT, ?OTYPE_ORACLE];
|
||||||
serialize_type(oracle_query)-> [?TYPE_OBJECT, ?OTYPE_ORACLE_Q];
|
serialize_type(oracle_query)-> [?TYPE_OBJECT, ?OTYPE_ORACLE_Q];
|
||||||
@ -263,11 +260,13 @@ deserialize_type(<<?TYPE_LIST, Rest/binary>>) ->
|
|||||||
deserialize_type(<<?TYPE_TUPLE, N, Rest/binary>>) ->
|
deserialize_type(<<?TYPE_TUPLE, N, Rest/binary>>) ->
|
||||||
{Ts, Rest2} = deserialize_types(N, Rest, []),
|
{Ts, Rest2} = deserialize_types(N, Rest, []),
|
||||||
{{tuple, Ts}, Rest2};
|
{{tuple, Ts}, Rest2};
|
||||||
|
deserialize_type(<<?TYPE_BYTES, Rest/binary>>) ->
|
||||||
|
{N, Rest2} = deserialize_one(Rest),
|
||||||
|
true = is_integer(N) andalso N >= 0,
|
||||||
|
{{bytes, N}, Rest2};
|
||||||
deserialize_type(<<?TYPE_OBJECT, ObjectType, Rest/binary>>) ->
|
deserialize_type(<<?TYPE_OBJECT, ObjectType, Rest/binary>>) ->
|
||||||
case ObjectType of
|
case ObjectType of
|
||||||
?OTYPE_ADDRESS -> {address, Rest};
|
?OTYPE_ADDRESS -> {address, Rest};
|
||||||
?OTYPE_HASH -> {hash, Rest};
|
|
||||||
?OTYPE_SIGNATURE -> {signature, Rest};
|
|
||||||
?OTYPE_CONTRACT -> {contract, Rest};
|
?OTYPE_CONTRACT -> {contract, Rest};
|
||||||
?OTYPE_ORACLE -> {oracle, Rest};
|
?OTYPE_ORACLE -> {oracle, Rest};
|
||||||
?OTYPE_ORACLE_Q -> {oracle_query, Rest};
|
?OTYPE_ORACLE_Q -> {oracle_query, Rest};
|
||||||
@ -382,13 +381,15 @@ deserialize2(<<S:6, ?SHORT_STRING:2, Rest/binary>>) ->
|
|||||||
String = binary:part(Rest, 0, S),
|
String = binary:part(Rest, 0, S),
|
||||||
Rest2 = binary:part(Rest, byte_size(Rest), - (byte_size(Rest) - S)),
|
Rest2 = binary:part(Rest, byte_size(Rest), - (byte_size(Rest) - S)),
|
||||||
{?MAKE_FATE_STRING(String), Rest2};
|
{?MAKE_FATE_STRING(String), Rest2};
|
||||||
|
deserialize2(<<?OBJECT, ?OTYPE_BYTES, Rest/binary>>) ->
|
||||||
|
{String, Rest2} = deserialize_one(Rest),
|
||||||
|
true = ?IS_FATE_STRING(String),
|
||||||
|
{?FATE_BYTES(?FATE_STRING_VALUE(String)), Rest2};
|
||||||
deserialize2(<<?OBJECT, ObjectType, Rest/binary>>) ->
|
deserialize2(<<?OBJECT, ObjectType, Rest/binary>>) ->
|
||||||
{A, Rest2} = aeser_rlp:decode_one(Rest),
|
{A, Rest2} = aeser_rlp:decode_one(Rest),
|
||||||
Val =
|
Val =
|
||||||
case ObjectType of
|
case ObjectType of
|
||||||
?OTYPE_ADDRESS -> ?FATE_ADDRESS(A);
|
?OTYPE_ADDRESS -> ?FATE_ADDRESS(A);
|
||||||
?OTYPE_HASH -> ?FATE_HASH(A);
|
|
||||||
?OTYPE_SIGNATURE -> ?FATE_SIGNATURE(A);
|
|
||||||
?OTYPE_CONTRACT -> ?FATE_CONTRACT(A);
|
?OTYPE_CONTRACT -> ?FATE_CONTRACT(A);
|
||||||
?OTYPE_ORACLE -> ?FATE_ORACLE(A);
|
?OTYPE_ORACLE -> ?FATE_ORACLE(A);
|
||||||
?OTYPE_ORACLE_Q -> ?FATE_ORACLE_Q(A);
|
?OTYPE_ORACLE_Q -> ?FATE_ORACLE_Q(A);
|
||||||
@ -485,7 +486,5 @@ sort(KVList) ->
|
|||||||
|
|
||||||
valid_key_type(K) when ?IS_FATE_MAP(K) ->
|
valid_key_type(K) when ?IS_FATE_MAP(K) ->
|
||||||
error({map_as_key_in_map, K});
|
error({map_as_key_in_map, K});
|
||||||
valid_key_type(K) when ?IS_FATE_VARIANT(K) ->
|
|
||||||
error({variant_as_key_in_map, K});
|
|
||||||
valid_key_type(_K) ->
|
valid_key_type(_K) ->
|
||||||
true.
|
true.
|
||||||
|
@ -161,8 +161,8 @@ ops_defs() ->
|
|||||||
, { 'MAP_TO_LIST', 16#70, false, 3, [a,a], map_to_list, {map}, list, "Arg0 := The tuple list representation of the map Arg1."}
|
, { 'MAP_TO_LIST', 16#70, false, 3, [a,a], map_to_list, {map}, list, "Arg0 := The tuple list representation of the map Arg1."}
|
||||||
, { 'STR_LENGTH', 16#71, false, 3, [a,a], str_length, {string}, integer, "Arg0 := The length of the string Arg1."}
|
, { 'STR_LENGTH', 16#71, false, 3, [a,a], str_length, {string}, integer, "Arg0 := The length of the string Arg1."}
|
||||||
|
|
||||||
, { 'ECVERIFY', 16#72, false, 1300, [a,a,a,a], ecverify, {hash, address, signature}, boolean, "Arg0 := ecverify(Hash, PubKey, Signature)"}
|
, { 'ECVERIFY', 16#72, false, 1300, [a,a,a,a], ecverify, {bytes, address, bytes}, boolean, "Arg0 := ecverify(Hash, PubKey, Signature)"}
|
||||||
, { 'ECVERIFY_SECP256K1', 16#73, false, 1300, [a,a,a,a], ecverify_secp256k1, {hash, signature, signature}, boolean, "Arg0 := ecverify_secp256k1(Hash, PubKey, Signature)"}
|
, { 'ECVERIFY_SECP256K1', 16#73, false, 1300, [a,a,a,a], ecverify_secp256k1, {bytes, bytes, bytes}, boolean, "Arg0 := ecverify_secp256k1(Hash, PubKey, Signature)"}
|
||||||
|
|
||||||
, { 'CONTRACT_TO_ADDRESS', 16#74, false, 3, [a,a], contract_to_address, {contract}, address, "Arg0 := Arg1 - A no-op type conversion"}
|
, { 'CONTRACT_TO_ADDRESS', 16#74, false, 3, [a,a], contract_to_address, {contract}, address, "Arg0 := Arg1 - A no-op type conversion"}
|
||||||
, { 'AUTH_TX_HASH', 16#75, false, 3, [a], auth_tx_hash, {}, variant, "If in GA authentication context return Some(TxHash) otherwise None."}
|
, { 'AUTH_TX_HASH', 16#75, false, 3, [a], auth_tx_hash, {}, variant, "If in GA authentication context return Some(TxHash) otherwise None."}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
;; CONTRACT oracles
|
;; CONTRACT oracles
|
||||||
|
|
||||||
FUNCTION register (address, integer, {variant, [{tuple, [integer]}, {tuple, [integer]}]}) : oracle
|
FUNCTION register (address, integer, {variant, [{tuple, [integer]}, {tuple, [integer]}]}) : oracle
|
||||||
ORACLE_REGISTER a $sg_11111111111111111111111111111111111111111111111111111111111111116oUsJe arg0 arg1 arg2 'string '{variant, [{tuple, []}, {tuple, [integer]}]}
|
ORACLE_REGISTER a #AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== arg0 arg1 arg2 'string '{variant, [{tuple, []}, {tuple, [integer]}]}
|
||||||
RETURN
|
RETURN
|
||||||
|
|
||||||
FUNCTION query (oracle, integer, string) : oracle_query
|
FUNCTION query (oracle, integer, string) : oracle_query
|
||||||
@ -12,11 +12,11 @@ FUNCTION bogus_query () : oracle_query
|
|||||||
RETURNR @oq_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv
|
RETURNR @oq_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv
|
||||||
|
|
||||||
FUNCTION respond (oracle, integer, string) : {tuple, []}
|
FUNCTION respond (oracle, integer, string) : {tuple, []}
|
||||||
ORACLE_RESPOND $sg_11111111111111111111111111111111111111111111111111111111111111116oUsJe arg0 arg1 arg2 'string '{variant, [{tuple, []}, {tuple, [integer]}]}
|
ORACLE_RESPOND #AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== arg0 arg1 arg2 'string '{variant, [{tuple, []}, {tuple, [integer]}]}
|
||||||
RETURNR {}
|
RETURNR {}
|
||||||
|
|
||||||
FUNCTION extend (oracle, {variant, [{tuple, [integer]}, {tuple, [integer]}]}) : {tuple, []}
|
FUNCTION extend (oracle, {variant, [{tuple, [integer]}, {tuple, [integer]}]}) : {tuple, []}
|
||||||
ORACLE_EXTEND $sg_11111111111111111111111111111111111111111111111111111111111111116oUsJe arg0 arg1
|
ORACLE_EXTEND #AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== arg0 arg1
|
||||||
RETURNR {}
|
RETURNR {}
|
||||||
|
|
||||||
FUNCTION get_question (oracle, oracle_query) : string
|
FUNCTION get_question (oracle, oracle_query) : string
|
||||||
|
Loading…
x
Reference in New Issue
Block a user