Skip to content

Commit

Permalink
Merge pull request #2676 from aeternity/PT-167996886-a_proper_ecverify
Browse files Browse the repository at this point in the history
PT-167996886 A proper ecverify
  • Loading branch information
hanssv committed Aug 21, 2019
2 parents 0291f76 + cd1b006 commit 5412325
Show file tree
Hide file tree
Showing 16 changed files with 342 additions and 143 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ smoke-test: docker smoke-test-run

smoke-test-run: KIND=system_test
smoke-test-run: internal-build
@$(REBAR) as $(KIND) do ct $(ST_CT_DIR) $(ST_CT_FLAGS) --suite=aest_sync_SUITE,aest_commands_SUITE,aest_peers_SUITE
@$(REBAR) as $(KIND),test do upgrade, ct $(ST_CT_DIR) $(ST_CT_FLAGS) --suite=aest_sync_SUITE,aest_commands_SUITE,aest_peers_SUITE

system-smoke-test-deps:
$(MAKE) docker
Expand Down
110 changes: 61 additions & 49 deletions apps/aecontract/test/aecontract_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -4449,6 +4449,40 @@ sophia_crypto(_Cfg) ->
?call(create_contract, Acc, crypto, {})
end,

%% Test hash functions
String = <<"12345678901234567890123456789012-andsomemore">>,
Data = [{none, <<"foo">>}, {{some, 100432}, String}],
Bin = ?IF_AEVM(aeb_heap:to_binary(Data),
aeb_fate_encoding:serialize(aefate_test_utils:encode(Data))),
<<Sha3_N:256>> = Sha3 = aec_hash:hash(evm, Bin),
<<Sha256_N:256>> = Sha256 = aec_hash:sha256_hash(Bin),
<<Blake2b_N:256>> = Blake2b = aec_hash:blake2b_256_hash(Bin),
<<Sha3_S_N:256>> = Sha3_S = aec_hash:hash(evm, String),
<<Sha256_S_N:256>> = Sha256_S = aec_hash:sha256_hash(String),
<<Blake2b_S_N:256>> = Blake2b_S = aec_hash:blake2b_256_hash(String),

ResSha3_S = ?call(call_contract, Acc, IdC, sha3_str, word, String),
ResSha256_S = ?call(call_contract, Acc, IdC, sha256_str, word, String),
ResBlake2b_S = ?call(call_contract, Acc, IdC, blake2b_str, word, String),
ResSha3 = ?call(call_contract, Acc, IdC, sha3, word, Data ),
ResSha256 = ?call(call_contract, Acc, IdC, sha256, word, Data ),
ResBlake2b = ?call(call_contract, Acc, IdC, blake2b, word, Data ),

?assertMatchAEVM (Sha3_S_N , ResSha3_S),
?assertMatchAEVM1OOG(Sha256_S_N , ResSha256_S),
?assertMatchAEVM1OOG(Blake2b_S_N, ResBlake2b_S),
?assertMatchAEVM1OOG(Sha3_N , ResSha3),
?assertMatchAEVM1OOG(Sha256_N , ResSha256),
?assertMatchAEVM1OOG(Blake2b_N , ResBlake2b),

?assertMatchFATE({bytes, Sha3_S}, ResSha3_S),
?assertMatchFATE({bytes, Sha256_S}, ResSha256_S),
?assertMatchFATE({bytes, Blake2b_S}, ResBlake2b_S),
?assertMatchFATE({bytes, Sha3}, ResSha3),
?assertMatchFATE({bytes, Sha256}, ResSha256),
?assertMatchFATE({bytes, Blake2b}, ResBlake2b),

%% Test plain signature verification.
Message = <<"The secret message">>,
MsgHash = aec_hash:hash(evm, Message),
PubKey = Acc,
Expand All @@ -4464,7 +4498,7 @@ sophia_crypto(_Cfg) ->
, {test_string_verify, Message, true}
, {test_string_verify, <<"Not the secret message">>, false}] ],

%% SECP256K1
%% SECP256K1 signature verification
{SECP_Pub0, SECP_Priv} = crypto:generate_key(ecdh, secp256k1),
SECP_Pub = aeu_crypto:ecdsa_from_der_pk(SECP_Pub0),
SECP_Der_Sig = crypto:sign(ecdsa, sha256, {digest, MsgHash}, [SECP_Priv, secp256k1]),
Expand All @@ -4479,80 +4513,58 @@ sophia_crypto(_Cfg) ->
, {test_string_verify_secp256k1, Message, true}
, {test_string_verify_secp256k1, <<"Not the secret message">>, false}] ],

