Skip to content

Commit

Permalink
Load contracts from default directories (#4322)
Browse files Browse the repository at this point in the history
* Check for hyper chain contracts in the default location
  • Loading branch information
mitchelli committed Apr 8, 2024
1 parent 805c662 commit de34e33
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 71 deletions.
99 changes: 39 additions & 60 deletions apps/aecore/src/aec_fork_block_settings.erl
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,11 @@ preset_accounts(Type, Release, ErrorMsg) ->
-spec read_preset(accounts | extra_accounts, aec_hard_forks:protocol_vsn()) ->
{ok, binary()} | {error, {atom(), string()}}.
read_preset(accounts, Release) ->
read_hard_fork_file(Release, <<"accounts_file">>, fun(Protocol) -> read_hard_fork_file(aec_fork_block_settings:accounts_file_name(Protocol)) end);
read_hard_fork_file(Release, <<"accounts_file">>, fun(Protocol) -> read_hard_fork_file(aec_fork_block_settings:accounts_file_name(Protocol)) end, fun() -> {ok, <<"{}">>} end);
read_preset(extra_accounts, Release) ->
read_hard_fork_file(Release, <<"extra_accounts_file">>, fun(Protocol) -> read_hard_fork_file(aec_fork_block_settings:extra_accounts_file_name(Protocol)) end).
read_hard_fork_file(Release, <<"extra_accounts_file">>, fun(Protocol) -> read_hard_fork_file(aec_fork_block_settings:extra_accounts_file_name(Protocol)) end, fun() -> {ok, <<"{}">>} end).

read_hard_fork_file(Protocol, Key, DefaultFun) when is_integer(Protocol) ->
read_hard_fork_file(Protocol, Key, DefaultFun, UndefinedCustomFileFun) when is_integer(Protocol) ->
case aeu_env:config_value([<<"chain">>, <<"hard_forks">>], aecore, hard_forks, undefined) of
undefined ->
DefaultFun(Protocol);
Expand All @@ -178,7 +178,7 @@ read_hard_fork_file(Protocol, Key, DefaultFun) when is_integer(Protocol) ->
case maps:get(Key, Map1, undefined) of
%% Setting files for a height are not mandatory so return empty object, an error will be return if the file name is set but not found
undefined ->
{ok, <<"{}">>};
UndefinedCustomFileFun();
FileName ->
AbsoluteFileName = case filename:pathtype(FileName) of
absolute ->
Expand All @@ -199,11 +199,16 @@ read_hard_fork_file(FileName) ->

-spec preset_contracts(aec_hard_forks:protocol_vsn(), atom()) -> map().
preset_contracts(Release, ErrorMsg) ->
case read_preset_contracts(Release) of
case read_preset_contracts(Release, ErrorMsg) of
{error, {_Err, Msg}} ->
erlang:error({ErrorMsg, Msg});
{ok, JSONData} ->
jsx:decode(JSONData, [return_maps])
try
jsx:decode(JSONData, [return_maps])
catch
error:_ ->
erlang:error(invalid_contracts_json)
end
end.

-spec preset_hardcoded_contracts(aec_hard_forks:protocol_vsn(), atom()) -> list().
Expand Down Expand Up @@ -295,10 +300,9 @@ decode_contract_spec(SpecIn) ->



-spec read_preset_contracts(aec_hard_forks:protocol_vsn()) -> {ok, binary()}| {error, {atom(), string()}}.
read_preset_contracts(Release) ->
%% If the configuration variable is not set return an empty object
read_hard_fork_file(Release, <<"contracts_file">>, fun(_Protocol) -> {ok, <<"{}">>} end).
-spec read_preset_contracts(aec_hard_forks:protocol_vsn(), atom()) -> {ok, binary()}| {error, {atom(), string()}}.
read_preset_contracts(Release, ErrorMsg) ->
read_hard_fork_file(Release, <<"contracts_file">>, fun(Protocol) -> read_hard_fork_file(aec_fork_block_settings:contracts_file_name(Protocol)) end, fun() -> erlang:error({ErrorMsg, "configuration not defined"}) end).

accounts_file_name(Release) ->
case aeu_env:find_config([<<"system">>, <<"custom_prefunded_accs_file">>], [user_config]) of
Expand All @@ -323,28 +327,6 @@ contracts_file_name(Release) ->


-ifdef(TEST).
accounts_json_file() ->
NetworkId = aec_governance:get_network_id(),
ConsensusModule = aec_consensus:get_consensus_module_at_height(0),
case NetworkId of
<<"ae_mainnet">> -> "accounts.json";
<<"ae_uat">> -> "accounts_uat.json";
_ ->
case ConsensusModule:get_type() of
pos ->
NetworkId = aec_governance:get_network_id(),
NetworkIdStr = binary_to_list(NetworkId),
NetworkIdStr ++ "_accounts.json";
pow ->
"accounts_test.json"
end
end.

extra_accounts_json_file() ->
"extra_accounts_test.json".

contracts_json_file() ->
"contracts_test.json".

whitelist_json_file() ->
".block_whitelist.json".
Expand All @@ -353,34 +335,6 @@ pre_iris_map_ordering_file() ->
".pre_iris_map_ordering.json".

-else.
accounts_json_file() ->
ConsensusModule = aec_consensus:get_consensus_module_at_height(0),
NetworkId = aec_governance:get_network_id(),
case ConsensusModule:get_type() of
pos ->
NetworkIdStr = binary_to_list(NetworkId),
NetworkIdStr ++ "_accounts.json";
pow ->
case NetworkId of
<<"ae_mainnet">> -> "accounts.json";
<<"ae_uat">> -> "accounts_uat.json";
_ -> "accounts_test.json"
end
end.

extra_accounts_json_file() ->
case aec_governance:get_network_id() of
<<"ae_mainnet">> -> "extra_accounts.json";
<<"ae_uat">> -> "extra_accounts_uat.json";
_ -> "extra_accounts_test.json"
end.

contracts_json_file() ->
case aec_governance:get_network_id() of
<<"ae_mainnet">> -> "contracts.json";
<<"ae_uat">> -> "contracts_uat.json";
_ -> "contracts_test.json"
end.

whitelist_json_file() ->
case aec_governance:get_network_id() of
Expand All @@ -397,6 +351,31 @@ pre_iris_map_ordering_file() ->
end.
-endif.

accounts_json_file() ->
json_file("accounts").

extra_accounts_json_file() ->
json_file("extra_accounts").

contracts_json_file() ->
json_file("contracts").

json_file(BaseFileName) ->
ConsensusModule = aec_consensus:get_consensus_module_at_height(0),
NetworkId = aec_governance:get_network_id(),
case ConsensusModule:get_type() of
pos ->
NetworkIdStr = binary_to_list(NetworkId),
lists:concat([NetworkIdStr, "_", BaseFileName, ".json"]);
pow ->
case NetworkId of
<<"ae_mainnet">> -> BaseFileName ++ ".json";
<<"ae_uat">> -> BaseFileName ++ "_uat.json";
_ -> BaseFileName ++ "_test.json"
end
end.


hardcoded_basename(ProtocolVsn) ->
case ProtocolVsn of
?ROMA_PROTOCOL_VSN -> ?GENESIS_DIR;
Expand Down
114 changes: 103 additions & 11 deletions apps/aecore/test/aec_fork_block_settings_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,29 @@

genesis_accounts_test_() ->
release_based(?ROOT_DIR ++ "/.genesis",
undefined,
fun ?TEST_MODULE:genesis_accounts/0,
none,
none,
genesis_accounts_file_missing).

minerva_accounts_test_() ->
release_based(?ROOT_DIR ++ "/.minerva",
undefined,
fun ?TEST_MODULE:minerva_accounts/0,
none,
none,
minerva_accounts_file_missing).

fortuna_accounts_test_() ->
release_based(?ROOT_DIR ++ "/.fortuna",
undefined,
fun ?TEST_MODULE:fortuna_accounts/0,
none,
none,
fortuna_accounts_file_missing).

lima_accounts_test_() ->
release_based(?ROOT_DIR ++ "/.lima",
undefined,
fun ?TEST_MODULE:lima_accounts/0,
fun ?TEST_MODULE:lima_contracts/0,
{lima, fun ?TEST_MODULE:lima_contracts/0},
lima_contracts_file_missing,
lima_accounts_file_missing).

Expand All @@ -50,24 +46,54 @@ configurable_accounts_override_test_() ->
%% Test the hard coded accounts are overridden
configurable_accounts(?ROMA_PROTOCOL_VSN, 0).

configurable_accounts_hard_coded_test_() ->
Config = #{integer_to_binary(?IRIS_PROTOCOL_VSN) => 0},

release_based(?ROOT_DIR ++ "/.iris",
Config,
fun() -> ?TEST_MODULE:accounts(?IRIS_PROTOCOL_VSN) end,
{hc, fun() -> ?TEST_MODULE:contracts(?IRIS_PROTOCOL_VSN) end},
contracts_file_missing,
accounts_file_missing).

configurable_accounts_hc_test_() ->
Config = #{integer_to_binary(?IRIS_PROTOCOL_VSN) => 0},

release_based(?ROOT_DIR ++ "/.iris",
Config,
<<"aehc_demo">>,
fun() -> ?TEST_MODULE:accounts(?IRIS_PROTOCOL_VSN) end,
{hc, fun() -> ?TEST_MODULE:contracts(?IRIS_PROTOCOL_VSN) end},
contracts_file_missing,
accounts_file_missing).


configurable_accounts(Protocol, Height) ->
Dir = ?ROOT_DIR ++ "/.configurable",
Config = #{integer_to_binary(Protocol) =>
#{<<"accounts_file">> => accounts_filename(Dir),
<<"contracts_file">> => contracts_filename(Dir),
<<"height">> => Height}},
release_based(Dir,
Config,
fun() -> ?TEST_MODULE:accounts(Protocol) end,
none,
{hc, fun() -> ?TEST_MODULE:contracts(Protocol) end},
contracts_file_missing,
accounts_file_missing).

