@@ -174,6 +174,16 @@ inline std::vector<OutputGroup>& KnapsackGroupOutputs(const CoinsResult& availab
174174 return static_groups.all_groups .mixed_group ;
175175}
176176
177+ static std::unique_ptr<CWallet> NewWallet (const node::NodeContext& m_node, const std::string& wallet_name = " " )
178+ {
179+ std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain .get (), wallet_name, CreateMockWalletDatabase ());
180+ BOOST_CHECK (wallet->LoadWallet () == DBErrors::LOAD_OK);
181+ LOCK (wallet->cs_wallet );
182+ wallet->SetWalletFlag (WALLET_FLAG_DESCRIPTORS);
183+ wallet->SetupDescriptorScriptPubKeyMans ();
184+ return wallet;
185+ }
186+
177187// Branch and bound coin selection tests
178188BOOST_AUTO_TEST_CASE (bnb_search_test)
179189{
@@ -310,11 +320,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
310320 coin_selection_params_bnb.m_subtract_fee_outputs = true ;
311321
312322 {
313- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain .get (), " " , CreateMockWalletDatabase ());
314- wallet->LoadWallet ();
315- LOCK (wallet->cs_wallet );
316- wallet->SetWalletFlag (WALLET_FLAG_DESCRIPTORS);
317- wallet->SetupDescriptorScriptPubKeyMans ();
323+ std::unique_ptr<CWallet> wallet = NewWallet (m_node);
318324
319325 CoinsResult available_coins;
320326
@@ -332,11 +338,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
332338 }
333339
334340 {
335- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain .get (), " " , CreateMockWalletDatabase ());
336- wallet->LoadWallet ();
337- LOCK (wallet->cs_wallet );
338- wallet->SetWalletFlag (WALLET_FLAG_DESCRIPTORS);
339- wallet->SetupDescriptorScriptPubKeyMans ();
341+ std::unique_ptr<CWallet> wallet = NewWallet (m_node);
340342
341343 CoinsResult available_coins;
342344
@@ -351,15 +353,13 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
351353 selected_input.Insert (select_coin, coin_selection_params_bnb.m_subtract_fee_outputs );
352354 available_coins.Erase ({available_coins.coins [OutputType::BECH32].begin ()->outpoint });
353355 coin_selection_params_bnb.m_effective_feerate = CFeeRate (0 );
356+ LOCK (wallet->cs_wallet );
354357 const auto result10 = SelectCoins (*wallet, available_coins, selected_input, 10 * CENT, coin_control, coin_selection_params_bnb);
355358 BOOST_CHECK (result10);
356359 }
357360 {
358- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain .get (), " " , CreateMockWalletDatabase ());
359- wallet->LoadWallet ();
360- LOCK (wallet->cs_wallet );
361- wallet->SetWalletFlag (WALLET_FLAG_DESCRIPTORS);
362- wallet->SetupDescriptorScriptPubKeyMans ();
361+ std::unique_ptr<CWallet> wallet = NewWallet (m_node);
362+ LOCK (wallet->cs_wallet ); // Every 'SelectCoins' call requires it
363363
364364 CoinsResult available_coins;
365365
@@ -418,11 +418,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
418418 // Test bnb max weight exceeded
419419 // Inputs set [10, 9, 8, 5, 3, 1], Selection Target = 16 and coin 5 exceeding the max weight.
420420
421- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain .get (), " " , m_args, CreateMockWalletDatabase ());
422- wallet->LoadWallet ();
423- LOCK (wallet->cs_wallet );
424- wallet->SetWalletFlag (WALLET_FLAG_DESCRIPTORS);
425- wallet->SetupDescriptorScriptPubKeyMans ();
421+ std::unique_ptr<CWallet> wallet = NewWallet (m_node);
426422
427423 CoinsResult available_coins;
428424 add_coin (available_coins, *wallet, 10 * CENT, coin_selection_params_bnb.m_effective_feerate , 6 * 24 , false , 0 , true );
@@ -455,11 +451,7 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
455451 FastRandomContext rand{};
456452 const auto temp1{[&rand](std::vector<OutputGroup>& g, const CAmount& v, CAmount c) { return KnapsackSolver (g, v, c, rand); }};
457453 const auto KnapsackSolver{temp1};
458- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain .get (), " " , CreateMockWalletDatabase ());
459- wallet->LoadWallet ();
460- LOCK (wallet->cs_wallet );
461- wallet->SetWalletFlag (WALLET_FLAG_DESCRIPTORS);
462- wallet->SetupDescriptorScriptPubKeyMans ();
454+ std::unique_ptr<CWallet> wallet = NewWallet (m_node);
463455
464456 CoinsResult available_coins;
465457
@@ -765,11 +757,7 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
765757BOOST_AUTO_TEST_CASE (ApproximateBestSubset)
766758{
767759 FastRandomContext rand{};
768- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain .get (), " " , CreateMockWalletDatabase ());
769- wallet->LoadWallet ();
770- LOCK (wallet->cs_wallet );
771- wallet->SetWalletFlag (WALLET_FLAG_DESCRIPTORS);
772- wallet->SetupDescriptorScriptPubKeyMans ();
760+ std::unique_ptr<CWallet> wallet = NewWallet (m_node);
773761
774762 CoinsResult available_coins;
775763
@@ -787,11 +775,8 @@ BOOST_AUTO_TEST_CASE(ApproximateBestSubset)
787775// Tests that with the ideal conditions, the coin selector will always be able to find a solution that can pay the target value
788776BOOST_AUTO_TEST_CASE (SelectCoins_test)
789777{
790- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain .get (), " " , CreateMockWalletDatabase ());
791- wallet->LoadWallet ();
792- LOCK (wallet->cs_wallet );
793- wallet->SetWalletFlag (WALLET_FLAG_DESCRIPTORS);
794- wallet->SetupDescriptorScriptPubKeyMans ();
778+ std::unique_ptr<CWallet> wallet = NewWallet (m_node);
779+ LOCK (wallet->cs_wallet ); // Every 'SelectCoins' call requires it
795780
796781 // Random generator stuff
797782 std::default_random_engine generator;
@@ -979,12 +964,7 @@ static util::Result<SelectionResult> SelectCoinsSRD(const CAmount& target,
979964 int max_weight,
980965 std::function<CoinsResult(CWallet&)> coin_setup)
981966{
982- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain .get (), " " , CreateMockWalletDatabase ());
983- wallet->LoadWallet ();
984- LOCK (wallet->cs_wallet );
985- wallet->SetWalletFlag (WALLET_FLAG_DESCRIPTORS);
986- wallet->SetupDescriptorScriptPubKeyMans ();
987-
967+ std::unique_ptr<CWallet> wallet = NewWallet (m_node);
988968 CoinEligibilityFilter filter (0 , 0 , 0 ); // accept all coins without ancestors
989969 Groups group = GroupOutputs (*wallet, coin_setup (*wallet), cs_params, {{filter}})[filter].all_groups ;
990970 return SelectCoinsSRD (group.positive_group , target, cs_params.rng_fast , max_weight);
@@ -1066,16 +1046,12 @@ BOOST_AUTO_TEST_CASE(srd_tests)
10661046 }
10671047}
10681048
1069- static util::Result<SelectionResult> select_coins (const CAmount& target, const CoinSelectionParams& cs_params, const CCoinControl& cc, std::function<CoinsResult(CWallet&)> coin_setup, interfaces::Chain* chain )
1049+ static util::Result<SelectionResult> select_coins (const CAmount& target, const CoinSelectionParams& cs_params, const CCoinControl& cc, std::function<CoinsResult(CWallet&)> coin_setup, const node::NodeContext& m_node )
10701050{
1071- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(chain, " " , CreateMockWalletDatabase ());
1072- wallet->LoadWallet ();
1073- LOCK (wallet->cs_wallet );
1074- wallet->SetWalletFlag (WALLET_FLAG_DESCRIPTORS);
1075- wallet->SetupDescriptorScriptPubKeyMans ();
1076-
1051+ std::unique_ptr<CWallet> wallet = NewWallet (m_node);
10771052 auto available_coins = coin_setup (*wallet);
10781053
1054+ LOCK (wallet->cs_wallet );
10791055 auto result = SelectCoins (*wallet, available_coins, /* pre_set_inputs=*/ {}, target, cc, cs_params);
10801056 if (result) {
10811057 const auto signedTxSize = 10 + 34 + 68 * result->GetInputSet ().size (); // static header size + output size + inputs size (P2WPKH)
@@ -1109,8 +1085,6 @@ BOOST_AUTO_TEST_CASE(check_max_weight)
11091085 /* avoid_partial=*/ false ,
11101086 };
11111087
1112- auto chain{m_node.chain .get ()};
1113-
11141088 {
11151089 // Scenario 1:
11161090 // The actor starts with 1x 50.0 BTC and 1515x 0.033 BTC (~100.0 BTC total) unspent outputs
@@ -1129,7 +1103,7 @@ BOOST_AUTO_TEST_CASE(check_max_weight)
11291103 add_coin (available_coins, wallet, CAmount (50 * COIN), CFeeRate (0 ), 144 , false , 0 , true );
11301104 return available_coins;
11311105 },
1132- chain );
1106+ m_node );
11331107
11341108 BOOST_CHECK (result);
11351109 // Verify that only the 50 BTC UTXO was selected
@@ -1157,7 +1131,7 @@ BOOST_AUTO_TEST_CASE(check_max_weight)
11571131 }
11581132 return available_coins;
11591133 },
1160- chain );
1134+ m_node );
11611135
11621136 BOOST_CHECK (has_coin (result->GetInputSet (), CAmount (0.0625 * COIN)));
11631137 BOOST_CHECK (has_coin (result->GetInputSet (), CAmount (0.025 * COIN)));
@@ -1178,7 +1152,7 @@ BOOST_AUTO_TEST_CASE(check_max_weight)
11781152 }
11791153 return available_coins;
11801154 },
1181- chain );
1155+ m_node );
11821156
11831157 // No results
11841158 // 1515 inputs * 68 bytes = 103,020 bytes
@@ -1193,20 +1167,11 @@ BOOST_AUTO_TEST_CASE(SelectCoins_effective_value_test)
11931167 // This test creates a coin whose value is higher than the target but whose effective value is lower than the target.
11941168 // The coin is selected using coin control, with m_allow_other_inputs = false. SelectCoins should fail due to insufficient funds.
11951169
1196- std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain .get (), " " , CreateMockWalletDatabase ());
1197- wallet->LoadWallet ();
1198- LOCK (wallet->cs_wallet );
1199- wallet->SetWalletFlag (WALLET_FLAG_DESCRIPTORS);
1200- wallet->SetupDescriptorScriptPubKeyMans ();
1170+ std::unique_ptr<CWallet> wallet = NewWallet (m_node);
12011171
12021172 CoinsResult available_coins;
12031173 {
1204- std::unique_ptr<CWallet> dummyWallet = std::make_unique<CWallet>(m_node.chain .get (), " dummy" , CreateMockWalletDatabase ());
1205- dummyWallet->LoadWallet ();
1206- LOCK (dummyWallet->cs_wallet );
1207- dummyWallet->SetWalletFlag (WALLET_FLAG_DESCRIPTORS);
1208- dummyWallet->SetupDescriptorScriptPubKeyMans ();
1209-
1174+ std::unique_ptr<CWallet> dummyWallet = NewWallet (m_node, /* wallet_name=*/ " dummy" );
12101175 add_coin (available_coins, *dummyWallet, 100000 ); // 0.001 BTC
12111176 }
12121177
@@ -1230,6 +1195,7 @@ BOOST_AUTO_TEST_CASE(SelectCoins_effective_value_test)
12301195 cc.SetInputWeight (output.outpoint , 148 );
12311196 cc.SelectExternal (output.outpoint , output.txout );
12321197
1198+ LOCK (wallet->cs_wallet );
12331199 const auto preset_inputs = *Assert (FetchSelectedInputs (*wallet, cc, cs_params));
12341200 available_coins.Erase ({available_coins.coins [OutputType::BECH32].begin ()->outpoint });
12351201
@@ -1242,11 +1208,7 @@ BOOST_FIXTURE_TEST_CASE(wallet_coinsresult_test, BasicTestingSetup)
12421208 // Test case to verify CoinsResult object sanity.
12431209 CoinsResult available_coins;
12441210 {
1245- std::unique_ptr<CWallet> dummyWallet = std::make_unique<CWallet>(m_node.chain .get (), " dummy" , CreateMockWalletDatabase ());
1246- BOOST_CHECK_EQUAL (dummyWallet->LoadWallet (), DBErrors::LOAD_OK);
1247- LOCK (dummyWallet->cs_wallet );
1248- dummyWallet->SetWalletFlag (WALLET_FLAG_DESCRIPTORS);
1249- dummyWallet->SetupDescriptorScriptPubKeyMans ();
1211+ std::unique_ptr<CWallet> dummyWallet = NewWallet (m_node, /* wallet_name=*/ " dummy" );
12501212
12511213 // Add some coins to 'available_coins'
12521214 for (int i=0 ; i<10 ; i++) {
0 commit comments