get rid of byte code argument to create_calldata

This means that there is less type checking at calldata creation time.
Make sure that we check that the function hash exists before calling
a contract!
This commit is contained in:
Ulf Norell 2019-02-26 17:31:53 +01:00
parent 5a4a84805f
commit e0fff00e64
2 changed files with 11 additions and 42 deletions

View File

@ -11,7 +11,7 @@
-define(HASH_SIZE, 32). -define(HASH_SIZE, 32).
-export([ old_create_calldata/3 -export([ old_create_calldata/3
, create_calldata/5 , create_calldata/4
, check_calldata/2 , check_calldata/2
, function_type_info/3 , function_type_info/3
, function_type_hash/3 , function_type_hash/3
@ -39,22 +39,11 @@
%%%=================================================================== %%%===================================================================
%%% Handle calldata %%% Handle calldata
create_calldata(Contract, FunName, Args, ArgTypes, RetType) -> create_calldata(FunName, Args, ArgTypes, RetType) ->
case get_type_info_and_hash(Contract, FunName) of <<TypeHashInt:?HASH_SIZE/unit:8>> =
{ok, TypeInfo, TypeHashInt} -> function_type_hash(list_to_binary(FunName), ArgTypes, RetType),
Data = aeso_heap:to_binary({TypeHashInt, list_to_tuple(Args)}), Data = aeso_heap:to_binary({TypeHashInt, list_to_tuple(Args)}),
case check_calldata(Data, TypeInfo) of {ok, Data, {tuple, [word, {tuple, ArgTypes}]}, RetType}.
{ok, CallDataType, OutType} ->
case check_given_type(FunName, ArgTypes, RetType, CallDataType, OutType) of
ok ->
{ok, Data, CallDataType, OutType};
{error, _} = Err ->
Err
end;
{error,_What} = Err -> Err
end;
{error, _} = Err -> Err
end.
get_type_info_and_hash(#{type_info := TypeInfo}, FunName) -> get_type_info_and_hash(#{type_info := TypeInfo}, FunName) ->
FunBin = list_to_binary(FunName), FunBin = list_to_binary(FunName),
@ -64,26 +53,6 @@ get_type_info_and_hash(#{type_info := TypeInfo}, FunName) ->
{error, _} = Err -> Err {error, _} = Err -> Err
end. end.
%% Check that the given type matches the type from the metadata.
check_given_type(FunName, GivenArgs, GivenRet, CalldataType, ExpectRet) ->
{tuple, [word, {tuple, ExpectArgs}]} = CalldataType,
ReturnOk = if FunName == "init" -> true;
GivenRet == any -> true;
true -> GivenRet == ExpectRet
end,
ArgsOk = ExpectArgs == GivenArgs,
case ReturnOk andalso ArgsOk of
true -> ok;
false when FunName == "init" ->
{error, {init_args_mismatch,
{given, GivenArgs},
{expected, ExpectArgs}}};
false ->
{error, {call_type_mismatch,
{given, GivenArgs, '=>', GivenRet},
{expected, ExpectArgs, '=>', ExpectRet}}}
end.
-spec check_calldata(binary(), type_info()) -> -spec check_calldata(binary(), type_info()) ->
{'ok', typerep(), typerep()} | {'error', atom()}. {'ok', typerep(), typerep()} | {'error', atom()}.
check_calldata(CallData, TypeInfo) -> check_calldata(CallData, TypeInfo) ->

View File

@ -12,7 +12,7 @@
, file/2 , file/2
, from_string/2 , from_string/2
, check_call/4 , check_call/4
, create_calldata/4 , create_calldata/3
, version/0 , version/0
, sophia_type_to_typerep/1 , sophia_type_to_typerep/1
, to_sophia_value/4 , to_sophia_value/4
@ -271,13 +271,13 @@ translate_vm_value(VmTypes, {constr_t, _, Con, Types}, Args)
translate_vm_value(_VmType, _Type, _Data) -> translate_vm_value(_VmType, _Type, _Data) ->
throw(cannot_translate_to_sophia). throw(cannot_translate_to_sophia).
-spec create_calldata(map(), string(), string(), [string()]) -> -spec create_calldata(string(), string(), [string()]) ->
{ok, binary(), aeso_sophia:type(), aeso_sophia:type()} {ok, binary(), aeso_sophia:type(), aeso_sophia:type()}
| {error, argument_syntax_error}. | {error, argument_syntax_error}.
create_calldata(Contract, Code, Fun, Args) when is_map(Contract) -> create_calldata(Code, Fun, Args) ->
case check_call(Code, Fun, Args, []) of case check_call(Code, Fun, Args, []) of
{ok, FunName, {ArgTypes, RetType}, Args} -> {ok, FunName, {ArgTypes, RetType}, VMArgs} ->
aeso_abi:create_calldata(Contract, FunName, Args, ArgTypes, RetType); aeso_abi:create_calldata(FunName, VMArgs, ArgTypes, RetType);
{error, _} = Err -> Err {error, _} = Err -> Err
end. end.