Compile oracle check functions in FATE backend

This commit is contained in:
Ulf Norell 2019-06-25 11:05:29 +02:00
parent c7a8a4af22
commit a3efaf71a7
3 changed files with 44 additions and 15 deletions

View File

@ -175,11 +175,12 @@ builtins() ->
{["Chain"], [{"spend", 2}, {"balance", 1}, {"block_hash", 1}, {"coinbase", none},
{"timestamp", none}, {"block_height", none}, {"difficulty", none},
{"gas_limit", none}]},
{["Contract"], [{"address", none}, {"balance", none}]},
{["Contract"], [{"address", none}, {"balance", none}, {"creator", none}]},
{["Call"], [{"origin", none}, {"caller", none}, {"value", none}, {"gas_price", none},
{"gas_left", 0}]},
{["Oracle"], [{"register", 4}, {"query_fee", 1}, {"query", 5}, {"get_question", 2},
{"respond", 4}, {"extend", 3}, {"get_answer", 2}]},
{"respond", 4}, {"extend", 3}, {"get_answer", 2},
{"check", 1}, {"check_query", 2}]},
{["AENS"], [{"resolve", 2}, {"preclaim", 3}, {"claim", 4}, {"transfer", 4},
{"revoke", 3}]},
{["Map"], [{"from_list", 1}, {"to_list", 1}, {"lookup", 2},
@ -192,7 +193,7 @@ builtins() ->
{"union", 2}, {"difference", 2}, {"none", none}, {"all", none}]},
{["Bytes"], [{"to_int", 1}, {"to_str", 1}]},
{["Int"], [{"to_str", 1}]},
{["Address"], [{"to_str", 1}]}
{["Address"], [{"to_str", 1}, {"is_oracle", 1}, {"is_contract", 1}]}
],
maps:from_list([ {NS ++ [Fun], {MkName(NS, Fun), Arity}}
|| {NS, Funs} <- Scopes,
@ -475,7 +476,9 @@ expr_to_fcode(Env, Type, {app, _Ann, Fun = {typed, _, _, {fun_t, _, NamedArgsT,
B =:= oracle_get_question;
B =:= oracle_get_answer;
B =:= oracle_respond;
B =:= oracle_register ->
B =:= oracle_register;
B =:= oracle_check;
B =:= oracle_check_query ->
%% Get the type of the oracle from the args or the expression itself
OType = get_oracle_type(B, Type, Args1),
{oracle, QType, RType} = type_to_fcode(Env, OType),
@ -547,10 +550,12 @@ make_if(Cond, Then, Else) ->
get_oracle_type(oracle_register, OType, _Args) -> OType;
get_oracle_type(oracle_query, _Type, [{typed, _,_Expr, OType}|_]) -> OType;
get_oracle_type(oracle_get_question, _Type, [{typed, _,_Expr, OType}|_]) -> OType;
get_oracle_type(oracle_get_answer, _Type, [{typed, _,_Expr, OType}|_]) -> OType;
get_oracle_type(oracle_respond, _Type, [_,{typed, _,_Expr, OType}|_]) -> OType.
get_oracle_type(oracle_query, _Type, [{typed, _, _Expr, OType} | _]) -> OType;
get_oracle_type(oracle_get_question, _Type, [{typed, _, _Expr, OType} | _]) -> OType;
get_oracle_type(oracle_get_answer, _Type, [{typed, _, _Expr, OType} | _]) -> OType;
get_oracle_type(oracle_check, _Type, [{typed, _, _Expr, OType}]) -> OType;
get_oracle_type(oracle_check_query, _Type, [{typed, _, _Expr, OType} | _]) -> OType;
get_oracle_type(oracle_respond, _Type, [_, {typed, _,_Expr, OType} | _]) -> OType.
%% -- Pattern matching --
@ -1261,6 +1266,8 @@ pp_punctuate(Sep, [X | Xs]) -> [pp_beside(X, Sep) | pp_punctuate(Sep, Xs)].
pp_par([]) -> prettypr:empty();
pp_par(Xs) -> prettypr:par(Xs).
pp_fexpr({lit, {typerep, T}}) ->
pp_ftype(T);
pp_fexpr({lit, {Tag, Lit}}) ->
aeso_pretty:expr({Tag, [], Lit});
pp_fexpr(nil) ->
@ -1321,18 +1328,23 @@ pp_fexpr({switch, Split}) -> pp_split(Split).
pp_call(Fun, Args) ->
pp_beside(Fun, pp_fexpr({tuple, Args})).
pp_call_t(Fun, Args) ->
pp_beside(pp_text(Fun), pp_ftype({tuple, Args})).
-spec pp_ftype(ftype()) -> prettypr:doc().
pp_ftype(T) when is_atom(T) -> pp_text(T);
pp_ftype(any) -> pp_text("_");
pp_ftype({tvar, X}) -> pp_text(X);
pp_ftype({bytes, N}) -> pp_text("bytes(" ++ integer_to_list(N) ++ ")");
pp_ftype({bytes, N}) -> pp_call(pp_text("bytes"), [{lit, {int, N}}]);
pp_ftype({oracle, Q, R}) -> pp_call_t("oracle", [Q, R]);
pp_ftype({tuple, Ts}) ->
pp_parens(pp_par(pp_punctuate(pp_text(","), [pp_ftype(T) || T <- Ts])));
pp_ftype({list, T}) ->
pp_beside([pp_text("list("), pp_ftype(T), pp_text(")")]);
pp_call_t("list", [T]);
pp_ftype({function, Args, Res}) ->
pp_par([pp_ftype({tuple, Args}), pp_text("=>"), pp_ftype(Res)]);
pp_ftype({map, Key, Val}) ->
pp_beside([pp_text("map"), pp_ftype({tuple, [Key, Val]})]);
pp_call_t("map", [Key, Val]);
pp_ftype({variant, Cons}) ->
pp_par(
pp_punctuate(pp_text(" |"),

View File

@ -104,6 +104,11 @@
Op =:= 'AUTH_TX_HASH' orelse
Op =:= 'BYTES_TO_INT' orelse
Op =:= 'BYTES_TO_STR' orelse
Op =:= 'ORACLE_CHECK' orelse
Op =:= 'ORACLE_CHECK_QUERY' orelse
Op =:= 'IS_ORACLE' orelse
Op =:= 'IS_CONTRACT' orelse
Op =:= 'CREATOR' orelse
false)).
-record(env, { contract, vars = [], locals = [], tailpos = true }).
@ -499,6 +504,8 @@ builtin_to_scode(_Env, contract_balance, []) ->
[aeb_fate_ops:balance(?a)];
builtin_to_scode(_Env, contract_address, []) ->
[aeb_fate_ops:address(?a)];
builtin_to_scode(_Env, contract_creator, []) ->
[aeb_fate_ops:contract_creator(?a)];
builtin_to_scode(_Env, call_origin, []) ->
[aeb_fate_ops:origin(?a)];
builtin_to_scode(_Env, call_caller, []) ->
@ -525,6 +532,14 @@ builtin_to_scode(Env, oracle_extend, [_Sign, _Oracle, _TTL] = Args) ->
tuple(0)], Args);
builtin_to_scode(Env, oracle_get_answer, [_Oracle, _QueryId, _QType, _RType] = Args) ->
call_to_scode(Env, aeb_fate_ops:oracle_get_answer(?a, ?a, ?a, ?a, ?a), Args);
builtin_to_scode(Env, oracle_check, [_Oracle, _QType, _RType] = Args) ->
call_to_scode(Env, aeb_fate_ops:oracle_check(?a, ?a, ?a, ?a), Args);
builtin_to_scode(Env, oracle_check_query, [_Oracle, _Query, _QType, _RType] = Args) ->
call_to_scode(Env, aeb_fate_ops:oracle_check_query(?a, ?a, ?a, ?a, ?a), Args);
builtin_to_scode(Env, address_is_oracle, [_] = Args) ->
call_to_scode(Env, aeb_fate_ops:is_oracle(?a, ?a), Args);
builtin_to_scode(Env, address_is_contract, [_] = Args) ->
call_to_scode(Env, aeb_fate_ops:is_contract(?a, ?a), Args);
builtin_to_scode(_Env, aens_resolve, [_, _] = _Args) ->
?TODO(fate_aens_resolve_instruction);
builtin_to_scode(_Env, aens_preclaim, [_, _, _] = _Args) ->
@ -810,6 +825,11 @@ attributes(I) ->
{'AUTH_TX_HASH', A} -> Pure(A, []);
{'BYTES_TO_INT', A, B} -> Pure(A, [B]);
{'BYTES_TO_STR', A, B} -> Pure(A, [B]);
{'ORACLE_CHECK', A, B, C, D} -> Impure(A, [B, C, D]);
{'ORACLE_CHECK_QUERY', A, B, C, D, E} -> Impure(A, [B, C, D, E]);
{'IS_ORACLE', A, B} -> Impure(A, [B]);
{'IS_CONTRACT', A, B} -> Impure(A, [B]);
{'CREATOR', A} -> Pure(A, []);
{'ADDRESS', A} -> Pure(A, []);
{'BALANCE', A} -> Impure(A, []);
{'BALANCE_OTHER', A, B} -> Impure(A, [B]);

View File

@ -120,10 +120,7 @@ compilable_contracts() ->
].
not_yet_compilable(fate) ->
["events", %% events
"address_literals", %% oracle_query_id literals
"address_chain" %% Oracle.check_query
];
["events"];
not_yet_compilable(aevm) -> [].
%% Contracts that should produce type errors