Commit 68f46d5c authored by andymck's avatar andymck Committed by Mark Allen
Browse files

refactor txn mgr dependency test

Rework miner_ct_utils:initial_dkg to account for partial completion

Refactor tests for new miner_ct_utils:initial_dkg
parent 56ffe2db
Showing with 180 additions and 125 deletions
+180 -125
......@@ -287,7 +287,7 @@ handle_call({initial_dkg, GenesisTransactions, Addrs, N, Curve}, From, State0) -
{noreply, DKGState#state{dkg_await=From}};
{false, NonDKGState} ->
lager:info("Not running DKG, From: ~p, WorkerAddr: ~p", [From, blockchain_swarm:pubkey_bin()]),
{reply, ok, NonDKGState}
{reply, not_in, NonDKGState}
end;
handle_call(consensus_pos, _From, State) ->
Ledger = blockchain:ledger(State#state.chain),
......@@ -556,7 +556,14 @@ handle_info({blockchain_event, {add_block, _Hash, _Sync, _Ledger}}, State) ->
{noreply, State}
end;
handle_info({blockchain_event, {new_chain, NC}}, State) ->
%% check if we're in the consensus group
self() ! timeout,
{noreply, State#state{chain = NC}};
handle_info({blockchain_event, {integrate_genesis_block, _Hash}}, State = #state{chain=undefined}) ->
%% check if we're in the consensus group
self() ! timeout,
Chain = blockchain_worker:blockchain(),
{noreply, State#state{chain=Chain}};
%% we had a chain to start with, so check restore state
handle_info(timeout, State) ->
try
......
......@@ -109,23 +109,14 @@ init_per_testcase(TestCase, Config0) ->
InitGen = [blockchain_txn_gen_gateway_v1:new(Addr, Addr, Loc, 0) || {Addr, Loc} <- lists:zip(Addresses, Locations)],
Txns = InitialVars ++ InitialPayment ++ InitGen,
DKGResults = miner_ct_utils:initial_dkg(Miners, Txns, Addresses, NumConsensusMembers, Curve),
true = lists:all(fun(Res) -> Res == ok end, DKGResults),
{ok, DKGCompletedNodes} = miner_ct_utils:initial_dkg(Miners, Txns, Addresses, NumConsensusMembers, Curve),
timer:sleep(500),
%% Get both consensus and non consensus miners
true = miner_ct_utils:wait_until(
fun() ->
{_ConsensusMiners, NCMiners} = miner_ct_utils:miners_by_consensus_state(Miners),
length(NCMiners) == (length(Miners) - NumConsensusMembers)
end, 25, 200),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(DKGCompletedNodes), Miners -- DKGCompletedNodes),
{ConsensusMiners, NonConsensusMiners} = miner_ct_utils:miners_by_consensus_state(Miners),
ct:pal("ConsensusMiners: ~p, NonConsensusMiners: ~p", [ConsensusMiners, NonConsensusMiners]),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(ConsensusMiners), NonConsensusMiners),
ok = miner_ct_utils:wait_for_gte(height, Miners, 3, all, 15),
[ {master_key, {Priv, Pub}},
......@@ -133,8 +124,9 @@ init_per_testcase(TestCase, Config0) ->
{non_consensus_miners, NonConsensusMiners}
| Config]
catch
What:Why ->
What:Why:Stack ->
end_per_testcase(TestCase, Config),
ct:pal("Stack ~p", [Stack]),
erlang:What(Why)
end.
......
......@@ -368,14 +368,49 @@ delete_dirs(DirWildcard, SubDir)->
ok.
initial_dkg(Miners, Txns, Addresses, NumConsensusMembers, Curve)->
initial_dkg(Miners, Txns, Addresses, NumConsensusMembers, Curve, 12000).
initial_dkg(Miners, Txns, Addresses, NumConsensusMembers, Curve, Timeout)->
DKGResults = miner_ct_utils:pmap(
fun(Miner) ->
ct_rpc:call(Miner, miner_consensus_mgr, initial_dkg,
[Txns, Addresses, NumConsensusMembers, Curve], Timeout)
end, Miners),
DKGResults.
initial_dkg(Miners, Txns, Addresses, NumConsensusMembers, Curve, 60000).
initial_dkg(Miners, Txns, Addresses, NumConsensusMembers, Curve, Timeout) ->
SuperParent = self(),
SuperTimeout = Timeout + 5000,
Threshold = (NumConsensusMembers - 1) div 3,
spawn(fun() ->
Parent = self(),
lists:foreach(
fun(Miner) ->
spawn(fun() ->
Res = ct_rpc:call(Miner, miner_consensus_mgr, initial_dkg,
[Txns, Addresses, NumConsensusMembers, Curve], Timeout),
Parent ! {Miner, Res}
end)
end, Miners),
SuperParent ! receive_dkg_results(Threshold, Miners, [])
end),
receive
DKGResults ->
DKGResults
after SuperTimeout ->
{error, dkg_timeout}
end.
receive_dkg_results(Threshold, [], OKResults) ->
ct:pal("only ~p completed dkg, lower than threshold of ~p", [OKResults, Threshold]),
{error, insufficent_dkg_completion};
receive_dkg_results(Threshold, _Miners, OKResults) when length(OKResults) >= Threshold ->
{ok, OKResults};
receive_dkg_results(Threshold, Miners, OKResults) ->
receive
{Miner, ok} ->
case lists:member(Miner, Miners) of
true ->
receive_dkg_results(Threshold, Miners -- [Miner], [Miner|OKResults]);
false ->
receive_dkg_results(Threshold, Miners, OKResults)
end;
{Miner, OtherResult} ->
ct:pal("Miner ~p failed DKG: ~p", [Miner, OtherResult]),
receive_dkg_results(Threshold, Miners -- [Miner], OKResults)
end.
......@@ -638,6 +673,7 @@ init_per_testcase(Mod, TestCase, Config0) ->
MinerBaseDir = BaseDir ++ "_" ++ atom_to_list(Miner),
ct:pal("MinerBaseDir: ~p", [MinerBaseDir]),
%% set blockchain env
ct_rpc:call(Miner, application, set_env, [blockchain, enable_nat, false]),
ct_rpc:call(Miner, application, set_env, [blockchain, base_dir, MinerBaseDir]),
ct_rpc:call(Miner, application, set_env, [blockchain, port, Port]),
ct_rpc:call(Miner, application, set_env, [blockchain, seed_nodes, SeedNodes]),
......@@ -686,6 +722,9 @@ init_per_testcase(Mod, TestCase, Config0) ->
Addrs = miner_ct_utils:pmap(
fun(Miner) ->
Swarm = ct_rpc:call(Miner, blockchain_swarm, swarm, [], 2000),
true = miner_ct_utils:wait_until(fun() ->
length(ct_rpc:call(Miner, libp2p_swarm, listen_addrs, [Swarm], 2000)) > 0
end),
[H|_] = ct_rpc:call(Miner, libp2p_swarm, listen_addrs, [Swarm], 2000),
H
end, Miners),
......@@ -924,7 +963,7 @@ make_vars(Keys, Map, Mode) ->
?predicate_callback_mod => miner,
?predicate_callback_fun => test_version,
?predicate_threshold => 0.60,
?monthly_reward => 50000 * 1000000,
?monthly_reward => 5000000 * 1000000,
?securities_percent => 0.35,
?dc_percent => 0.0,
?poc_challengees_percent => 0.19 + 0.16,
......
......@@ -46,11 +46,9 @@ initial_dkg_test(Config) ->
NumConsensusMembers = ?config(num_consensus_members, Config),
Curve = ?config(dkg_curve, Config),
DKGResults = miner_ct_utils:initial_dkg(Miners, InitialTransactions, Addresses,
{ok, DKGCompletedNodes} = miner_ct_utils:initial_dkg(Miners, InitialTransactions, Addresses,
NumConsensusMembers, Curve),
true = lists:all(fun(Res) -> Res == ok end, DKGResults),
{comment, DKGResults}.
{comment, DKGCompletedNodes}.
%% ------------------------------------------------------------------
......
......@@ -36,20 +36,15 @@ init_per_testcase(TestCase, Config0) ->
AddressesWithLocations = lists:zip(Addresses, Locations),
InitialGenGatewayTxns = [blockchain_txn_gen_gateway_v1:new(Addr, Addr, Loc, 0) || {Addr, Loc} <- AddressesWithLocations],
InitialTransactions = InitialVars ++ InitialPaymentTransactions ++ InitialGenGatewayTxns,
DKGResults = miner_ct_utils:pmap(
fun(Miner) ->
ct_rpc:call(Miner, miner_consensus_mgr, initial_dkg, [InitialTransactions, Addresses, N, Curve])
end,
Miners
),
ct:pal("results ~p", [DKGResults]),
?assert(lists:all(fun(Res) -> Res == ok end, DKGResults)),
{ok, DKGCompletedNodes} = miner_ct_utils:initial_dkg(Miners, InitialTransactions, Addresses, N, Curve),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(DKGCompletedNodes), Miners -- DKGCompletedNodes),
RadioPorts = [ P || {_Miner, {_TP, P}} <- MinersAndPorts ],
miner_fake_radio_backplane:start_link(8, 45000, lists:zip(RadioPorts, Locations)),
GenesisBlock = miner_ct_utils:get_genesis_block(Miners, Config),
timer:sleep(5000),
ok = miner_ct_utils:load_genesis_block(GenesisBlock, Miners, Config),
miner_fake_radio_backplane ! go,
Config
catch
......@@ -59,7 +54,7 @@ init_per_testcase(TestCase, Config0) ->
end.
end_per_testcase(TestCase, Config) ->
gen_server:stop(miner_fake_radio_backplane),
catch gen_server:stop(miner_fake_radio_backplane),
miner_ct_utils:end_per_testcase(TestCase, Config).
basic_test(Config) ->
......
......@@ -61,14 +61,13 @@ init_per_testcase(_TestCase, Config0) ->
?dkg_curve => Curve,
?allow_zero_amount => false}),
DKGResults = miner_ct_utils:initial_dkg(Miners, InitialVars ++ InitialPaymentTransactions ++ AddGwTxns,
{ok, DKGCompletedNodes} = miner_ct_utils:initial_dkg(Miners, InitialVars ++ InitialPaymentTransactions ++ AddGwTxns,
Addresses, NumConsensusMembers, Curve),
true = lists:all(fun(Res) -> Res == ok end, DKGResults),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(DKGCompletedNodes), Miners -- DKGCompletedNodes),
%% Get both consensus and non consensus miners
{ConsensusMiners, NonConsensusMiners} = miner_ct_utils:miners_by_consensus_state(Miners),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(ConsensusMiners), NonConsensusMiners),
%% confirm we have a height of 1
ok = miner_ct_utils:wait_for_gte(height, Miners, 2),
......
......@@ -58,14 +58,14 @@ init_per_testcase(_TestCase, Config0) ->
?max_payments => 10,
?allow_zero_amount => false}),
DKGResults = miner_ct_utils:initial_dkg(Miners, InitialVars ++ InitialPaymentTransactions ++ AddGwTxns,
{ok, DKGCompletedNodes} = miner_ct_utils:initial_dkg(Miners, InitialVars ++ InitialPaymentTransactions ++ AddGwTxns,
Addresses, NumConsensusMembers, Curve),
true = lists:all(fun(Res) -> Res == ok end, DKGResults),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(DKGCompletedNodes), Miners -- DKGCompletedNodes),
%% Get both consensus and non consensus miners
{ConsensusMiners, NonConsensusMiners} = miner_ct_utils:miners_by_consensus_state(Miners),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(ConsensusMiners), NonConsensusMiners),
ok = miner_ct_utils:wait_for_gte(height, Miners, 2),
......
......@@ -335,7 +335,7 @@ basic_test(Config) ->
ok = add_block(Chain, ConsensusMembers, []),
timer:sleep(100)
end,
lists:seq(1, 10)
lists:seq(1, 20)
),
?assertEqual(receiving, erlang:element(1, sys:get_state(Statem))),
......@@ -929,14 +929,12 @@ initialize_chain(Miners, TestCase, Config, VarMap) ->
AddressesWithClaimedLocations = lists:zip(Addresses, ClaimedLocations),
InitialGenGatewayTxns = [blockchain_txn_gen_gateway_v1:new(Addr, Addr, Loc, 0) || {Addr, Loc} <- AddressesWithLocations],
InitialTransactions = InitialVars ++ InitialPaymentTransactions ++ InitialGenGatewayTxns,
DKGResults = miner_ct_utils:pmap(
fun(Miner) ->
ct_rpc:call(Miner, miner_consensus_mgr, initial_dkg, [InitialTransactions, Addresses, N, Curve])
end,
Miners
),
ct:pal("results ~p", [DKGResults]),
?assert(lists:all(fun(Res) -> Res == ok end, DKGResults)),
{ok, DKGCompletedNodes} = miner_ct_utils:initial_dkg(Miners, InitialTransactions, Addresses, N, Curve),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(DKGCompletedNodes), Miners -- DKGCompletedNodes),
AddressesWithClaimedLocations.
find_requests(Miners) ->
......
......@@ -53,9 +53,11 @@ init_per_testcase(_TestCase, Config0) ->
?batch_size => BatchSize,
?dkg_curve => Curve}),
DKGResults = miner_ct_utils:initial_dkg(Miners, InitialVars ++ InitialCoinbaseTxns ++ AddGwTxns,
{ok, DKGCompletedNodes} = miner_ct_utils:initial_dkg(Miners, InitialVars ++ InitialCoinbaseTxns ++ AddGwTxns,
Addresses, NumConsensusMembers, Curve),
true = lists:all(fun(Res) -> Res == ok end, DKGResults),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(DKGCompletedNodes), Miners -- DKGCompletedNodes),
ok = miner_ct_utils:wait_for_in_consensus(Miners, NumConsensusMembers),
......@@ -68,9 +70,7 @@ init_per_testcase(_TestCase, Config0) ->
%% Get consensus miners
ConsensusMiners = miner_ct_utils:in_consensus_miners(Miners),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(ConsensusMiners), NonConsensusMiners),
%% confirm height is 1
ok = miner_ct_utils:wait_for_gte(height, Miners, 2),
......
......@@ -74,24 +74,15 @@ init_per_testcase(_TestCase, Config0) ->
?batch_size => BatchSize,
?dkg_curve => Curve}),
DKGResults = miner_ct_utils:initial_dkg(Miners, InitialVars ++ InitialPaymentTransactions ++ InitialDCTransactions ++ InitialGenGatewayTxns,
{ok, DKGCompletedNodes} = miner_ct_utils:initial_dkg(Miners, InitialVars ++ InitialPaymentTransactions ++ InitialDCTransactions ++ InitialGenGatewayTxns,
Addresses, NumConsensusMembers, Curve),
true = lists:all(fun(Res) -> Res == ok end, DKGResults),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(DKGCompletedNodes), Miners -- DKGCompletedNodes),
RadioPorts = [ P || {_Miner, {_TP, P}} <- MinersAndPorts ],
miner_fake_radio_backplane:start_link(8, 45000, lists:zip(RadioPorts, Locations)),
%% Get both consensus and non consensus miners
{ConsensusMiners, NonConsensusMiners} = miner_ct_utils:miners_by_consensus_state(Miners),
%% ensure that blockchain is undefined for non_consensus miners
false = miner_ct_utils:blockchain_worker_check(NonConsensusMiners),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(ConsensusMiners), NonConsensusMiners),
%% confirm height has grown to 1
ok = miner_ct_utils:wait_for_gte(height, Miners, 2),
......
......@@ -146,15 +146,14 @@ init_per_testcase(TestCase, Config0) ->
AllVars = miner_ct_utils:make_vars(Keys, maps:merge(BaseVars0, maps:merge(SCVars, RewardVars))),
ct:pal("AllVars: ~p", [AllVars]),
DKGResults = miner_ct_utils:initial_dkg(Miners,
{ok, DKGCompletedNodes} = miner_ct_utils:initial_dkg(Miners,
AllVars ++ InitialPaymentTransactions ++ AddGwTxns ++ InitialDCTxns ++ [InitialPriceTxn],
Addresses, NumConsensusMembers, Curve),
true = lists:all(fun(Res) -> Res == ok end, DKGResults),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(DKGCompletedNodes), Miners -- DKGCompletedNodes),
%% Get both consensus and non consensus miners
{ConsensusMiners, NonConsensusMiners} = miner_ct_utils:miners_by_consensus_state(Miners),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(ConsensusMiners), NonConsensusMiners),
ListenNode = lists:last(Miners),
......
......@@ -65,14 +65,13 @@ init_per_testcase(_TestCase, Config0) ->
?transfer_hotspot_stale_poc_blocks => 100,
?allow_zero_amount => false}),
DKGResults = miner_ct_utils:initial_dkg(Miners, InitialVars ++ InitialPaymentTransactions ++ AddGwTxns,
{ok, DKGCompletedNodes} = miner_ct_utils:initial_dkg(Miners, InitialVars ++ InitialPaymentTransactions ++ AddGwTxns,
Addresses, NumConsensusMembers, Curve),
true = lists:all(fun(Res) -> Res == ok end, DKGResults),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(DKGCompletedNodes), Miners -- DKGCompletedNodes),
%% Get both consensus and non consensus miners
{ConsensusMiners, NonConsensusMiners} = miner_ct_utils:miners_by_consensus_state(Miners),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(ConsensusMiners), NonConsensusMiners),
ok = miner_ct_utils:wait_for_gte(height, Miners, 2),
......
......@@ -79,15 +79,15 @@ init_per_testcase(_TestCase, Config0) ->
?batch_size => BatchSize,
?dkg_curve => Curve}),
DKGResults = miner_ct_utils:initial_dkg(Miners, InitialVars ++ InitialCoinbaseTxns ++ CoinbaseDCTxns ++ AddGwTxns,
{ok, DKGCompletedNodes} = miner_ct_utils:initial_dkg(Miners, InitialVars ++ InitialCoinbaseTxns ++ CoinbaseDCTxns ++ AddGwTxns,
Addresses, NumConsensusMembers, Curve),
true = lists:all(fun(Res) -> Res == ok end, DKGResults),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(DKGCompletedNodes), Miners -- DKGCompletedNodes),
%% Get both consensus and non consensus miners
{ConsensusMiners, NonConsensusMiners} = miner_ct_utils:miners_by_consensus_state(Miners),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(ConsensusMiners), NonConsensusMiners),
[
{consensus_miners, ConsensusMiners},
{non_consensus_miners, NonConsensusMiners}
......
......@@ -47,7 +47,12 @@ init_per_testcase(_TestCase, Config0) ->
|| Addr <- Addresses],
NumConsensusMembers = ?config(num_consensus_members, Config),
BlockTime = ?config(block_time, Config),
BlockTime =
case _TestCase of
txn_dependent_test -> 2000;
_ -> ?config(block_time, Config)
end,
BatchSize = ?config(batch_size, Config),
Curve = ?config(dkg_curve, Config),
......@@ -60,14 +65,14 @@ init_per_testcase(_TestCase, Config0) ->
?batch_size => BatchSize,
?dkg_curve => Curve}),
DKGResults = miner_ct_utils:initial_dkg(Miners, InitialVars ++ InitialPaymentTransactions ++ AddGwTxns,
{ok, DKGCompletionNodes} = miner_ct_utils:initial_dkg(Miners, InitialVars ++ InitialPaymentTransactions ++ AddGwTxns,
Addresses, NumConsensusMembers, Curve),
true = lists:all(fun(Res) -> Res == ok end, DKGResults),
ct:pal("Nodes which completed the DKG: ~p", [DKGCompletionNodes]),
%% Get both consensus and non consensus miners
{ConsensusMiners, NonConsensusMiners} = miner_ct_utils:miners_by_consensus_state(Miners),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(ConsensusMiners), NonConsensusMiners),
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(DKGCompletionNodes), Miners -- DKGCompletionNodes),
ct:pal("genesis load results: ~p", [_GenesisLoadResults]),
%% confirm we have a height of 1
ok = miner_ct_utils:wait_for_gte(height, Miners, 2),
......@@ -136,8 +141,6 @@ txn_in_sequence_nonce_test(Config) ->
ok.
txn_out_of_sequence_nonce_test(Config) ->
%% send two standalone payments, but out of order so that the first submitted has an out of sequence nonce
%% this will result in validations determining undecided and the txn stays in txn mgr cache
......@@ -207,7 +210,6 @@ txn_out_of_sequence_nonce_test(Config) ->
ok.
txn_invalid_nonce_test(Config) ->
%% send two standalone payments, the second with a duplicate/invalid nonce
%% the first txn will be successful, the second should be declared invalid
......@@ -270,45 +272,80 @@ txn_invalid_nonce_test(Config) ->
ok.
txn_dependent_test(Config) ->
%% send a bunch of dependent txns
%% give them time to be accepted by the CG group and
%% send a bunch of out of order dependent txns
%% they should all end up being accepted in the *same* block
%% but only after the txn with the lowest sequenced nonce is submitted
%% as until that happens none will pass validations
%% confirm the 3 txns remain in the txn mgr cache until the missing txn is submitted
%% after which we confirm the txn mgr cache empties due to the txns being accepted
%% confirm we dont have any strays in the txn mgr cache at the end of it
Miners = ?config(miners, Config),
Miner = hd(?config(non_consensus_miners, Config)),
ConMiners = ?config(consensus_miners, Config),
AddrList = ?config(tagged_miner_addresses, Config),
Count = 50,
Addr = miner_ct_utils:node2addr(Miner, AddrList),
Chain = ct_rpc:call(Miner, blockchain_worker, blockchain, []),
ct:pal("miner in use ~p", [Miner]),
PayerAddr = Addr,
Payee = hd(miner_ct_utils:shuffle(ConMiners)),
PayeeAddr = miner_ct_utils:node2addr(Payee, AddrList),
{ok, _Pubkey, SigFun, _ECDHFun} = ct_rpc:call(Miner, blockchain_swarm, keys, []),
IgnoredTxns = [],
IgnoredTxns = [blockchain_txn_poc_request_v1_pb],
StartNonce = miner_ct_utils:get_nonce(Miner, Addr),
%% send a bunch of dependant txns and ensure they are processed by the txn mgr
%% and dont hang around it its cache
UnsignedTxns = [ ct_rpc:call(Miner, blockchain_txn_payment_v1, new, [PayerAddr, PayeeAddr, 1, Nonce]) || Nonce <- lists:seq(1, Count) ],
SignedTxns = [ ct_rpc:call(Miner, blockchain_txn_payment_v1, sign, [Txn, SigFun]) || Txn <- UnsignedTxns],
[ ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [SignedTxn]) || SignedTxn <- miner_ct_utils:shuffle(SignedTxns) ],
%% prep the txns, 1 - 4
Txn1 = ct_rpc:call(Miner, blockchain_txn_payment_v1, new, [PayerAddr, PayeeAddr, 1000, StartNonce+1]),
SignedTxn1 = ct_rpc:call(Miner, blockchain_txn_payment_v1, sign, [Txn1, SigFun]),
Txn2 = ct_rpc:call(Miner, blockchain_txn_payment_v1, new, [PayerAddr, PayeeAddr, 1000, StartNonce+2]),
SignedTxn2 = ct_rpc:call(Miner, blockchain_txn_payment_v1, sign, [Txn2, SigFun]),
Txn3 = ct_rpc:call(Miner, blockchain_txn_payment_v1, new, [PayerAddr, PayeeAddr, 1000, StartNonce+3]),
SignedTxn3 = ct_rpc:call(Miner, blockchain_txn_payment_v1, sign, [Txn3, SigFun]),
Txn4 = ct_rpc:call(Miner, blockchain_txn_payment_v1, new, [PayerAddr, PayeeAddr, 1000, StartNonce+4]),
SignedTxn4 = ct_rpc:call(Miner, blockchain_txn_payment_v1, sign, [Txn4, SigFun]),
%% get the start height
{ok, Height} = ct_rpc:call(Miner, blockchain, height, [Chain]),
%% send txns with nonces 2, 3 and 4, all out of sequence
%% we wont send txn with nonce 1 yet
%% this means the 3 submitted txns cannot be accepted and will remain in the txn mgr cache
%% until txn with nonce 1 gets submitted
ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [SignedTxn2]),
ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [SignedTxn4]),
ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [SignedTxn3]),
Result1 = miner_ct_utils:wait_until(
%% Wait a few blocks, confirm txns remain in the cache
ok = miner_ct_utils:wait_for_gte(height_exactly, Miners, Height + 3),
%% confirm all txns are still be in txn mgr cache
true = miner_ct_utils:wait_until(
fun()->
case get_cached_txns_with_exclusions(Miner, IgnoredTxns) of
#{} -> true;
_ -> false
end
end, 60, 2000),
ok = handle_get_cached_txn_result(Result1, Miner, IgnoredTxns, Chain),
maps:size(get_cached_txns_with_exclusions(Miner, IgnoredTxns)) == 3
end, 60, 100),
%% check the miners nonce values to be sure the txns have actually been absorbed and not just lost
ExpectedNonce = StartNonce +50,
%% now submit the remaining txn which will have the missing nonce
%% this should result in both this and the previous txns being accepted by the CG
%% and cleared out of the txn mgr cache
ok = ct_rpc:call(Miner, blockchain_worker, submit_txn, [SignedTxn1]),
%% Wait one more block
ok = miner_ct_utils:wait_for_gte(height_exactly, Miners, Height + 4),
%% confirm all txns are are gone from the cache within the span of a single block
%% ie they are not carrying across blocks
true = miner_ct_utils:wait_until(
fun()->
maps:size(get_cached_txns_with_exclusions(Miner, IgnoredTxns)) == 0
end, 60, 100),
ok = miner_ct_utils:wait_for_gte(height_exactly, Miners, Height + 5),
ExpectedNonce = StartNonce +4,
true = nonce_updated_for_miner(Addr, ExpectedNonce, ConMiners),
ok.
......@@ -331,11 +368,14 @@ handle_get_cached_txn_result(Result, Miner, IgnoredTxns, Chain)->
get_cached_txns_with_exclusions(Miner, Exclusions)->
case ct_rpc:call(Miner, blockchain_txn_mgr, txn_list, []) of
#{} -> #{};
Txns ->
TxnMap when map_size(TxnMap) > 0 ->
ct:pal("~p txns in txn list", [maps:size(TxnMap)]),
maps:filter(
fun(Txn, _TxnData)->
not lists:member(blockchain_txn:type(Txn), Exclusions) end, Txns)
not lists:member(blockchain_txn:type(Txn), Exclusions) end, TxnMap);
_ ->
ct:pal("empty txn map", []),
#{}
end.
nonce_updated_for_miner(Addr, ExpectedNonce, ConMiners)->
......
......@@ -158,14 +158,12 @@ initialize_chain(Miners, TestCase, Config, VarMap, Keys) ->
AddressesWithClaimedLocations = lists:zip(Addresses, ClaimedLocations),
InitialGenGatewayTxns = [blockchain_txn_gen_gateway_v1:new(Addr, Addr, Loc, 0) || {Addr, Loc} <- AddressesWithLocations],
InitialTransactions = InitialVars ++ InitialPaymentTransactions ++ InitialGenGatewayTxns,
DKGResults = miner_ct_utils:pmap(
fun(Miner) ->
ct_rpc:call(Miner, miner_consensus_mgr, initial_dkg, [InitialTransactions, Addresses, N, Curve])
end,
Miners
),
ct:pal("results ~p", [DKGResults]),
?assert(lists:all(fun(Res) -> Res == ok end, DKGResults)),
{ok, DKGCompletedNodes} = miner_ct_utils:initial_dkg(Miners, InitialTransactions, Addresses, N, Curve),
%% integrate genesis block
_GenesisLoadResults = miner_ct_utils:integrate_genesis_block(hd(DKGCompletedNodes), Miners -- DKGCompletedNodes),
AddressesWithClaimedLocations.
get_genesis_block(Miners, Config) ->
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment