Merge pull request #99 from aeternity/PT-166897066-run_http_contracts_on_fate
Pt 166897066 run http contracts on fate
This commit is contained in:
commit
dd5fc17554
@ -11,7 +11,7 @@
|
|||||||
{git,"https://github.com/aeternity/erl-base58.git",
|
{git,"https://github.com/aeternity/erl-base58.git",
|
||||||
{ref,"60a335668a60328a29f9731b67c4a0e9e3d50ab6"}},
|
{ref,"60a335668a60328a29f9731b67c4a0e9e3d50ab6"}},
|
||||||
2},
|
2},
|
||||||
{<<"eblake2">>,{pkg,<<"eblake2">>,<<"1.0.0">>},1},
|
{<<"eblake2">>,{pkg,<<"eblake2">>,<<"1.0.0">>},0},
|
||||||
{<<"getopt">>,{pkg,<<"getopt">>,<<"1.0.1">>},0},
|
{<<"getopt">>,{pkg,<<"getopt">>,<<"1.0.1">>},0},
|
||||||
{<<"jsx">>,
|
{<<"jsx">>,
|
||||||
{git,"https://github.com/talentdeficit/jsx.git",
|
{git,"https://github.com/talentdeficit/jsx.git",
|
||||||
|
@ -136,7 +136,7 @@ on_current_scope(Env = #env{ namespace = NS, scopes = Scopes }, Fun) ->
|
|||||||
Env#env{ scopes = Scopes#{ NS => Fun(Scope) } }.
|
Env#env{ scopes = Scopes#{ NS => Fun(Scope) } }.
|
||||||
|
|
||||||
-spec on_scopes(env(), fun((scope()) -> scope())) -> env().
|
-spec on_scopes(env(), fun((scope()) -> scope())) -> env().
|
||||||
on_scopes(Env = #env{ namespace = NS, scopes = Scopes }, Fun) ->
|
on_scopes(Env = #env{ scopes = Scopes }, Fun) ->
|
||||||
Env#env{ scopes = maps:map(fun(_, Scope) -> Fun(Scope) end, Scopes) }.
|
Env#env{ scopes = maps:map(fun(_, Scope) -> Fun(Scope) end, Scopes) }.
|
||||||
|
|
||||||
-spec bind_var(aeso_syntax:id(), type(), env()) -> env().
|
-spec bind_var(aeso_syntax:id(), type(), env()) -> env().
|
||||||
@ -401,7 +401,7 @@ global_env() ->
|
|||||||
[{"spend", StateFun([Address, Int], Unit)},
|
[{"spend", StateFun([Address, Int], Unit)},
|
||||||
%% Chain environment
|
%% Chain environment
|
||||||
{"balance", Fun1(Address, Int)},
|
{"balance", Fun1(Address, Int)},
|
||||||
{"block_hash", Fun1(Int, Int)},
|
{"block_hash", Fun1(Int, Option(Hash))},
|
||||||
{"coinbase", Address},
|
{"coinbase", Address},
|
||||||
{"timestamp", Int},
|
{"timestamp", Int},
|
||||||
{"block_height", Int},
|
{"block_height", Int},
|
||||||
|
@ -141,7 +141,7 @@ ast_body(?qid_app([Con, "Chain", "event"], [Event], _, _), Icode = #{ contract_n
|
|||||||
ast_body(?qid_app(["Chain", "balance"], [Address], _, _), Icode) ->
|
ast_body(?qid_app(["Chain", "balance"], [Address], _, _), Icode) ->
|
||||||
#prim_balance{ address = ast_body(Address, Icode) };
|
#prim_balance{ address = ast_body(Address, Icode) };
|
||||||
ast_body(?qid_app(["Chain", "block_hash"], [Height], _, _), Icode) ->
|
ast_body(?qid_app(["Chain", "block_hash"], [Height], _, _), Icode) ->
|
||||||
#prim_block_hash{ height = ast_body(Height, Icode) };
|
builtin_call(block_hash, [ast_body(Height, Icode)]);
|
||||||
ast_body(?qid_app(["Call", "gas_left"], [], _, _), _Icode) ->
|
ast_body(?qid_app(["Call", "gas_left"], [], _, _), _Icode) ->
|
||||||
prim_gas_left;
|
prim_gas_left;
|
||||||
ast_body({qid, _, ["Contract", "address"]}, _Icode) -> prim_contract_address;
|
ast_body({qid, _, ["Contract", "address"]}, _Icode) -> prim_contract_address;
|
||||||
|
@ -130,6 +130,7 @@ builtin_function(BF) ->
|
|||||||
case BF of
|
case BF of
|
||||||
{event, EventT} -> bfun(BF, builtin_event(EventT));
|
{event, EventT} -> bfun(BF, builtin_event(EventT));
|
||||||
abort -> bfun(BF, builtin_abort());
|
abort -> bfun(BF, builtin_abort());
|
||||||
|
block_hash -> bfun(BF, builtin_block_hash());
|
||||||
require -> bfun(BF, builtin_require());
|
require -> bfun(BF, builtin_require());
|
||||||
{map_lookup, Type} -> bfun(BF, builtin_map_lookup(Type));
|
{map_lookup, Type} -> bfun(BF, builtin_map_lookup(Type));
|
||||||
map_put -> bfun(BF, builtin_map_put());
|
map_put -> bfun(BF, builtin_map_put());
|
||||||
@ -211,6 +212,12 @@ builtin_abort() ->
|
|||||||
A(?REVERT)]}, %% Stack: 0,Ptr
|
A(?REVERT)]}, %% Stack: 0,Ptr
|
||||||
{tuple,[]}}.
|
{tuple,[]}}.
|
||||||
|
|
||||||
|
builtin_block_hash() ->
|
||||||
|
{[{"height", word}],
|
||||||
|
?LET(hash, #prim_block_hash{ height = ?V(height)},
|
||||||
|
{ifte, ?EQ(hash, 0), option_none(), option_some(?V(hash))}),
|
||||||
|
aeso_icode:option_typerep(word)}.
|
||||||
|
|
||||||
builtin_require() ->
|
builtin_require() ->
|
||||||
{[{"c", word}, {"msg", string}],
|
{[{"c", word}, {"msg", string}],
|
||||||
{ifte, ?V(c), {tuple, []}, ?call(abort, [?V(msg)])},
|
{ifte, ?V(c), {tuple, []}, ?call(abort, [?V(msg)])},
|
||||||
|
@ -288,25 +288,40 @@ to_sophia_value(_, _, revert, Data, _Options) ->
|
|||||||
end;
|
end;
|
||||||
to_sophia_value(ContractString, FunName, ok, Data, Options) ->
|
to_sophia_value(ContractString, FunName, ok, Data, Options) ->
|
||||||
try
|
try
|
||||||
#{ typed_ast := TypedAst,
|
Code = string_to_code(ContractString, Options),
|
||||||
type_env := TypeEnv,
|
#{ typed_ast := TypedAst, type_env := TypeEnv} = Code,
|
||||||
icode := Icode } = string_to_code(ContractString, Options),
|
|
||||||
{ok, _, Type0} = get_decode_type(FunName, TypedAst),
|
{ok, _, Type0} = get_decode_type(FunName, TypedAst),
|
||||||
Type = aeso_ast_infer_types:unfold_types_in_type(TypeEnv, Type0, [unfold_record_types, unfold_variant_types]),
|
Type = aeso_ast_infer_types:unfold_types_in_type(TypeEnv, Type0, [unfold_record_types, unfold_variant_types]),
|
||||||
VmType = aeso_ast_to_icode:ast_typerep(Type, Icode),
|
|
||||||
case aeb_heap:from_binary(VmType, Data) of
|
case proplists:get_value(backend, Options, aevm) of
|
||||||
{ok, VmValue} ->
|
aevm ->
|
||||||
try
|
Icode = maps:get(icode, Code),
|
||||||
{ok, aeso_vm_decode:from_aevm(VmType, Type, VmValue)}
|
VmType = aeso_ast_to_icode:ast_typerep(Type, Icode),
|
||||||
catch throw:cannot_translate_to_sophia ->
|
case aeb_heap:from_binary(VmType, Data) of
|
||||||
Type0Str = prettypr:format(aeso_pretty:type(Type0)),
|
{ok, VmValue} ->
|
||||||
{error, join_errors("Translation error", [lists:flatten(io_lib:format("Cannot translate VM value ~p\n of type ~p\n to Sophia type ~s\n",
|
try
|
||||||
[Data, VmType, Type0Str]))],
|
{ok, aeso_vm_decode:from_aevm(VmType, Type, VmValue)}
|
||||||
fun (E) -> E end)}
|
catch throw:cannot_translate_to_sophia ->
|
||||||
|
Type0Str = prettypr:format(aeso_pretty:type(Type0)),
|
||||||
|
{error, join_errors("Translation error", [lists:flatten(io_lib:format("Cannot translate VM value ~p\n of type ~p\n to Sophia type ~s\n",
|
||||||
|
[Data, VmType, Type0Str]))],
|
||||||
|
fun (E) -> E end)}
|
||||||
|
end;
|
||||||
|
{error, _Err} ->
|
||||||
|
{error, join_errors("Decode errors", [lists:flatten(io_lib:format("Failed to decode binary at type ~p", [VmType]))],
|
||||||
|
fun(E) -> E end)}
|
||||||
end;
|
end;
|
||||||
{error, _Err} ->
|
fate ->
|
||||||
{error, join_errors("Decode errors", [lists:flatten(io_lib:format("Failed to decode binary at type ~p", [VmType]))],
|
try
|
||||||
fun(E) -> E end)}
|
{ok, aeso_vm_decode:from_fate(Type, aeb_fate_encoding:deserialize(Data))}
|
||||||
|
catch throw:cannot_translate_to_sophia ->
|
||||||
|
{error, join_errors("Translation error",
|
||||||
|
[lists:flatten(io_lib:format("Cannot translate fate value ~p\n of Sophia type ~s\n",
|
||||||
|
[aeb_fate_encoding:deserialize(Data), Type]))],
|
||||||
|
fun (E) -> E end)};
|
||||||
|
_:R ->
|
||||||
|
{error, iolist_to_binary(io_lib:format("Decode error ~p: ~p\n", [R, erlang:get_stacktrace()]))}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
catch
|
catch
|
||||||
error:{parse_errors, Errors} ->
|
error:{parse_errors, Errors} ->
|
||||||
|
@ -50,7 +50,7 @@ contract Environment =
|
|||||||
function get_balance(acct : address) : int = Chain.balance(acct)
|
function get_balance(acct : address) : int = Chain.balance(acct)
|
||||||
|
|
||||||
// Block hash
|
// Block hash
|
||||||
function block_hash(height : int) : int = Chain.block_hash(height)
|
function block_hash(height : int) : option(hash) = Chain.block_hash(height)
|
||||||
|
|
||||||
// Coinbase
|
// Coinbase
|
||||||
function coinbase() : address = Chain.coinbase
|
function coinbase() : address = Chain.coinbase
|
||||||
|
Loading…
x
Reference in New Issue
Block a user