Skip to content

Commit 0e9105e

Browse files
Merge #6550: backport: bitcoin#25784, 25878, 25865, 25879
b50fa09 Merge bitcoin#25879: refactor: Make Join() util work with any container type (MacroFake) ce0a046 Merge bitcoin#25865: test: speedup wallet tests by whitelisting peers (immediate tx relay) (MacroFake) 4acf37e Merge bitcoin#25878: tests: Use mocktime for wallet encryption timeout (MacroFake) e6d958f Merge bitcoin#25784: Wallet: Document expectations for AddWalletFlags (now InitWalletFlags) correctly (Andrew Chow) Pull request description: Bitcoin Backporting ACKs for top commit: UdjinM6: utACK b50fa09 PastaPastaPasta: utACK b50fa09 Tree-SHA512: b2bc3de9fba619a5a195da37b602c31b22e313265095b0b24cca56aa3b25a8be7bc4de9886b22d27e51de6f6457fa9e508c22e7139fe7b31c1d4dab551276a43
2 parents bb46968 + b50fa09 commit 0e9105e

15 files changed

+64
-61
lines changed

src/blockfilter.cpp

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

55
#include <mutex>
6-
#include <sstream>
76
#include <set>
87

98
#include <blockfilter.h>
@@ -13,6 +12,7 @@
1312
#include <script/script.h>
1413
#include <streams.h>
1514
#include <util/golombrice.h>
15+
#include <util/string.h>
1616

1717
/// SerType used to serialize parameters in GCS filter encoding.
1818
static constexpr int GCS_SER_TYPE = SER_NETWORK;
@@ -179,19 +179,7 @@ const std::set<BlockFilterType>& AllBlockFilterTypes()
179179

180180
const std::string& ListBlockFilterTypes()
181181
{
182-
static std::string type_list;
183-
184-
static std::once_flag flag;
185-
std::call_once(flag, []() {
186-
std::stringstream ret;
187-
bool first = true;
188-
for (auto entry : g_filter_types) {
189-
if (!first) ret << ", ";
190-
ret << entry.second;
191-
first = false;
192-
}
193-
type_list = ret.str();
194-
});
182+
static std::string type_list{Join(g_filter_types, ", ", [](const auto& entry) { return entry.second; })};
195183

196184
return type_list;
197185
}

src/test/util_tests.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -250,15 +250,15 @@ BOOST_AUTO_TEST_CASE(span_write_bytes)
250250
BOOST_AUTO_TEST_CASE(util_Join)
251251
{
252252
// Normal version
253-
BOOST_CHECK_EQUAL(Join({}, ", "), "");
254-
BOOST_CHECK_EQUAL(Join({"foo"}, ", "), "foo");
255-
BOOST_CHECK_EQUAL(Join({"foo", "bar"}, ", "), "foo, bar");
253+
BOOST_CHECK_EQUAL(Join(std::vector<std::string>{}, ", "), "");
254+
BOOST_CHECK_EQUAL(Join(std::vector<std::string>{"foo"}, ", "), "foo");
255+
BOOST_CHECK_EQUAL(Join(std::vector<std::string>{"foo", "bar"}, ", "), "foo, bar");
256256

257257
// Version with unary operator
258258
const auto op_upper = [](const std::string& s) { return ToUpper(s); };
259-
BOOST_CHECK_EQUAL(Join<std::string>({}, ", ", op_upper), "");
260-
BOOST_CHECK_EQUAL(Join<std::string>({"foo"}, ", ", op_upper), "FOO");
261-
BOOST_CHECK_EQUAL(Join<std::string>({"foo", "bar"}, ", ", op_upper), "FOO, BAR");
259+
BOOST_CHECK_EQUAL(Join(std::list<std::string>{}, ", ", op_upper), "");
260+
BOOST_CHECK_EQUAL(Join(std::list<std::string>{"foo"}, ", ", op_upper), "FOO");
261+
BOOST_CHECK_EQUAL(Join(std::list<std::string>{"foo", "bar"}, ", ", op_upper), "FOO, BAR");
262262
}
263263

264264
BOOST_AUTO_TEST_CASE(util_ReplaceAll)

