diff --git a/rebar.lock b/rebar.lock index b6a7bc644..ea28f1333 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,7 +3,7 @@ {<<"base32">>,{pkg,<<"base32">>,<<"0.1.0">>},3}, {<<"blockchain">>, {git,"git@github.com:helium/blockchain-core.git", - {ref,"b0bd97938ae06fe8915c207cc5352f6bbae1d5f6"}}, + {ref,"898acb718cbec21be43982143c4925d3edf4ff76"}}, 0}, {<<"clique">>, {git,"https://github.com/helium/clique.git", diff --git a/src/cli/miner_cli_genesis.erl b/src/cli/miner_cli_genesis.erl index 96442070b..f50ce5783 100644 --- a/src/cli/miner_cli_genesis.erl +++ b/src/cli/miner_cli_genesis.erl @@ -97,8 +97,8 @@ create(OldGenesisFile, PubKeyB58, ProofB58, Addrs, N, Curve) -> BinPub = libp2p_crypto:b58_to_bin(PubKeyB58), Proof = base58:base58_to_binary(ProofB58), - VarTxn = blockchain_txn_vars_v1:new(make_vars(), <<>>, 1, #{master_key => BinPub, - key_proof => Proof}), + VarTxn = blockchain_txn_vars_v1:new(make_vars(), 1, #{master_key => BinPub}), + VarTxn1 = blockchain_txn_vars_v1:key_proof(VarTxn, Proof), OldSecurities = case proplists:get_value(securities, Config) of undefined -> []; @@ -132,7 +132,7 @@ create(OldGenesisFile, PubKeyB58, ProofB58, Addrs, N, Curve) -> OldGenesisTransactions = OldAccounts ++ OldGateways ++ OldSecurities ++ OldDCs, Addresses = [libp2p_crypto:p2p_to_pubkey_bin(Addr) || Addr <- string:split(Addrs, ",", all)], - miner_consensus_mgr:initial_dkg(OldGenesisTransactions ++ [VarTxn], Addresses, N, Curve), + miner_consensus_mgr:initial_dkg(OldGenesisTransactions ++ [VarTxn1], Addresses, N, Curve), [clique_status:text("ok")]; {error, Reason} -> [clique_status:text(io_lib:format("~p", [Reason]))] @@ -170,8 +170,8 @@ forge(PubKeyB58, ProofB58, Addrs, N, Curve) -> BinPub = libp2p_crypto:b58_to_bin(PubKeyB58), Proof = base58:base58_to_binary(ProofB58), - VarTxn = blockchain_txn_vars_v1:new(make_vars(), <<>>, 1, #{master_key => BinPub, - key_proof => Proof}), + VarTxn = blockchain_txn_vars_v1:new(make_vars(), 1, #{master_key => BinPub}), + VarTxn1 = blockchain_txn_vars_v1:key_proof(VarTxn, Proof), Addresses = [libp2p_crypto:p2p_to_pubkey_bin(Addr) || Addr <- string:split(Addrs, ",", all)], InitialPaymentTransactions = [ blockchain_txn_coinbase_v1:new(Addr, 500000000) || Addr <- Addresses], @@ -182,7 +182,7 @@ forge(PubKeyB58, ProofB58, Addrs, N, Curve) -> %% NOTE: This is mostly for locally testing run.sh so we have nodes added as gateways in the genesis block InitialGatewayTransactions = [blockchain_txn_gen_gateway_v1:new(Addr, Addr, 16#8c283475d4e89ff, 0) || Addr <- Addresses ], - miner_consensus_mgr:initial_dkg([VarTxn] ++ + miner_consensus_mgr:initial_dkg([VarTxn1] ++ InitialPaymentTransactions ++ InitialGatewayTransactions ++ InitialSecurityTransactions ++ @@ -296,9 +296,13 @@ genesis_proof(["genesis", "proof", PrivKeyB58], [], []) -> PrivKeyBin = base58:base58_to_binary(PrivKeyB58), #{secret := Priv, public := Pub} = libp2p_crypto:keys_from_bin(PrivKeyBin), Vars = make_vars(), - KeyProof = blockchain_txn_vars_v1:create_proof(Priv, Vars), + + BinPub = libp2p_crypto:pubkey_to_bin(Pub), + Txn = blockchain_txn_vars_v1:new(Vars, 1, #{master_key => BinPub}), + Proof = blockchain_txn_vars_v1:create_proof(Priv, Txn), + [clique_status:text(io_lib:format("Proof:~n~s~nPubKey:~n~s", - [base58:binary_to_base58(KeyProof), + [base58:binary_to_base58(Proof), libp2p_crypto:pubkey_to_b58(Pub)]))]; genesis_proof(_, [], []) -> usage. diff --git a/test/miner_blockchain_SUITE.erl b/test/miner_blockchain_SUITE.erl index 942a58bb9..d7c86b36d 100644 --- a/test/miner_blockchain_SUITE.erl +++ b/test/miner_blockchain_SUITE.erl @@ -26,7 +26,8 @@ all() -> [ growth_test, election_test, group_change_test, - master_key_test + master_key_test, + version_change_test ]. init_per_suite(Config) -> @@ -45,54 +46,32 @@ init_per_testcase(TestCase, Config0) -> Interval = proplists:get_value(election_interval, Config), BatchSize = proplists:get_value(batch_size, Config), Curve = proplists:get_value(dkg_curve, Config), - %% VarCommitInterval = proplists:get_value(var_commit_interval, Config), - #{secret := Priv, public := Pub} = + #{secret := Priv, public := Pub} = Keys = libp2p_crypto:generate_keys(ecc_compact), - Vars = #{?block_time => BlockTime, + Extras = + case TestCase of + _ -> + #{} + end, + + Vars = #{garbage_value => totes_garb, + ?block_time => BlockTime, ?election_interval => Interval, - ?election_restart_interval => 10, ?num_consensus_members => NumConsensusMembers, ?batch_size => BatchSize, - ?vars_commit_delay => 5, - ?var_gw_inactivity_threshold => 20, - ?block_version => v1, - ?dkg_curve => Curve, - garbage_value => totes_garb, - ?predicate_callback_mod => miner, - ?predicate_callback_fun => test_version, - ?predicate_threshold => 0.85, - ?monthly_reward => 50000 * 1000000, - ?securities_percent => 0.35, - ?dc_percent => 0, - ?poc_challengees_percent => 0.19 + 0.16, - ?poc_challengers_percent => 0.09 + 0.06, - ?poc_witnesses_percent => 0.02 + 0.03, - ?consensus_percent => 0.10, - ?election_selection_pct => 60, - ?election_replacement_factor => 4, - ?election_replacement_slope => 20, - ?min_score => 0.2, - ?alpha_decay => 0.007, - ?beta_decay => 0.0005, - ?max_staleness => 100000, - ?min_assert_h3_res => 12, - ?h3_neighbor_res => 12, - ?h3_max_grid_distance => 13, - ?h3_exclusion_ring_dist => 2, - ?poc_challenge_interval => 10 - }, - - BinPub = libp2p_crypto:pubkey_to_bin(Pub), - KeyProof = blockchain_txn_vars_v1:create_proof(Priv, Vars), - - ct:pal("master key ~p~n priv ~p~n vars ~p~n keyproof ~p~n artifact ~p", - [BinPub, Priv, Vars, KeyProof, - term_to_binary(Vars, [{compressed, 9}])]), - - InitialVars = [ blockchain_txn_vars_v1:new(Vars, <<>>, 1, #{master_key => BinPub, - key_proof => KeyProof}) ], + ?dkg_curve => Curve}, + FinalVars = maps:merge(Vars, Extras), + ct:pal("final vars ~p", [FinalVars]), + + InitialVars = + case TestCase of + version_change_test -> + miner_ct_utils:make_vars(Keys, FinalVars, legacy); + _ -> + miner_ct_utils:make_vars(Keys, FinalVars) + end, InitialPayment = [ blockchain_txn_coinbase_v1:new(Addr, 5000) || Addr <- Addresses], Locations = lists:foldl( @@ -332,13 +311,14 @@ group_change_test(Config) -> {Priv, _Pub} = proplists:get_value(master_key, Config), - Proof = blockchain_txn_vars_v1:create_proof(Priv, Vars), - Txn = blockchain_txn_vars_v1:new(Vars, Proof, 2, #{version_predicate => 2, - unsets => [garbage_value]}), + Txn = blockchain_txn_vars_v1:new(Vars, 2, #{version_predicate => 2, + unsets => [garbage_value]}), + Proof = blockchain_txn_vars_v1:create_proof(Priv, Txn), + Txn1 = blockchain_txn_vars_v1:proof(Txn, Proof), %% wait for it to take effect - _ = [ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [Txn]) + _ = [ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [Txn1]) || Miner <- Miners], HChain = ct_rpc:call(hd(Miners), blockchain_worker, blockchain, []), @@ -347,19 +327,18 @@ group_change_test(Config) -> ok = miner_ct_utils:wait_until( fun() -> true == lists:all(fun(Miner) -> - C = ct_rpc:call(Miner, blockchain_worker, blockchain, []), - {ok, Ht} = ct_rpc:call(Miner, blockchain, height, [C]), + C = ct_rpc:call(Miner, blockchain_worker, blockchain, [], 500), + {ok, Ht} = ct_rpc:call(Miner, blockchain, height, [C], 500), ct:pal("miner ~p height ~p", [Miner, Ht]), Ht > (Height + 20) end, shuffle(Miners)) - end, 40, timer:seconds(1)), + end, 80, timer:seconds(1)), %% make sure we still haven't executed it - CGroup1 = lists:filtermap( - fun(Miner) -> - true == ct_rpc:call(Miner, miner_consensus_mgr, in_consensus, []) - end, Miners), - ?assertEqual(4, length(CGroup1)), + C = ct_rpc:call(hd(Miners), blockchain_worker, blockchain, []), + L = ct_rpc:call(hd(Miners), blockchain, ledger, [C]), + {ok, Members} = ct_rpc:call(hd(Miners), blockchain_ledger_v1, consensus_members, [L]), + ?assertEqual(4, length(Members)), %% alter the "version" for all of them. lists:foreach( @@ -436,10 +415,11 @@ master_key_test(Config) -> {Priv, _Pub} = proplists:get_value(master_key, Config), Vars = #{garbage_value => totes_goats_garb}, - Proof = blockchain_txn_vars_v1:create_proof(Priv, Vars), - ConsensusTxn = blockchain_txn_vars_v1:new(Vars, Proof, 2, #{}), + Txn1_0 = blockchain_txn_vars_v1:new(Vars, 2), + Proof = blockchain_txn_vars_v1:create_proof(Priv, Txn1_0), + Txn1_1 = blockchain_txn_vars_v1:proof(Txn1_0, Proof), - _ = [ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [ConsensusTxn]) + _ = [ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [Txn1_1]) || Miner <- Miners], ok = miner_ct_utils:wait_until( @@ -460,14 +440,16 @@ master_key_test(Config) -> BinPub2 = libp2p_crypto:pubkey_to_bin(Pub2), Vars2 = #{garbage_value => goats_are_not_garb}, - Proof2 = blockchain_txn_vars_v1:create_proof(Priv, Vars2), - KeyProof2 = blockchain_txn_vars_v1:create_proof(Priv2, Vars2), - KeyProof2Corrupted = <>, - ConsensusTxn2 = blockchain_txn_vars_v1:new(Vars2, Proof2, 3, #{master_key => BinPub2, - key_proof => KeyProof2Corrupted}), + Txn2_0 = blockchain_txn_vars_v1:new(Vars2, 3, #{master_key => BinPub2}), + Proof2 = blockchain_txn_vars_v1:create_proof(Priv, Txn2_0), + KeyProof2 = blockchain_txn_vars_v1:create_proof(Priv2, Txn2_0), + KeyProof2Corrupted = <>, + Txn2_1 = blockchain_txn_vars_v1:proof(Txn2_0, Proof2), + Txn2_2c = blockchain_txn_vars_v1:key_proof(Txn2_1, KeyProof2Corrupted), + {ok, Start2} = ct_rpc:call(hd(Miners), blockchain, height, [Blockchain1]), - _ = [ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [ConsensusTxn2]) + _ = [ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [Txn2_2c]) || Miner <- Miners], ok = miner_ct_utils:wait_until( @@ -482,14 +464,12 @@ master_key_test(Config) -> {ok, totes_goats_garb} == ct_rpc:call(Miner, blockchain, config, [garbage_value, Ledger]) end, shuffle(Miners)) - end, 40, timer:seconds(1)), + end, 60, timer:seconds(1)), %% good master key - ConsensusTxn3 = blockchain_txn_vars_v1:new(Vars2, Proof2, 4, #{master_key => BinPub2, - key_proof => KeyProof2}), - - _ = [ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [ConsensusTxn3]) + Txn2_2 = blockchain_txn_vars_v1:key_proof(Txn2_1, KeyProof2), + _ = [ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [Txn2_2]) || Miner <- Miners], ok = miner_ct_utils:wait_until( @@ -508,11 +488,13 @@ master_key_test(Config) -> %% make sure old master key is no longer working Vars4 = #{garbage_value => goats_are_too_garb}, - Proof4 = blockchain_txn_vars_v1:create_proof(Priv, Vars4), - ConsensusTxn4 = blockchain_txn_vars_v1:new(Vars4, Proof4, 5, #{}), + Txn4_0 = blockchain_txn_vars_v1:new(Vars4, 4), + Proof4 = blockchain_txn_vars_v1:create_proof(Priv, Txn4_0), + Txn4_1 = blockchain_txn_vars_v1:proof(Txn4_0, Proof4), + {ok, Start4} = ct_rpc:call(hd(Miners), blockchain, height, [Blockchain1]), - _ = [ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [ConsensusTxn4]) + _ = [ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [Txn4_1]) || Miner <- Miners], ok = miner_ct_utils:wait_until( @@ -527,15 +509,16 @@ master_key_test(Config) -> {ok, goats_are_not_garb} == ct_rpc:call(Miner, blockchain, config, [garbage_value, Ledger]) end, shuffle(Miners)) - end, 40, timer:seconds(1)), + end, 80, timer:seconds(1)), %% double check that new master key works Vars5 = #{garbage_value => goats_always_win}, - Proof5 = blockchain_txn_vars_v1:create_proof(Priv2, Vars5), - ConsensusTxn5 = blockchain_txn_vars_v1:new(Vars5, Proof5, 6, #{}), + Txn5_0 = blockchain_txn_vars_v1:new(Vars5, 4), + Proof5 = blockchain_txn_vars_v1:create_proof(Priv2, Txn5_0), + Txn5_1 = blockchain_txn_vars_v1:proof(Txn5_0, Proof5), - _ = [ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [ConsensusTxn5]) + _ = [ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [Txn5_1]) || Miner <- Miners], ok = miner_ct_utils:wait_until( @@ -552,3 +535,141 @@ master_key_test(Config) -> ok. + + + +version_change_test(Config) -> + %% get all the miners + Miners = proplists:get_value(miners, Config), + + %% check consensus miners + ConsensusMiners = lists:filtermap(fun(Miner) -> + true == ct_rpc:call(Miner, miner_consensus_mgr, in_consensus, []) + end, Miners), + + %% check non consensus miners + NonConsensusMiners = lists:filtermap(fun(Miner) -> + false == ct_rpc:call(Miner, miner_consensus_mgr, in_consensus, []) + end, Miners), + + ?assertNotEqual([], ConsensusMiners), + %% get the first consensus miner + FirstConsensusMiner = hd(ConsensusMiners), + + ?assertEqual(7, length(ConsensusMiners)), + + Blockchain = ct_rpc:call(FirstConsensusMiner, blockchain_worker, blockchain, []), + + %% get the genesis block from first consensus miner + {ok, GenesisBlock} = ct_rpc:call(FirstConsensusMiner, blockchain, genesis_block, [Blockchain]), + + %% check genesis load results for non consensus miners + _GenesisLoadResults = miner_ct_utils:pmap(fun(M) -> + ct_rpc:call(M, blockchain_worker, integrate_genesis_block, [GenesisBlock]) + end, NonConsensusMiners), + + %% make sure that elections are rolling + ok = miner_ct_utils:wait_until(fun() -> + true == lists:all(fun(Miner) -> + Epoch = ct_rpc:call(Miner, miner, election_epoch, []), + ct:pal("miner ~p Epoch ~p", [Miner, Epoch]), + Epoch > 1 + end, shuffle(Miners)) + end, 30, timer:seconds(1)), + + + %% baseline: old-style chain vars are working + + Blockchain1 = ct_rpc:call(hd(Miners), blockchain_worker, blockchain, []), + {Priv, _Pub} = proplists:get_value(master_key, Config), + + Vars = #{garbage_value => totes_goats_garb}, + Proof = blockchain_txn_vars_v1:legacy_create_proof(Priv, Vars), + Txn1_0 = blockchain_txn_vars_v1:new(Vars, 2), + Txn1_1 = blockchain_txn_vars_v1:proof(Txn1_0, Proof), + + _ = [ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [Txn1_1]) + || Miner <- Miners], + + ok = miner_ct_utils:wait_until( + fun() -> + lists:all( + fun(Miner) -> + C = ct_rpc:call(Miner, blockchain_worker, blockchain, []), + Ledger = ct_rpc:call(Miner, blockchain, ledger, [C]), + {ok, totes_goats_garb} == ct_rpc:call(Miner, blockchain, config, [garbage_value, Ledger]) + end, shuffle(Miners)) + end, 40, timer:seconds(1)), + + %% switch chain version + + Vars2 = #{?chain_vars_version => 2}, + Proof2 = blockchain_txn_vars_v1:legacy_create_proof(Priv, Vars2), + Txn2_0 = blockchain_txn_vars_v1:new(Vars2, 3), + Txn2_1 = blockchain_txn_vars_v1:proof(Txn2_0, Proof2), + + _ = [ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [Txn2_1]) + || Miner <- Miners], + + %% make sure that it has taken effect + ok = miner_ct_utils:wait_until( + fun() -> + lists:all( + fun(Miner) -> + C = ct_rpc:call(Miner, blockchain_worker, blockchain, []), + Ledger = ct_rpc:call(Miner, blockchain, ledger, [C]), + {ok, 2} == + ct_rpc:call(Miner, blockchain, config, [?chain_vars_version, + Ledger]) + end, shuffle(Miners)) + end, 60, timer:seconds(1)), + + %% try a new-style txn change + + Vars3 = #{garbage_value => goats_are_not_garb}, + Txn3_0 = blockchain_txn_vars_v1:new(Vars3, 4), + Proof3 = blockchain_txn_vars_v1:create_proof(Priv, Txn3_0), + Txn3_1 = blockchain_txn_vars_v1:proof(Txn3_0, Proof3), + + _ = [ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [Txn3_1]) + || Miner <- Miners], + + ok = miner_ct_utils:wait_until( + fun() -> + lists:all( + fun(Miner) -> + C = ct_rpc:call(Miner, blockchain_worker, blockchain, []), + Ledger = ct_rpc:call(Miner, blockchain, ledger, [C]), + Val = ct_rpc:call(Miner, blockchain, config, [garbage_value, Ledger]), + ct:pal("val ~p", [Val]), + {ok, goats_are_not_garb} == Val + end, shuffle(Miners)) + end, 40, timer:seconds(1)), + + + %% make sure old style is now closed off. + + Vars4 = #{garbage_value => goats_are_too_garb}, + Txn4_0 = blockchain_txn_vars_v1:new(Vars4, 5), + Proof4 = blockchain_txn_vars_v1:legacy_create_proof(Priv, Vars4), + Txn4_1 = blockchain_txn_vars_v1:proof(Txn4_0, Proof4), + + {ok, Start4} = ct_rpc:call(hd(Miners), blockchain, height, [Blockchain1]), + + _ = [ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [Txn4_1]) + || Miner <- Miners], + + ok = miner_ct_utils:wait_until( + fun() -> + lists:all( + fun(Miner) -> + C = ct_rpc:call(Miner, blockchain_worker, blockchain, []), + Ledger = ct_rpc:call(Miner, blockchain, ledger, [C]), + {ok, Ht} = ct_rpc:call(Miner, blockchain, height, [C]), + ct:pal("miner ~p height ~p", [Miner, Ht]), + Ht > (Start4 + 15) andalso + {ok, goats_are_not_garb} == + ct_rpc:call(Miner, blockchain, config, [garbage_value, Ledger]) + end, shuffle(Miners)) + end, 40, timer:seconds(1)), + ok. diff --git a/test/miner_ct_utils.erl b/test/miner_ct_utils.erl index 740d0335f..238e5f5c2 100644 --- a/test/miner_ct_utils.erl +++ b/test/miner_ct_utils.erl @@ -1,5 +1,8 @@ -module(miner_ct_utils). +-include_lib("eunit/include/eunit.hrl"). +-include_lib("blockchain/include/blockchain_vars.hrl"). + -export([pmap/2, pmap/3, wait_until/1, wait_until/3, @@ -14,7 +17,8 @@ random_n/2, init_per_testcase/2, end_per_testcase/2, - get_balance/2 + get_balance/2, + make_vars/1, make_vars/2, make_vars/3 ]). pmap(F, L) -> @@ -44,7 +48,7 @@ wait_until(Fun) -> wait_until(Fun, 40, 100). wait_until(Fun, Retry, Delay) when Retry > 0 -> Res = Fun(), - case Res of + try Res of true -> ok; _ when Retry == 1 -> @@ -52,6 +56,9 @@ wait_until(Fun, Retry, Delay) when Retry > 0 -> _ -> timer:sleep(Delay), wait_until(Fun, Retry-1, Delay) + catch _:_ -> + timer:sleep(Delay), + wait_until(Fun, Retry-1, Delay) end. wait_until_offline(Node) -> @@ -291,3 +298,69 @@ get_balance(Miner, Addr) -> Ledger = ct_rpc:call(Miner, blockchain, ledger, [Chain]), {ok, Entry} = ct_rpc:call(Miner, blockchain_ledger_v1, find_entry, [Addr, Ledger]), ct_rpc:call(Miner, blockchain_ledger_entry_v1, balance, [Entry]). + +make_vars(Keys) -> + make_vars(Keys, #{}). + +make_vars(Keys, Map) -> + make_vars(Keys, Map, modern). + +make_vars(Keys, Map, Mode) -> + Vars1 = #{?chain_vars_version => 2, + ?block_time => 1, + ?election_interval => 30, + ?election_restart_interval => 10, + ?num_consensus_members => 7, + ?batch_size => 2500, + ?vars_commit_delay => 5, + ?var_gw_inactivity_threshold => 20, + ?block_version => v1, + ?dkg_curve => 'SS512', + ?predicate_callback_mod => miner, + ?predicate_callback_fun => test_version, + ?predicate_threshold => 0.85, + ?monthly_reward => 50000 * 1000000, + ?securities_percent => 0.35, + ?dc_percent => 0, + ?poc_challengees_percent => 0.19 + 0.16, + ?poc_challengers_percent => 0.09 + 0.06, + ?poc_witnesses_percent => 0.02 + 0.03, + ?consensus_percent => 0.10, + ?election_selection_pct => 60, + ?election_replacement_factor => 4, + ?election_replacement_slope => 20, + ?min_score => 0.2, + ?alpha_decay => 0.007, + ?beta_decay => 0.0005, + ?max_staleness => 100000, + ?min_assert_h3_res => 12, + ?h3_neighbor_res => 12, + ?h3_max_grid_distance => 13, + ?h3_exclusion_ring_dist => 2, + ?poc_challenge_interval => 10%% , + %% ?poc_path_limit => 7 + }, + + #{secret := Priv, public := Pub} = Keys, + BinPub = libp2p_crypto:pubkey_to_bin(Pub), + + Vars = maps:merge(Vars1, Map), + case Mode of + modern -> + Txn = blockchain_txn_vars_v1:new(Vars, 1, #{master_key => BinPub}), + Proof = blockchain_txn_vars_v1:create_proof(Priv, Txn), + [blockchain_txn_vars_v1:key_proof(Txn, Proof)]; + %% in legacy mode, we have to do without some stuff + %% because everything will break if there are too many vars + legacy -> + %% ideally figure out a few more that are safe to + %% remove or bring back the splitting code + LegVars = maps:without([poc_path_limit, ?chain_vars_version, ?block_version], + Vars), + Proof = blockchain_txn_vars_v1:legacy_create_proof(Priv, LegVars), + Txn = blockchain_txn_vars_v1:new(LegVars, 1, #{master_key => BinPub, + key_proof => Proof}), + + [Txn] + + end. diff --git a/test/miner_dkg_SUITE.erl b/test/miner_dkg_SUITE.erl index ab40e4e4f..e7146ab27 100644 --- a/test/miner_dkg_SUITE.erl +++ b/test/miner_dkg_SUITE.erl @@ -37,14 +37,18 @@ end_per_testcase(_TestCase, Config) -> initial_dkg_test(Config) -> Miners = proplists:get_value(miners, Config), Addresses = proplists:get_value(addresses, Config), + Keys = libp2p_crypto:generate_keys(ecc_compact), + + InitialVars = miner_ct_utils:make_vars(Keys, #{}), InitialPaymentTransactions = [blockchain_txn_coinbase_v1:new(Addr, 5000) || Addr <- Addresses], + InitialTransactions = InitialVars ++ InitialPaymentTransactions, N = proplists:get_value(num_consensus_members, Config), Curve = proplists:get_value(dkg_curve, Config), DKGResults = miner_ct_utils:pmap( fun(Miner) -> ct_rpc:call(Miner, miner_consensus_mgr, initial_dkg, - [InitialPaymentTransactions, Addresses, N, Curve], + [InitialTransactions, Addresses, N, Curve], timer:seconds(60)) end, Miners), ?assertEqual([ok], lists:usort(DKGResults)), diff --git a/test/miner_libp2p_SUITE.erl b/test/miner_libp2p_SUITE.erl index ac8b1854f..a1bfc0211 100644 --- a/test/miner_libp2p_SUITE.erl +++ b/test/miner_libp2p_SUITE.erl @@ -3,6 +3,7 @@ -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). -include_lib("kernel/include/inet.hrl"). +-include_lib("blockchain/include/blockchain_vars.hrl"). -export([ init_per_suite/1 diff --git a/test/miner_payment_txn_SUITE.erl b/test/miner_payment_txn_SUITE.erl index e267651a5..c84f9c33f 100644 --- a/test/miner_payment_txn_SUITE.erl +++ b/test/miner_payment_txn_SUITE.erl @@ -40,57 +40,18 @@ init_per_testcase(_TestCase, Config0) -> N = proplists:get_value(num_consensus_members, Config), BlockTime = proplists:get_value(block_time, Config), - Interval = proplists:get_value(election_interval, Config), BatchSize = proplists:get_value(batch_size, Config), Curve = proplists:get_value(dkg_curve, Config), %% VarCommitInterval = proplists:get_value(var_commit_interval, Config), - #{secret := Priv, public := Pub} = - libp2p_crypto:generate_keys(ecc_compact), - - Vars = #{?block_time => BlockTime, - ?election_interval => Interval, - ?election_restart_interval => 10, - ?num_consensus_members => N, - ?batch_size => BatchSize, - ?vars_commit_delay => 2, - ?var_gw_inactivity_threshold => 20, - ?block_version => v1, - ?dkg_curve => Curve, - ?predicate_callback_mod => miner, - ?predicate_callback_fun => test_version, - ?predicate_threshold => 0.85, - ?monthly_reward => 0, - ?securities_percent => 0, - ?dc_percent => 0, - ?poc_challengees_percent => 0, - ?poc_challengers_percent => 0, - ?poc_witnesses_percent => 0, - ?consensus_percent => 0, - ?election_selection_pct => 60, - ?election_replacement_factor => 4, - ?election_replacement_slope => 20, - ?min_score => 0.2, - ?alpha_decay => 0.007, - ?beta_decay => 0.0005, - ?max_staleness => 100000, - ?min_assert_h3_res => 12, - ?h3_neighbor_res => 12, - ?h3_max_grid_distance => 13, - ?h3_exclusion_ring_dist => 2, - ?poc_challenge_interval => 30 - }, - - BinPub = libp2p_crypto:pubkey_to_bin(Pub), - KeyProof = blockchain_txn_vars_v1:create_proof(Priv, Vars), - - ct:pal("master key ~p~n priv ~p~n vars ~p~n keyproof ~p~n artifact ~p", - [BinPub, Priv, Vars, KeyProof, - term_to_binary(Vars, [{compressed, 9}])]), - - InitialVars = [ blockchain_txn_vars_v1:new(Vars, <<>>, 1, #{master_key => BinPub, - key_proof => KeyProof}) ], + Keys = libp2p_crypto:generate_keys(ecc_compact), + InitialVars = miner_ct_utils:make_vars(Keys, #{?block_time => BlockTime, + %% rule out rewards + ?election_interval => infinity, + ?num_consensus_members => N, + ?batch_size => BatchSize, + ?dkg_curve => Curve}), DKGResults = miner_ct_utils:pmap( fun(Miner) -> ct_rpc:call(Miner, miner_consensus_mgr, initial_dkg, @@ -212,7 +173,7 @@ single_payment_test(Config) -> Miners -- [Candidate] ) end, - 60, + 20, timer:seconds(1) ), @@ -220,8 +181,8 @@ single_payment_test(Config) -> PayerBalance2 = miner_ct_utils:get_balance(Payer, PayerAddr), PayeeBalance2 = miner_ct_utils:get_balance(Payee, PayeeAddr), - 4000 = PayerBalance2 + Fee, - 6000 = PayeeBalance2, + ?assertEqual(4000, PayerBalance2 + Fee), + ?assertEqual(6000, PayeeBalance2), ct_rpc:call(Candidate, sys, resume, [Group]), @@ -234,13 +195,14 @@ single_payment_test(Config) -> PayerBalance3 = miner_ct_utils:get_balance(Miner, PayerAddr), PayeeBalance3 = miner_ct_utils:get_balance(Miner, PayeeAddr), + ct:pal("payer ~p payee ~p", [PayerBalance3, PayeeBalance3]), 3000 == PayerBalance3 + Fee andalso 7000 == PayeeBalance3 end, Miners ) end, - 60, + 20, timer:seconds(1) ), ct:comment("FinalPayerBalance: ~p, FinalPayeeBalance: ~p", [PayerBalance, PayeeBalance]), diff --git a/test/miner_poc_SUITE.erl b/test/miner_poc_SUITE.erl index ed08c03a5..61cf31f2f 100644 --- a/test/miner_poc_SUITE.erl +++ b/test/miner_poc_SUITE.erl @@ -47,51 +47,14 @@ dist(Config0) -> Curve = proplists:get_value(dkg_curve, Config), %% VarCommitInterval = proplists:get_value(var_commit_interval, Config), - #{secret := Priv, public := Pub} = - libp2p_crypto:generate_keys(ecc_compact), - - Vars = #{?block_time => BlockTime, - ?election_interval => Interval, - ?election_restart_interval => 10, - ?num_consensus_members => N, - ?batch_size => BatchSize, - ?vars_commit_delay => 2, - ?var_gw_inactivity_threshold => 20, - ?block_version => v1, - ?dkg_curve => Curve, - ?predicate_callback_mod => miner, - ?predicate_callback_fun => test_version, - ?predicate_threshold => 0.85, - ?monthly_reward => 50000 * 1000000, - ?securities_percent => 0.35, - ?dc_percent => 0, - ?poc_challengees_percent => 0.19 + 0.16, - ?poc_challengers_percent => 0.09 + 0.06, - ?poc_witnesses_percent => 0.02 + 0.03, - ?consensus_percent => 0.10, - ?election_selection_pct => 60, - ?election_replacement_factor => 4, - ?election_replacement_slope => 20, - ?min_score => 0.2, - ?alpha_decay => 0.007, - ?beta_decay => 0.0005, - ?max_staleness => 100000, - ?min_assert_h3_res => 12, - ?h3_neighbor_res => 12, - ?h3_max_grid_distance => 13, - ?h3_exclusion_ring_dist => 2, - ?poc_challenge_interval => 20 - }, - - BinPub = libp2p_crypto:pubkey_to_bin(Pub), - KeyProof = blockchain_txn_vars_v1:create_proof(Priv, Vars), - - ct:pal("master key ~p~n priv ~p~n vars ~p~n keyproof ~p~n artifact ~p", - [BinPub, Priv, Vars, KeyProof, - term_to_binary(Vars, [{compressed, 9}])]), - - InitialVars = [ blockchain_txn_vars_v1:new(Vars, <<>>, 1, #{master_key => BinPub, - key_proof => KeyProof}) ], + Keys = libp2p_crypto:generate_keys(ecc_compact), + + InitialVars = miner_ct_utils:make_vars(Keys, #{?block_time => BlockTime, + ?election_interval => Interval, + ?num_consensus_members => N, + ?batch_size => BatchSize, + ?dkg_curve => Curve, + ?poc_challenge_interval => 20}), InitialPaymentTransactions = [blockchain_txn_coinbase_v1:new(Addr, 5000) || Addr <- Addresses], Locations = lists:foldl( @@ -166,7 +129,13 @@ dist(Config0) -> %% load the genesis block on all the nodes lists:foreach( fun(Miner) -> - ct_rpc:call(Miner, blockchain_worker, integrate_genesis_block, [GenesisBlock]) + case ct_rpc:call(Miner, miner_consensus_mgr, in_consensus, [], 5000) of + true -> + ok; + false -> + ct_rpc:call(Miner, blockchain_worker, + integrate_genesis_block, [GenesisBlock], 5000) + end end, Miners ), diff --git a/test/miner_reward_SUITE.erl b/test/miner_reward_SUITE.erl index 4d39a864c..c52006d66 100644 --- a/test/miner_reward_SUITE.erl +++ b/test/miner_reward_SUITE.erl @@ -38,55 +38,17 @@ init_per_testcase(_TestCase, Config0) -> N = proplists:get_value(num_consensus_members, Config), BlockTime = proplists:get_value(block_time, Config), - Interval = 3, + Interval = 5, BatchSize = proplists:get_value(batch_size, Config), Curve = proplists:get_value(dkg_curve, Config), - #{secret := Priv, public := Pub} = - libp2p_crypto:generate_keys(ecc_compact), - - Vars = #{?block_time => BlockTime, - ?election_interval => Interval, - ?election_restart_interval => 5, - ?num_consensus_members => N, - ?batch_size => BatchSize, - ?vars_commit_delay => 2, - ?var_gw_inactivity_threshold => 20, - ?block_version => v1, - ?dkg_curve => Curve, - ?predicate_callback_mod => miner, - ?predicate_callback_fun => test_version, - ?predicate_threshold => 0.85, - ?monthly_reward => 50000 * 1000000, - ?securities_percent => 0.35, - ?dc_percent => 0, - ?poc_challengees_percent => 0.19 + 0.16, - ?poc_challengers_percent => 0.09 + 0.06, - ?poc_witnesses_percent => 0.02 + 0.03, - ?consensus_percent => 0.10, - ?election_selection_pct => 60, - ?election_replacement_factor => 4, - ?election_replacement_slope => 20, - ?min_score => 0.2, - ?alpha_decay => 0.007, - ?beta_decay => 0.0005, - ?max_staleness => 100000, - ?min_assert_h3_res => 12, - ?h3_neighbor_res => 12, - ?h3_max_grid_distance => 13, - ?h3_exclusion_ring_dist => 2, - ?poc_challenge_interval => 30 - }, - - BinPub = libp2p_crypto:pubkey_to_bin(Pub), - KeyProof = blockchain_txn_vars_v1:create_proof(Priv, Vars), - - ct:pal("master key ~p~n priv ~p~n vars ~p~n keyproof ~p~n artifact ~p", - [BinPub, Priv, Vars, KeyProof, - term_to_binary(Vars, [{compressed, 9}])]), - - InitialVars = [ blockchain_txn_vars_v1:new(Vars, <<>>, 1, #{master_key => BinPub, - key_proof => KeyProof}) ], + Keys = libp2p_crypto:generate_keys(ecc_compact), + + InitialVars = miner_ct_utils:make_vars(Keys, #{?block_time => BlockTime, + ?election_interval => Interval, + ?num_consensus_members => N, + ?batch_size => BatchSize, + ?dkg_curve => Curve}), DKGResults = miner_ct_utils:pmap( fun(Miner) -> @@ -175,7 +137,7 @@ basic_test(Config) -> fun(Miner) -> C = ct_rpc:call(Miner, blockchain_worker, blockchain, []), {ok, Height} = ct_rpc:call(Miner, blockchain, height, [C]), - Height >= CurrentHeight + 6 + Height >= CurrentHeight + 10 end, Miners ) @@ -187,19 +149,27 @@ basic_test(Config) -> %% Check that the election txn is in the same block as the rewards txn ok = lists:foreach(fun(Miner) -> Chain0 = ct_rpc:call(Miner, blockchain_worker, blockchain, []), - {ok, ElectionRewardBlock} = ct_rpc:call(Miner, blockchain, get_block, [6, Chain0]), - Txns = ct_rpc:call(Miner, blockchain_block, transactions, [ElectionRewardBlock]), - ?assertEqual(length(Txns), 2), - [First, Second] = Txns, - ?assertEqual(blockchain_txn:type(Second), blockchain_txn_consensus_group_v1), - ?assertEqual(blockchain_txn:type(First), blockchain_txn_rewards_v1), - Rewards = blockchain_txn_rewards_v1:rewards(First), - ?assertEqual(length(Rewards), length(ConsensusMiners)), - lists:foreach(fun(R) -> - ?assertEqual(blockchain_txn_reward_v1:type(R), consensus), - ?assertEqual(blockchain_txn_reward_v1:amount(R), 83) - end, - Rewards) + lists:any( + fun(H) -> + try + {ok, ElectionRewardBlock} = ct_rpc:call(Miner, blockchain, get_block, [H, Chain0]), + Txns = ct_rpc:call(Miner, blockchain_block, transactions, [ElectionRewardBlock]), + ?assertEqual(length(Txns), 2), + [First, Second] = Txns, + ?assertEqual(blockchain_txn:type(Second), blockchain_txn_consensus_group_v1), + ?assertEqual(blockchain_txn:type(First), blockchain_txn_rewards_v1), + Rewards = blockchain_txn_rewards_v1:rewards(First), + ?assertEqual(length(Rewards), length(ConsensusMiners)), + lists:foreach(fun(R) -> + ?assertEqual(blockchain_txn_reward_v1:type(R), consensus), + ?assertEqual(blockchain_txn_reward_v1:amount(R), 83) + end, + Rewards), + true + catch _:_ -> + false + end + end, lists:seq(4, 10)) end, Miners), @@ -213,15 +183,15 @@ basic_test(Config) -> lists:member(Miner, ConsensusMiners), lists:member(Miner, NonConsensusMiners)} of {true, _, true, _} -> - ?assertEqual(4083, Bal); + ?assertEqual(4138, Bal); {true, _, _, true} -> ?assertEqual(4000, Bal); {_, true, true, _} -> - ?assertEqual(6083, Bal); + ?assertEqual(6138, Bal); {_, true, _, true} -> ?assertEqual(6000, Bal); {_, _, true, _} -> - ?assertEqual(5083, Bal); + ?assertEqual(5138, Bal); _ -> ?assertEqual(5000, Bal) end diff --git a/test/miner_router_SUITE.erl b/test/miner_router_SUITE.erl index 3bff52df1..9b0e7975a 100644 --- a/test/miner_router_SUITE.erl +++ b/test/miner_router_SUITE.erl @@ -4,6 +4,8 @@ -include_lib("eunit/include/eunit.hrl"). -include_lib("kernel/include/inet.hrl"). -include_lib("helium_proto/src/pb/helium_longfi_pb.hrl"). +-include_lib("blockchain/include/blockchain_vars.hrl"). + -export([ init_per_testcase/2, @@ -43,47 +45,13 @@ init_per_testcase(_TestCase, Config0) -> Curve = proplists:get_value(dkg_curve, Config), %% VarCommitInterval = proplists:get_value(var_commit_interval, Config), - #{secret := Priv, public := Pub} = - libp2p_crypto:generate_keys(ecc_compact), - - Vars = #{block_time => BlockTime, - election_interval => Interval, - election_restart_interval => 10, - num_consensus_members => N, - batch_size => BatchSize, - vars_commit_delay => 2, - block_version => v1, - dkg_curve => Curve, - predicate_callback_mod => miner, - predicate_callback_fun => test_version, - proposal_threshold => 0.85, - monthly_reward => 0, - securities_percent => 0, - dc_percent => 0, - poc_challengees_percent => 0, - poc_challengers_percent => 0, - poc_witnesses_percent => 0, - consensus_percent => 0, - election_selection_pct => 60, - election_replacement_factor => 4, - election_replacement_slope => 20, - min_score => 0.2, - h3_ring_size => 2, - h3_path_res => 8, - alpha_decay => 0.007, - beta_decay => 0.0005, - max_staleness => 100000 - }, - - BinPub = libp2p_crypto:pubkey_to_bin(Pub), - KeyProof = blockchain_txn_vars_v1:create_proof(Priv, Vars), - - ct:pal("master key ~p~n priv ~p~n vars ~p~n keyproof ~p~n artifact ~p", - [BinPub, Priv, Vars, KeyProof, - term_to_binary(Vars, [{compressed, 9}])]), - - InitialVars = [ blockchain_txn_vars_v1:new(Vars, <<>>, 1, #{master_key => BinPub, - key_proof => KeyProof}) ], + Keys = libp2p_crypto:generate_keys(ecc_compact), + + InitialVars = miner_ct_utils:make_vars(Keys, #{?block_time => BlockTime, + ?election_interval => Interval, + ?num_consensus_members => N, + ?batch_size => BatchSize, + ?dkg_curve => Curve}), DKGResults = miner_ct_utils:pmap( fun(Miner) ->