?skipRest(sophia_version() =< ?SOPHIA_FORTUNA, ecrecover_not_in_fortuna),
?skipRest(sophia_version() =< ?SOPHIA_FORTUNA, ecrecover_not_pre_lima),

%% Test ecrecover

%% Static examples are taken from
%% https://github.com/aeternity/parity-ethereum/blob/master/ethcore/builtin/src/lib.rs#L656

GoodHexSig1 = "47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03",
GoodHexAcc1 = "000000000000000000000000c08b5542d177ac6686946920409741463a15dddb",
BadHexSig = "47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001a650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03",
BadHexAcc = "0000000000000000000000000000000000000000000000000000000000000000",
GoodHexAcc1 = "c08b5542d177ac6686946920409741463a15dddb",
BadHexSig = "47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001a650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03",
<<GoodMsg1:32/binary, _:31/binary, GoodSig1_v:65/binary>> = aeu_hex:hex_to_bin(GoodHexSig1),
<<BadMsg:32/binary, _:31/binary, BadSig:65/binary>> = aeu_hex:hex_to_bin(BadHexSig),
<<_:1/binary, GoodSig:64/binary>> = GoodSig1_v,
GoodPubHash = aeu_crypto:ecrecover(secp256k1, GoodMsg1, GoodSig1_v),
{ok, GoodPubHash} = aeu_crypto:ecrecover(secp256k1, GoodMsg1, GoodSig1_v),
GoodSig1_v2 = aeu_crypto:ecdsa_recoverable_from_ecdsa(GoodMsg1, GoodSig, GoodPubHash),

%% Static example pre-generated via JS
GoodSig2_v = aeu_hex:hex_to_bin("1cfab9762e816133bae486b7396dced722a7315a42e90f17d31e191d5e36bbf46210a7b86c915beea013660252366808a88cfdb58b3ef7e13f64e99588628229cc"),
GoodHexAcc2 = "0000000000000000000000000dED50440139Bb2a3C4240286A85df3baC17EBfc",
GoodHexAcc2 = "0dED50440139Bb2a3C4240286A85df3baC17EBfc",
GoodMsg2 = aeu_hex:hex_to_bin("38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e"),

%% Dynamic example

SECP_Pub_Hash0 = sha3:hash(256, SECP_Pub),
SECP_Pub_Hash0_Tail = binary:part(SECP_Pub_Hash0, byte_size(SECP_Pub_Hash0), -20),
SECP_Pub_Hash = << 0:(8*12), SECP_Pub_Hash0_Tail/binary >>,
SECP_Pub_Hash = binary:part(SECP_Pub_Hash0, byte_size(SECP_Pub_Hash0), -20),
SECP_Sig_v = aeu_crypto:ecdsa_recoverable_from_ecdsa(MsgHash, aeu_crypto:ecdsa_from_der_sig(SECP_Der_Sig),
SECP_Pub_Hash),