src/util/string.h

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,34 +58,30 @@ void ReplaceAll(std::string& in_out, const std::string& search, const std::strin
5858
}
5959

6060
/**
61-
* Join a list of items
61+
* Join all container items. Typically used to concatenate strings but accepts
62+
* containers with elements of any type.
6263
*
63-
* @param list The list to join
64-
* @param separator The separator
65-
* @param unary_op Apply this operator to each item in the list
64+
* @param container The items to join
65+
* @param separator The separator
66+
* @param unary_op Apply this operator to each item
6667
*/
67-
template <typename T, typename BaseType, typename UnaryOp>
68-
auto Join(const std::vector<T>& list, const BaseType& separator, UnaryOp unary_op)
69-
-> decltype(unary_op(list.at(0)))
68+
template <typename C, typename S, typename UnaryOp>
69+
auto Join(const C& container, const S& separator, UnaryOp unary_op)
7070
{
71-
decltype(unary_op(list.at(0))) ret;
72-
for (size_t i = 0; i < list.size(); ++i) {
73-
if (i > 0) ret += separator;
74-
ret += unary_op(list.at(i));
71+
decltype(unary_op(*container.begin())) ret;
72+
bool first{true};
73+
for (const auto& item : container) {
74+
if (!first) ret += separator;
75+
ret += unary_op(item);
76+
first = false;
7577
}
7678
return ret;
7779
}
7880

79-
template <typename T, typename T2>
80-
T Join(const std::vector<T>& list, const T2& separator)
81+
template <typename C, typename S>
82+
auto Join(const C& container, const S& separator)
8183
{
82-
return Join(list, separator, [](const T& i) { return i; });
83-
}
84-
85-
// Explicit overload needed for c_str arguments, which would otherwise cause a substitution failure in the template above.
86-
inline std::string Join(const std::vector<std::string>& list, std::string_view separator)
87-
{
88-
return Join<std::string>(list, separator);
84+
return Join(container, separator, [](const auto& i) { return i; });
8985
}
9086

9187
/**

src/wallet/wallet.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1655,16 +1655,20 @@ bool CWallet::LoadWalletFlags(uint64_t flags)
16551655
return true;
16561656
}
16571657

1658-
bool CWallet::AddWalletFlags(uint64_t flags)
1658+
void CWallet::InitWalletFlags(uint64_t flags)
16591659
{
16601660
LOCK(cs_wallet);
1661+
16611662
// We should never be writing unknown non-tolerable wallet flags
16621663
assert(((flags & KNOWN_WALLET_FLAGS) >> 32) == (flags >> 32));
1664+
// This should only be used once, when creating a new wallet - so current flags are expected to be blank
1665+
assert(m_wallet_flags == 0);
1666+
16631667
if (!WalletBatch(GetDatabase()).WriteWalletFlags(flags)) {
16641668
throw std::runtime_error(std::string(__func__) + ": writing wallet flags failed");
16651669
}
16661670

1667-
return LoadWalletFlags(flags);
1671+
if (!LoadWalletFlags(flags)) assert(false);
16681672
}
16691673

16701674
// Helper for producing a max-sized low-S low-R signature (eg 71 bytes)
@@ -3297,7 +3301,7 @@ std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain* chain, interfaces::C
32973301
{
32983302
walletInstance->SetMinVersion(FEATURE_LATEST);
32993303

3300-
walletInstance->AddWalletFlags(wallet_creation_flags);
3304+
walletInstance->InitWalletFlags(wallet_creation_flags);
33013305

33023306
// Only create LegacyScriptPubKeyMan when not descriptor wallet
33033307
if (!walletInstance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {

src/wallet/wallet.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -965,8 +965,9 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
965965
bool IsWalletFlagSet(uint64_t flag) const override;
966966

967967
/** overwrite all flags by the given uint64_t
968-
returns false if unknown, non-tolerable flags are present */
969-
bool AddWalletFlags(uint64_t flags);
968+
flags must be uninitialised (or 0)
969+
only known flags may be present */
970+
void InitWalletFlags(uint64_t flags);
970971
/** Loads the flags into the wallet. (used by LoadWallet) */
971972
bool LoadWalletFlags(uint64_t flags);
972973

src/wallet/wallettool.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ static void WalletCreate(CWallet* wallet_instance, uint64_t wallet_creation_flag
3838
} else {
3939
wallet_instance->SetMinVersion(FEATURE_COMPRPUBKEY);
4040
}
41-
wallet_instance->SetWalletFlag(wallet_creation_flags);
41+
wallet_instance->InitWalletFlags(wallet_creation_flags);
4242

4343
if (!wallet_instance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
4444
// TODO: use here SetupGeneration instead, such as: spk_man->SetupGeneration(false);

test/functional/wallet_abandonconflict.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ class AbandonConflictTest(BitcoinTestFramework):
2424
def set_test_params(self):
2525
self.num_nodes = 2
2626
self.extra_args = [["-minrelaytxfee=0.00001"], []]
27+
# whitelist peers to speed up tx relay / mempool sync
28+
for args in self.extra_args:
29+
args.append("-whitelist=noban@127.0.0.1")
2730

2831
def skip_test_if_missing_module(self):
2932
self.skip_if_no_wallet()

test/functional/wallet_balance.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ def set_test_params(self):
5353
['-limitdescendantcount=3'], # Limit mempool descendants as a hack to have wallet txs rejected from the mempool
5454
[],
5555
]
56+
# whitelist peers to speed up tx relay / mempool sync
57+
for args in self.extra_args:
58+
args.append("-whitelist=noban@127.0.0.1")
5659

5760
def skip_test_if_missing_module(self):
5861
self.skip_if_no_wallet()

test/functional/wallet_basic.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ def set_test_params(self):
2727
self.num_nodes = 4
2828
if self.options.descriptors:
2929
self.extra_args = [[
30-
"-acceptnonstdtxn=1"
30+
"-acceptnonstdtxn=1", "-whitelist=noban@127.0.0.1"
3131
] for i in range(self.num_nodes)]
3232
else:
3333
self.extra_args = [[
34-
"-acceptnonstdtxn=1",
34+
"-acceptnonstdtxn=1", "-whitelist=noban@127.0.0.1",
3535
'-usehd={:d}'.format(i%2==0)
3636
] for i in range(self.num_nodes)]
3737
self.setup_clean_chain = True

test/functional/wallet_encryption.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
from test_framework.test_framework import BitcoinTestFramework
1010
from test_framework.util import (
1111
assert_raises_rpc_error,
12-
assert_greater_than,
13-
assert_greater_than_or_equal,
12+
assert_equal,
1413
)
1514

1615

@@ -76,23 +75,18 @@ def run_test(self):
7675

7776
self.log.info('Check a timeout less than the limit')
7877
MAX_VALUE = 100000000
79-
expected_time = self.mocktime + MAX_VALUE - 600
78+
now = int(time.time())
79+
self.nodes[0].setmocktime(now)
80+
expected_time = now + MAX_VALUE - 600
8081
self.nodes[0].walletpassphrase(passphrase2, MAX_VALUE - 600)
81-
self.bump_mocktime(1)
82-
# give buffer for walletpassphrase, since it iterates over all encrypted keys
83-
expected_time_with_buffer = self.mocktime + MAX_VALUE - 600
8482
actual_time = self.nodes[0].getwalletinfo()['unlocked_until']
85-
assert_greater_than_or_equal(actual_time, expected_time)
86-
assert_greater_than(expected_time_with_buffer, actual_time)
83+
assert_equal(actual_time, expected_time)
8784

8885
self.log.info('Check a timeout greater than the limit')
89-
expected_time = self.mocktime + MAX_VALUE - 1
86+
expected_time = now + MAX_VALUE
9087
self.nodes[0].walletpassphrase(passphrase2, MAX_VALUE + 1000)
91-
self.bump_mocktime(1)
92-
expected_time_with_buffer = self.mocktime + MAX_VALUE
9388
actual_time = self.nodes[0].getwalletinfo()['unlocked_until']
94-
assert_greater_than_or_equal(actual_time, expected_time)
95-
assert_greater_than(expected_time_with_buffer, actual_time)
89+
assert_equal(actual_time, expected_time)
9690

9791

9892
if __name__ == '__main__':

0 commit comments

Comments
 (0)