release_based(Dir, ReadAccountsFun, ReadContractsFun, CMissingErr, AMissingErr) ->
release_based(Dir, undefined, ReadAccountsFun, ReadContractsFun, CMissingErr, AMissingErr).

release_based(Dir, ForkConfig, ReadAccountsFun, ReadContractsFun, CMissingErr, AMissingErr) ->
release_based(Dir, ForkConfig, undefined, ReadAccountsFun, ReadContractsFun, CMissingErr, AMissingErr).

release_based(Dir, ForkConfig, PosNetworkId, ReadAccountsFun, ReadContractsFunAndType, CMissingErr, AMissingErr) ->
{foreach,
fun() ->
file:make_dir(Dir),
meck:new(aeu_env, [passthrough]),
meck:new(aec_consensus, [passthrough]),
meck:new(aec_governance, [passthrough]),
meck:expect(aeu_env, data_dir, fun(aecore) -> ?ROOT_DIR end),
case ForkConfig of
undefined ->
Expand All @@ -77,11 +103,24 @@ release_based(Dir, ForkConfig, ReadAccountsFun, ReadContractsFun, CMissingErr, A
fun([<<"chain">>, <<"hard_forks">>], aecore, hard_forks, _Default) ->
ForkConfig end)
end,
case PosNetworkId of
undefined ->
ok;
_ ->
meck:expect(aec_consensus,get_consensus_module_at_height,
fun(_) ->
aec_consensus_hc end),
meck:expect(aec_governance,get_network_id,
fun() ->
PosNetworkId end)
end,
ok
end,
fun(ok) ->
delete_dir(Dir),
meck:unload(aeu_env),
meck:unload(aec_consensus),
meck:unload(aec_governance),
ok
end,
[ {"Preset accounts parsing: broken file",
Expand Down Expand Up @@ -142,9 +181,9 @@ release_based(Dir, ForkConfig, ReadAccountsFun, ReadContractsFun, CMissingErr, A
ok
end}]
++
case ReadContractsFun =:= none of
true -> [];
false ->
case ReadContractsFunAndType of
none -> [];
{lima, ReadContractsFun} ->
[{"Preset contracts parsing: broken file",
fun() ->
%% empty file
Expand Down Expand Up @@ -188,6 +227,41 @@ release_based(Dir, ForkConfig, ReadAccountsFun, ReadContractsFun, CMissingErr, A
end || S <- ill_formed_contract_specs()],
ok
end}
];
{hc, ReadContractsFun} ->
[{"Preset contracts parsing: broken file",
fun() ->
%% empty file
expect_contracts(Dir, <<"">>),
?assertError(invalid_contracts_json, ReadContractsFun()),
%% broken json
expect_contracts(Dir, <<"{">>),
?assertError(invalid_contracts_json, ReadContractsFun()),
%% not json at all
expect_contracts(Dir, <<"Hejsan svejsan">>),
?assertError(invalid_contracts_json, ReadContractsFun()),
ok
end},
{"Preset contracts parsing: empty object",
fun() ->
expect_contracts(Dir, <<"{}">>),
?assertEqual(#{}, ReadContractsFun()),
expect_contracts(Dir, <<"{ }">>),
?assertEqual(#{}, ReadContractsFun()),
ok
end},
{"Preset contracts parsing: preset contracts file missing",
fun() ->
delete_contracts_file(Dir),
File = contracts_filename(Dir),
case CMissingErr of
undefined ->
?assertEqual([], ReadContractsFun());
_ ->
?assertError({CMissingErr, File}, ReadContractsFun())
end,
okma
end}
]
end
}.
Expand Down Expand Up @@ -225,10 +299,28 @@ delete_dir(Dir) ->
ok = file:del_dir(Dir).

accounts_filename(Dir) ->
Dir ++ "/accounts_test.json".
ConsensusModule = aec_consensus:get_consensus_module_at_height(0),
NetworkId = aec_governance:get_network_id(),
FileName = case ConsensusModule:get_type() of
pos ->
NetworkIdStr = binary_to_list(NetworkId),
NetworkIdStr ++ "_accounts.json";
pow ->
"accounts_test.json"
end,
lists:concat([Dir, "/", FileName]).

contracts_filename(Dir) ->
Dir ++ "/contracts_test.json".
ConsensusModule = aec_consensus:get_consensus_module_at_height(0),
NetworkId = aec_governance:get_network_id(),
FileName = case ConsensusModule:get_type() of
pos ->
NetworkIdStr = binary_to_list(NetworkId),
NetworkIdStr ++ "_contracts.json";
pow ->
"contracts_test.json"
end,
lists:concat([Dir, "/", FileName]).

well_formed_contract_spec() ->
<<"{\"ct_11111111111111111111111111111115rHyByZ\" :
Expand Down

0 comments on commit de34e33

Please sign in to comment.