FixRes = fun({some, Word}) when is_integer(Word) ->
<<Bytes:20/binary, _/binary>> = <<Word:32/unit:8>>,
{some, {bytes, Bytes}};
(Res) -> Res end,
[ begin
TestRes = ?call(call_contract, Acc, IdC, Fun, word, {Msg, Sig}),
?assertMatchAEVM2OOG(Exp, <<TestRes:256>>),
?assertMatchFATE({bytes, Exp}, TestRes)
TestRes = FixRes(?call(call_contract, Acc, IdC, Fun, {option, word}, {Msg, Sig})),
?assertMatchAEVM(Exp, TestRes),
?assertMatchFATE(Exp, TestRes)
end || {Fun, Msg, Sig, Exp} <-
[ {test_recover_secp256k1, ?hsh(GoodMsg1), {bytes, GoodSig1_v}, aeu_hex:hex_to_bin(GoodHexAcc1)}
, {test_recover_secp256k1, ?hsh(BadMsg), {bytes, BadSig}, aeu_hex:hex_to_bin(BadHexAcc)}
, {test_recover_secp256k1, ?hsh(GoodMsg1), {bytes, GoodSig1_v2}, aeu_hex:hex_to_bin(GoodHexAcc1)}
, {test_recover_secp256k1, ?hsh(MsgHash), {bytes, SECP_Sig_v}, SECP_Pub_Hash}
, {test_recover_secp256k1, ?hsh(GoodMsg2), {bytes, GoodSig2_v}, aeu_hex:hex_to_bin(GoodHexAcc2)}
[ {test_recover_secp256k1, ?hsh(GoodMsg1), {bytes, GoodSig1_v}, {some, {bytes, aeu_hex:hex_to_bin(GoodHexAcc1)}}}
, {test_recover_secp256k1, ?hsh(BadMsg), {bytes, BadSig}, none}
, {test_recover_secp256k1, ?hsh(GoodMsg1), {bytes, GoodSig1_v2}, {some, {bytes, aeu_hex:hex_to_bin(GoodHexAcc1)}}}
, {test_recover_secp256k1, ?hsh(MsgHash), {bytes, SECP_Sig_v}, {some, {bytes, SECP_Pub_Hash}}}
, {test_recover_secp256k1, ?hsh(GoodMsg2), {bytes, GoodSig2_v}, {some, {bytes, aeu_hex:hex_to_bin(GoodHexAcc2)}}}
] ],

%% Test hash functions
String = <<"12345678901234567890123456789012-andsomemore">>,
Data = [{none, <<"foo">>}, {{some, 100432}, String}],
Bin = ?IF_AEVM(aeb_heap:to_binary(Data),
aeb_fate_encoding:serialize(aefate_test_utils:encode(Data))),
<<Sha3_N:256>> = Sha3 = aec_hash:hash(evm, Bin),
<<Sha256_N:256>> = Sha256 = aec_hash:sha256_hash(Bin),
<<Blake2b_N:256>> = Blake2b = aec_hash:blake2b_256_hash(Bin),
<<Sha3_S_N:256>> = Sha3_S = aec_hash:hash(evm, String),
<<Sha256_S_N:256>> = Sha256_S = aec_hash:sha256_hash(String),
<<Blake2b_S_N:256>> = Blake2b_S = aec_hash:blake2b_256_hash(String),

ResSha3_S = ?call(call_contract, Acc, IdC, sha3_str, word, String),
ResSha256_S = ?call(call_contract, Acc, IdC, sha256_str, word, String),
ResBlake2b_S = ?call(call_contract, Acc, IdC, blake2b_str, word, String),
ResSha3 = ?call(call_contract, Acc, IdC, sha3, word, Data ),
ResSha256 = ?call(call_contract, Acc, IdC, sha256, word, Data ),
ResBlake2b = ?call(call_contract, Acc, IdC, blake2b, word, Data ),

?assertMatchAEVM (Sha3_S_N , ResSha3_S),
?assertMatchAEVM1OOG(Sha256_S_N , ResSha256_S),
?assertMatchAEVM1OOG(Blake2b_S_N, ResBlake2b_S),
?assertMatchAEVM1OOG(Sha3_N , ResSha3),
?assertMatchAEVM1OOG(Sha256_N , ResSha256),
?assertMatchAEVM1OOG(Blake2b_N , ResBlake2b),

?assertMatchFATE({bytes, Sha3_S}, ResSha3_S),
?assertMatchFATE({bytes, Sha256_S}, ResSha256_S),
?assertMatchFATE({bytes, Blake2b_S}, ResBlake2b_S),
?assertMatchFATE({bytes, Sha3}, ResSha3),
?assertMatchFATE({bytes, Sha256}, ResSha256),
?assertMatchFATE({bytes, Blake2b}, ResBlake2b),
%% Test ecverify
[ begin
TestRes = ?call(call_contract, Acc, IdC, test_ecverify_secp256k1, bool, {Msg, Addr, Sig}),
?assertEqual(Exp, TestRes)
end || {Msg, Addr, Sig, Exp} <-
[ {?hsh(GoodMsg1), {bytes, GoodPubHash}, {bytes, GoodSig1_v}, true}
, {?hsh(GoodMsg1), {bytes, SECP_Pub_Hash}, {bytes, GoodSig1_v}, false}
, {?hsh(MsgHash), {bytes, SECP_Pub_Hash}, {bytes, SECP_Sig_v}, true} ] ],

ok.

Expand Down
5 changes: 3 additions & 2 deletions apps/aecore/src/aec_governance.erl
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,10 @@ primop_base_gas(?PRIM_CALL_MAP_PUT ) -> 0;
primop_base_gas(?PRIM_CALL_MAP_DELETE ) -> 0;
primop_base_gas(?PRIM_CALL_MAP_SIZE ) -> 0;
primop_base_gas(?PRIM_CALL_MAP_TOLIST ) -> 0;
primop_base_gas(?PRIM_CALL_CRYPTO_ECRECOVER_SECP256K1) -> 1300; %% 700 for call + 1300 = 2000
primop_base_gas(?PRIM_CALL_CRYPTO_ECVERIFY ) -> 1300; %% 700 for call + 1300 = 2000
primop_base_gas(?PRIM_CALL_CRYPTO_VERIFY_SIG ) -> 1300; %% 700 for call + 1300 = 2000
primop_base_gas(?PRIM_CALL_CRYPTO_VERIFY_SIG_SECP256K1 ) -> 1300; %% 700 for call + 1300 = 2000
primop_base_gas(?PRIM_CALL_CRYPTO_ECVERIFY_SECP256K1 ) -> 1300; %% 700 for call + 1300 = 2000
primop_base_gas(?PRIM_CALL_CRYPTO_ECRECOVER_SECP256K1) -> 1300; %% 700 for call + 1300 = 2000
primop_base_gas(?PRIM_CALL_CRYPTO_SHA3 ) -> 30; %% Same as gas cost for SHA3 instruction
primop_base_gas(?PRIM_CALL_CRYPTO_SHA256 ) -> 30;
primop_base_gas(?PRIM_CALL_CRYPTO_BLAKE2B ) -> 30;
Expand Down
32 changes: 22 additions & 10 deletions apps/aefate/src/aefa_fate_op.erl
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@
, aens_update/1
, aens_transfer/5
, aens_revoke/4
, ecverify/5
, verify_sig/5
, verify_sig_secp256k1/5
, ecverify_secp256k1/5
, ecrecover_secp256k1/4
, contract_to_address/3
Expand Down Expand Up @@ -1296,8 +1297,11 @@ delegation_signature_data(Type, {Pubkey, Hash}, Current) when Type =:= aens_clai
Type =:= aens_revoke ->
{<<Pubkey/binary, Hash/binary, Current/binary>>, Pubkey}.

ecverify(Arg0, Arg1, Arg2, Arg3, ES) ->
ter_op(ecverify, {Arg0, Arg1, Arg2, Arg3}, ES).
verify_sig(Arg0, Arg1, Arg2, Arg3, ES) ->
ter_op(verify_sig, {Arg0, Arg1, Arg2, Arg3}, ES).

verify_sig_secp256k1(Arg0, Arg1, Arg2, Arg3, ES) ->
ter_op(verify_sig_secp256k1, {Arg0, Arg1, Arg2, Arg3}, ES).

ecverify_secp256k1(Arg0, Arg1, Arg2, Arg3, ES) ->
ter_op(ecverify_secp256k1, {Arg0, Arg1, Arg2, Arg3}, ES).
Expand Down Expand Up @@ -1606,7 +1610,10 @@ op(bits_difference, A, B)
op(ecrecover_secp256k1, Msg, Sig) when ?IS_FATE_BYTES(32, Msg)
, ?IS_FATE_BYTES(65, Sig) ->
{?FATE_BYTES(Msg1), ?FATE_BYTES(Sig1)} = {Msg, Sig},
?FATE_BYTES(aeu_crypto:ecrecover(secp256k1, Msg1, Sig1)).
case aeu_crypto:ecrecover(secp256k1, Msg1, Sig1) of
false -> aeb_fate_data:make_variant([0, 1], 0, {});
{ok, Addr} -> aeb_fate_data:make_variant([0, 1], 1, {?FATE_BYTES(Addr)})
end.

%% Terinay operations
op(map_update, Map, Key, Value) when ?IS_FATE_MAP(Map),
Expand All @@ -1615,14 +1622,19 @@ op(map_update, Map, Key, Value) when ?IS_FATE_MAP(Map),
aeb_fate_data:make_map(Res);
op(map_update, ?FATE_STORE_MAP(Cache, Id), Key, Value) ->
?FATE_STORE_MAP(Cache#{ Key => Value }, Id);
op(ecverify, Msg, PK, Sig) when ?IS_FATE_BYTES(32, Msg)
, ?IS_FATE_ADDRESS(PK)
, ?IS_FATE_BYTES(64, Sig) ->
op(verify_sig, Msg, PK, Sig) when ?IS_FATE_BYTES(32, Msg)
, ?IS_FATE_ADDRESS(PK)
, ?IS_FATE_BYTES(64, Sig) ->
{?FATE_BYTES(Msg1), ?FATE_ADDRESS(PK1), ?FATE_BYTES(Sig1)} = {Msg, PK, Sig},
aeu_crypto:ecverify(Msg1, PK1, Sig1);
aeu_crypto:verify_sig(Msg1, PK1, Sig1);
op(verify_sig_secp256k1, Msg, PK, Sig) when ?IS_FATE_BYTES(32, Msg)
, ?IS_FATE_BYTES(64, PK)
, ?IS_FATE_BYTES(64, Sig) ->
{?FATE_BYTES(Msg1), ?FATE_BYTES(PK1), ?FATE_BYTES(Sig1)} = {Msg, PK, Sig},
aeu_crypto:verify_sig(secp256k1, Msg1, PK1, Sig1);
op(ecverify_secp256k1, Msg, PK, Sig) when ?IS_FATE_BYTES(32, Msg)
, ?IS_FATE_BYTES(64, PK)
, ?IS_FATE_BYTES(64, Sig) ->
, ?IS_FATE_BYTES(20, PK)
, ?IS_FATE_BYTES(65, Sig) ->
{?FATE_BYTES(Msg1), ?FATE_BYTES(PK1), ?FATE_BYTES(Sig1)} = {Msg, PK, Sig},
aeu_crypto:ecverify(secp256k1, Msg1, PK1, Sig1).

Expand Down
85 changes: 85 additions & 0 deletions apps/aega/test/aega_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
, bitcoin_contract_create/1
, bitcoin_contract_call/1

, ethereum_attach/1
, ethereum_spend_from/1
, ethereum_contract_create/1
, ethereum_contract_call/1

, oracle_register/1
, oracle_query/1
, oracle_query_x2/1
Expand Down Expand Up @@ -97,6 +102,7 @@ groups() ->
[ {aevm, [], [ {group, simple}
, {group, basic}
, {group, bitcoin}
, {group, ethereum}
, {group, oracle}
, {group, channel}
, {group, multi_wrap}
Expand All @@ -105,6 +111,7 @@ groups() ->
, {fate, [], [ {group, simple}
, {group, basic}
, {group, bitcoin}
, {group, ethereum}
, {group, oracle}
, {group, channel}
, {group, multi_wrap}
Expand Down Expand Up @@ -135,6 +142,12 @@ groups() ->
, bitcoin_contract_call
]}

, {ethereum, [], [ ethereum_attach
, ethereum_spend_from
, ethereum_contract_create
, ethereum_contract_call
]}

, {oracle, [], [ oracle_register
, oracle_query
, oracle_query_x2
Expand Down Expand Up @@ -185,6 +198,11 @@ init_per_group(fate, Cfg) ->
[{sophia_version, ?SOPHIA_LIMA_FATE}, {vm_version, ?VM_FATE_SOPHIA_1},
{abi_version, ?ABI_FATE_SOPHIA_1}, {protocol, lima} | Cfg]
end;
init_per_group(ethereum, Cfg) ->
case aect_test_utils:latest_protocol_version() of
Vsn when Vsn < ?LIMA_PROTOCOL_VSN -> {skip, ethereum_style_ecverify_not_pre_lima};
_Vsn -> Cfg
end;
init_per_group(_Grp, Cfg) ->
Cfg.

Expand Down Expand Up @@ -509,6 +527,62 @@ bitcoin_contract_call(_Cfg) ->

ok.

%%%===================================================================
%%% Ethereum GA tests
%%%===================================================================
-define(SECP256K1_ADDR, binary:part(sha3:hash(256, ?SECP256K1_PUB), 32, -20)).
-define(E_OWNER, aega_test_utils:to_hex_lit(20, ?SECP256K1_ADDR)).

ethereum_attach(_Cfg) ->
state(aect_test_utils:new_state()),
Acc1 = ?call(new_account, 1000000000 * aec_test_utils:min_gas_price()),
{ok, _} = ?call(attach, Acc1, "ethereum_auth", "authorize", [?E_OWNER]),
ok.

ethereum_spend_from(_Cfg) ->
state(aect_test_utils:new_state()),
MinGP = aec_test_utils:min_gas_price(),
Acc1 = ?call(new_account, 1000000000 * MinGP),
Acc2 = ?call(new_account, 1000000000 * MinGP),
{ok, _} = ?call(attach, Acc1, "ethereum_auth", "authorize", [?E_OWNER]),

AuthOpts = #{ prep_fun => fun(TxHash) -> ?call(ethereum_auth, Acc1, "1", TxHash) end },
PreBalance = ?call(account_balance, Acc2),
{ok, #{tx_res := ok}} =
?call(ga_spend, Acc1, AuthOpts, Acc2, 500, 20000 * MinGP),
PostBalance = ?call(account_balance, Acc2),
?assertMatch({X, Y} when X + 500 == Y, {PreBalance, PostBalance}),

ok.

ethereum_contract_create(_Cfg) ->
state(aect_test_utils:new_state()),
MinGP = aec_test_utils:min_gas_price(),
Acc1 = ?call(new_account, 1000000000 * MinGP),
{ok, _} = ?call(attach, Acc1, "ethereum_auth", "authorize", [?E_OWNER]),

AuthOpts = #{ prep_fun => fun(TxHash) -> ?call(ethereum_auth, Acc1, "1", TxHash) end },
{ok, #{init_res := ok}} = ?call(ga_create, Acc1, AuthOpts, "identity", []),

ok.

ethereum_contract_call(_Cfg) ->
state(aect_test_utils:new_state()),
MinGP = aec_test_utils:min_gas_price(),
Acc1 = ?call(new_account, 1000000000 * MinGP),
{ok, _} = ?call(attach, Acc1, "ethereum_auth", "authorize", [?E_OWNER]),

AuthOpts = #{ prep_fun => fun(TxHash) -> ?call(ethereum_auth, Acc1, "1", TxHash) end },
{ok, #{init_res := ok, ct_pubkey := Ct}} =
?call(ga_create, Acc1, AuthOpts, "identity", []),

AuthOpts2 = #{ prep_fun => fun(TxHash) -> ?call(ethereum_auth, Acc1, "2", TxHash) end },
{ok, #{call_res := ok, call_val := Val}} =
?call(ga_call, Acc1, AuthOpts2, Ct, "identity", "main", ["42"]),
?assertMatchABI("42", 42, decode_call_result("identity", "main", ok, Val)),

ok.

%%%===================================================================
%%% Oracle GA tests
%%%===================================================================
Expand Down Expand Up @@ -1497,3 +1571,14 @@ bitcoin_auth(_GA, Nonce, TxHash, S) ->
Sig = aega_test_utils:to_hex_lit(64, aeu_crypto:ecdsa_from_der_sig(Sig0)),
{aega_test_utils:make_calldata("bitcoin_auth", "authorize", [Nonce, Sig]), S}.

ethereum_auth(_GA, Nonce, TxHash, S) ->
Val = case abi_version() of
?ABI_AEVM_SOPHIA_1 -> <<32:256, TxHash/binary, (list_to_integer(Nonce)):256>>;
?ABI_FATE_SOPHIA_1 -> aeb_fate_encoding:serialize({tuple, {{bytes, TxHash}, list_to_integer(Nonce)}})
end,
Msg = aec_hash:hash(tx, Val),
Sig0 = crypto:sign(ecdsa, sha256, {digest, Msg}, [?SECP256K1_PRIV, secp256k1]),
Sig1 = aeu_crypto:ecdsa_from_der_sig(Sig0),
Sig2 = aeu_crypto:ecdsa_recoverable_from_ecdsa(Msg, Sig1, ?SECP256K1_ADDR),
Sig = aega_test_utils:to_hex_lit(65, Sig2),
{aega_test_utils:make_calldata("ethereum_auth", "authorize", [Nonce, Sig]), S}.
2 changes: 1 addition & 1 deletion apps/aetx/src/aetx.erl
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ min_fee(#aetx{} = AeTx, Height) ->
-spec min_gas(Tx :: tx(), Height :: aec_blocks:height()) -> Gas :: non_neg_integer().
min_gas(#aetx{ type = Type, size = Size, cb = CB, tx = Tx }, Height) when ?IS_CONTRACT_TX(Type) ->
base_gas(Type, Height, CB:abi_version(Tx)) + size_gas(Size);
min_gas(#aetx{ type = Type, size = Size, cb = CB, tx = Tx }, Height) when ?HAS_GAS_TX(Type) ->
min_gas(#aetx{ type = Type, size = Size }, Height) when ?HAS_GAS_TX(Type) ->
base_gas(Type, Height) + size_gas(Size);
min_gas(#aetx{} = Tx, Height) ->
gas_limit(Tx, Height).
Expand Down

0 comments on commit 5412325

Please sign in to comment.