Skip to content

Commit fac04cb

Browse files
author
MacroFake
committed
refactor: Add lock annotations to Active* methods
This is a refactor, putting the burden to think about thread safety to the caller. Otherwise, there is a risk that the caller will assume thread safety where none exists, as is evident in the previous two commits.
1 parent fac15ff commit fac04cb

11 files changed

+44
-28
lines changed

src/bitcoin-chainstate.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,14 @@ int main(int argc, char* argv[])
115115
// Main program logic starts here
116116
std::cout
117117
<< "Hello! I'm going to print out some information about your datadir." << std::endl
118-
<< "\t" << "Path: " << gArgs.GetDataDirNet() << std::endl
118+
<< "\t" << "Path: " << gArgs.GetDataDirNet() << std::endl;
119+
{
120+
LOCK(chainman.GetMutex());
121+
std::cout
119122
<< "\t" << "Reindexing: " << std::boolalpha << node::fReindex.load() << std::noboolalpha << std::endl
120123
<< "\t" << "Snapshot Active: " << std::boolalpha << chainman.IsSnapshotActive() << std::noboolalpha << std::endl
121124
<< "\t" << "Active Height: " << chainman.ActiveHeight() << std::endl
122125
<< "\t" << "Active IBD: " << std::boolalpha << chainman.ActiveChainstate().IsInitialBlockDownload() << std::noboolalpha << std::endl;
123-
{
124126
CBlockIndex* tip = chainman.ActiveTip();
125127
if (tip) {
126128
std::cout << "\t" << tip->ToString() << std::endl;

src/init.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1547,7 +1547,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
15471547
// Either install a handler to notify us when genesis activates, or set fHaveGenesis directly.
15481548
// No locking, as this happens before any background thread is started.
15491549
boost::signals2::connection block_notify_genesis_wait_connection;
1550-
if (chainman.ActiveChain().Tip() == nullptr) {
1550+
if (WITH_LOCK(chainman.GetMutex(), return chainman.ActiveChain().Tip() == nullptr)) {
15511551
block_notify_genesis_wait_connection = uiInterface.NotifyBlockTip_connect(std::bind(BlockNotifyGenesisWait, std::placeholders::_2));
15521552
} else {
15531553
fHaveGenesis = true;

src/net_processing.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2510,7 +2510,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer,
25102510
// Consider fetching more headers.
25112511
if (nCount == MAX_HEADERS_RESULTS) {
25122512
// Headers message had its maximum size; the peer may have more headers.
2513-
if (MaybeSendGetHeaders(pfrom, m_chainman.ActiveChain().GetLocator(pindexLast), peer)) {
2513+
if (MaybeSendGetHeaders(pfrom, WITH_LOCK(m_chainman.GetMutex(), return m_chainman.ActiveChain().GetLocator(pindexLast)), peer)) {
25142514
LogPrint(BCLog::NET, "more getheaders (%d) to end to peer=%d (startheight:%d)\n",
25152515
pindexLast->nHeight, pfrom.GetId(), peer.m_starting_height);
25162516
}

src/qt/test/wallettests.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,14 @@ void TestGUI(interfaces::Node& node)
175175
if (!wallet->AddWalletDescriptor(w_desc, provider, "", false)) assert(false);
176176
CTxDestination dest = GetDestinationForKey(test.coinbaseKey.GetPubKey(), wallet->m_default_address_type);
177177
wallet->SetAddressBook(dest, "", "receive");
178-
wallet->SetLastBlockProcessed(105, node.context()->chainman->ActiveChain().Tip()->GetBlockHash());
178+
wallet->SetLastBlockProcessed(105, WITH_LOCK(node.context()->chainman->GetMutex(), return node.context()->chainman->ActiveChain().Tip()->GetBlockHash()));
179179
}
180180
{
181181
WalletRescanReserver reserver(*wallet);
182182
reserver.reserve();
183183
CWallet::ScanResult result = wallet->ScanForWalletTransactions(Params().GetConsensus().hashGenesisBlock, /*start_height=*/0, /*max_height=*/{}, reserver, /*fUpdate=*/true, /*save_progress=*/false);
184184
QCOMPARE(result.status, CWallet::ScanResult::SUCCESS);
185-
QCOMPARE(result.last_scanned_block, node.context()->chainman->ActiveChain().Tip()->GetBlockHash());
185+
QCOMPARE(result.last_scanned_block, WITH_LOCK(node.context()->chainman->GetMutex(), return node.context()->chainman->ActiveChain().Tip()->GetBlockHash()));
186186
QVERIFY(result.last_failed_block.IsNull());
187187
}
188188
wallet->SetBroadcastTransactions(true);

src/test/interfaces_tests.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ BOOST_FIXTURE_TEST_SUITE(interfaces_tests, TestChain100Setup)
1717

1818
BOOST_AUTO_TEST_CASE(findBlock)
1919
{
20+
LOCK(Assert(m_node.chainman)->GetMutex());
2021
auto& chain = m_node.chain;
2122
const CChain& active = Assert(m_node.chainman)->ActiveChain();
2223

@@ -61,6 +62,7 @@ BOOST_AUTO_TEST_CASE(findBlock)
6162

6263
BOOST_AUTO_TEST_CASE(findFirstBlockWithTimeAndHeight)
6364
{
65+
LOCK(Assert(m_node.chainman)->GetMutex());
6466
auto& chain = m_node.chain;
6567
const CChain& active = Assert(m_node.chainman)->ActiveChain();
6668
uint256 hash;
@@ -73,6 +75,7 @@ BOOST_AUTO_TEST_CASE(findFirstBlockWithTimeAndHeight)
7375

7476
BOOST_AUTO_TEST_CASE(findAncestorByHeight)
7577
{
78+
LOCK(Assert(m_node.chainman)->GetMutex());
7679
auto& chain = m_node.chain;
7780
const CChain& active = Assert(m_node.chainman)->ActiveChain();
7881
uint256 hash;
@@ -83,6 +86,7 @@ BOOST_AUTO_TEST_CASE(findAncestorByHeight)
8386

8487
BOOST_AUTO_TEST_CASE(findAncestorByHash)
8588
{
89+
LOCK(Assert(m_node.chainman)->GetMutex());
8690
auto& chain = m_node.chain;
8791
const CChain& active = Assert(m_node.chainman)->ActiveChain();
8892
int height = -1;
@@ -94,7 +98,7 @@ BOOST_AUTO_TEST_CASE(findAncestorByHash)
9498
BOOST_AUTO_TEST_CASE(findCommonAncestor)
9599
{
96100
auto& chain = m_node.chain;
97-
const CChain& active = Assert(m_node.chainman)->ActiveChain();
101+
const CChain& active = WITH_LOCK(Assert(m_node.chainman)->GetMutex(), return Assert(m_node.chainman)->ActiveChain());
98102
auto* orig_tip = active.Tip();
99103
for (int i = 0; i < 10; ++i) {
100104
BlockValidationState state;

src/test/validation_block_tests.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
234234

235235
// Run the test multiple times
236236
for (int test_runs = 3; test_runs > 0; --test_runs) {
237-
BOOST_CHECK_EQUAL(last_mined->GetHash(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
237+
BOOST_CHECK_EQUAL(last_mined->GetHash(), WITH_LOCK(Assert(m_node.chainman)->GetMutex(), return m_node.chainman->ActiveChain().Tip()->GetBlockHash()));
238238

239239
// Later on split from here
240240
const uint256 split_hash{last_mined->hashPrevBlock};
@@ -316,7 +316,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
316316
ProcessBlock(b);
317317
}
318318
// Check that the reorg was eventually successful
319-
BOOST_CHECK_EQUAL(last_mined->GetHash(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
319+
BOOST_CHECK_EQUAL(last_mined->GetHash(), WITH_LOCK(Assert(m_node.chainman)->GetMutex(), return m_node.chainman->ActiveChain().Tip()->GetBlockHash()));
320320

321321
// We can join the other thread, which returns when the reorg was successful
322322
rpc_thread.join();
@@ -325,6 +325,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
325325

326326
BOOST_AUTO_TEST_CASE(witness_commitment_index)
327327
{
328+
LOCK(Assert(m_node.chainman)->GetMutex());
328329
CScript pubKey;
329330
pubKey << 1 << OP_TRUE;
330331
auto ptemplate = BlockAssembler{m_node.chainman->ActiveChainstate(), m_node.mempool.get()}.CreateNewBlock(pubKey);

src/test/validation_chainstatemanager_tests.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
4949
auto all = manager.GetAll();
5050
BOOST_CHECK_EQUAL_COLLECTIONS(all.begin(), all.end(), chainstates.begin(), chainstates.end());
5151

52-
auto& active_chain = manager.ActiveChain();
52+
auto& active_chain = WITH_LOCK(manager.GetMutex(), return manager.ActiveChain());
5353
BOOST_CHECK_EQUAL(&active_chain, &c1.m_chain);
5454

55-
BOOST_CHECK_EQUAL(manager.ActiveHeight(), -1);
55+
BOOST_CHECK_EQUAL(WITH_LOCK(manager.GetMutex(), return manager.ActiveHeight()), -1);
5656

57-
auto active_tip = manager.ActiveTip();
57+
auto active_tip = WITH_LOCK(manager.GetMutex(), return manager.ActiveTip());
5858
auto exp_tip = c1.m_chain.Tip();
5959
BOOST_CHECK_EQUAL(active_tip, exp_tip);
6060

@@ -84,12 +84,12 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
8484
auto all2 = manager.GetAll();
8585
BOOST_CHECK_EQUAL_COLLECTIONS(all2.begin(), all2.end(), chainstates.begin(), chainstates.end());
8686

87-
auto& active_chain2 = manager.ActiveChain();
87+
auto& active_chain2 = WITH_LOCK(manager.GetMutex(), return manager.ActiveChain());
8888
BOOST_CHECK_EQUAL(&active_chain2, &c2.m_chain);
8989

90-
BOOST_CHECK_EQUAL(manager.ActiveHeight(), 0);
90+
BOOST_CHECK_EQUAL(WITH_LOCK(manager.GetMutex(), return manager.ActiveHeight()), 0);
9191

92-
auto active_tip2 = manager.ActiveTip();
92+
auto active_tip2 = WITH_LOCK(manager.GetMutex(), return manager.ActiveTip());
9393
auto exp_tip2 = c2.m_chain.Tip();
9494
BOOST_CHECK_EQUAL(active_tip2, exp_tip2);
9595

@@ -236,7 +236,7 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100Setup)
236236
BOOST_CHECK(WITH_LOCK(::cs_main, return !chainman.ActiveChain().Genesis()->IsAssumedValid()));
237237

238238
const AssumeutxoData& au_data = *ExpectedAssumeutxo(snapshot_height, ::Params());
239-
const CBlockIndex* tip = chainman.ActiveTip();
239+
const CBlockIndex* tip = WITH_LOCK(chainman.GetMutex(), return chainman.ActiveTip());
240240

241241
BOOST_CHECK_EQUAL(tip->nChainTx, au_data.nChainTx);
242242

@@ -335,7 +335,7 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup)
335335
const int assumed_valid_start_idx = last_assumed_valid_idx - expected_assumed_valid;
336336

337337
CBlockIndex* validated_tip{nullptr};
338-
CBlockIndex* assumed_tip{chainman.ActiveChain().Tip()};
338+
CBlockIndex* assumed_tip{WITH_LOCK(chainman.GetMutex(), return chainman.ActiveChain().Tip())};
339339

340340
auto reload_all_block_indexes = [&]() {
341341
for (CChainState* cs : chainman.GetAll()) {

src/validation.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -951,9 +951,9 @@ class ChainstateManager
951951

952952
//! The most-work chain.
953953
CChainState& ActiveChainstate() const;
954-
CChain& ActiveChain() const { return ActiveChainstate().m_chain; }
955-
int ActiveHeight() const { return ActiveChain().Height(); }
956-
CBlockIndex* ActiveTip() const { return ActiveChain().Tip(); }
954+
CChain& ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex()) { return ActiveChainstate().m_chain; }
955+
int ActiveHeight() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex()) { return ActiveChain().Height(); }
956+
CBlockIndex* ActiveTip() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex()) { return ActiveChain().Tip(); }
957957

958958
node::BlockMap& BlockIndex() EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
959959
{

src/wallet/test/availablecoins_tests.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class AvailableCoinsTestingSetup : public TestChain100Setup
4444
CreateAndProcessBlock({CMutableTransaction(blocktx)}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
4545

4646
LOCK(wallet->cs_wallet);
47+
LOCK(m_node.chainman->GetMutex());
4748
wallet->SetLastBlockProcessed(wallet->GetLastBlockHeight() + 1, m_node.chainman->ActiveChain().Tip()->GetBlockHash());
4849
auto it = wallet->mapWallet.find(tx->GetHash());
4950
BOOST_CHECK(it != wallet->mapWallet.end());

src/wallet/test/spend_tests.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ BOOST_FIXTURE_TEST_SUITE(spend_tests, WalletTestingSetup)
1818
BOOST_FIXTURE_TEST_CASE(SubtractFee, TestChain100Setup)
1919
{
2020
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
21-
auto wallet = CreateSyncedWallet(*m_node.chain, m_node.chainman->ActiveChain(), m_args, coinbaseKey);
21+
auto wallet = CreateSyncedWallet(*m_node.chain, WITH_LOCK(Assert(m_node.chainman)->GetMutex(), return m_node.chainman->ActiveChain()), m_args, coinbaseKey);
2222

2323
// Check that a subtract-from-recipient transaction slightly less than the
2424
// coinbase input amount does not create a change output (because it would

src/wallet/test/wallet_tests.cpp

+15-7
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,17 @@ static void AddKey(CWallet& wallet, const CKey& key)
9191
BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
9292
{
9393
// Cap last block file size, and mine new block in a new block file.
94-
CBlockIndex* oldTip = m_node.chainman->ActiveChain().Tip();
94+
CBlockIndex* oldTip = WITH_LOCK(Assert(m_node.chainman)->GetMutex(), return m_node.chainman->ActiveChain().Tip());
9595
WITH_LOCK(::cs_main, m_node.chainman->m_blockman.GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE);
9696
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
97-
CBlockIndex* newTip = m_node.chainman->ActiveChain().Tip();
97+
CBlockIndex* newTip = WITH_LOCK(Assert(m_node.chainman)->GetMutex(), return m_node.chainman->ActiveChain().Tip());
9898

9999
// Verify ScanForWalletTransactions fails to read an unknown start block.
100100
{
101101
CWallet wallet(m_node.chain.get(), "", m_args, CreateDummyWalletDatabase());
102102
{
103103
LOCK(wallet.cs_wallet);
104+
LOCK(Assert(m_node.chainman)->GetMutex());
104105
wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
105106
wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
106107
}
@@ -121,6 +122,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
121122
CWallet wallet(m_node.chain.get(), "", m_args, CreateMockWalletDatabase());
122123
{
123124
LOCK(wallet.cs_wallet);
125+
LOCK(Assert(m_node.chainman)->GetMutex());
124126
wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
125127
wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
126128
}
@@ -165,6 +167,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
165167
CWallet wallet(m_node.chain.get(), "", m_args, CreateDummyWalletDatabase());
166168
{
167169
LOCK(wallet.cs_wallet);
170+
LOCK(Assert(m_node.chainman)->GetMutex());
168171
wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
169172
wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
170173
}
@@ -192,6 +195,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
192195
CWallet wallet(m_node.chain.get(), "", m_args, CreateDummyWalletDatabase());
193196
{
194197
LOCK(wallet.cs_wallet);
198+
LOCK(Assert(m_node.chainman)->GetMutex());
195199
wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
196200
wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
197201
}
@@ -210,10 +214,10 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
210214
BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup)
211215
{
212216
// Cap last block file size, and mine new block in a new block file.
213-
CBlockIndex* oldTip = m_node.chainman->ActiveChain().Tip();
217+
CBlockIndex* oldTip = WITH_LOCK(Assert(m_node.chainman)->GetMutex(), return m_node.chainman->ActiveChain().Tip());
214218
WITH_LOCK(::cs_main, m_node.chainman->m_blockman.GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE);
215219
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
216-
CBlockIndex* newTip = m_node.chainman->ActiveChain().Tip();
220+
CBlockIndex* newTip = WITH_LOCK(Assert(m_node.chainman)->GetMutex(), return m_node.chainman->ActiveChain().Tip());
217221

218222
// Prune the older block file.
219223
int file_number;
@@ -277,7 +281,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
277281
{
278282
// Create two blocks with same timestamp to verify that importwallet rescan
279283
// will pick up both blocks, not just the first.
280-
const int64_t BLOCK_TIME = m_node.chainman->ActiveChain().Tip()->GetBlockTimeMax() + 5;
284+
const int64_t BLOCK_TIME = WITH_LOCK(Assert(m_node.chainman)->GetMutex(), return m_node.chainman->ActiveChain().Tip()->GetBlockTimeMax() + 5);
281285
SetMockTime(BLOCK_TIME);
282286
m_coinbase_txns.emplace_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
283287
m_coinbase_txns.emplace_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
@@ -302,6 +306,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
302306
spk_man->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey());
303307

304308
AddWallet(context, wallet);
309+
LOCK(Assert(m_node.chainman)->GetMutex());
305310
wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
306311
}
307312
JSONRPCRequest request;
@@ -327,6 +332,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
327332
request.params.setArray();
328333
request.params.push_back(backup_file);
329334
AddWallet(context, wallet);
335+
LOCK(Assert(m_node.chainman)->GetMutex());
330336
wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
331337
wallet::importwallet().HandleRequest(request);
332338
RemoveWallet(context, wallet, /* load_on_start= */ std::nullopt);
@@ -350,9 +356,10 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
350356
BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup)
351357
{
352358
CWallet wallet(m_node.chain.get(), "", m_args, CreateDummyWalletDatabase());
353-
CWalletTx wtx{m_coinbase_txns.back(), TxStateConfirmed{m_node.chainman->ActiveChain().Tip()->GetBlockHash(), m_node.chainman->ActiveChain().Height(), /*index=*/0}};
354359

355360
LOCK(wallet.cs_wallet);
361+
LOCK(Assert(m_node.chainman)->GetMutex());
362+
CWalletTx wtx{m_coinbase_txns.back(), TxStateConfirmed{m_node.chainman->ActiveChain().Tip()->GetBlockHash(), m_node.chainman->ActiveChain().Height(), /*index=*/0}};
356363
wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
357364
wallet.SetupDescriptorScriptPubKeyMans();
358365

@@ -520,7 +527,7 @@ class ListCoinsTestingSetup : public TestChain100Setup
520527
ListCoinsTestingSetup()
521528
{
522529
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
523-
wallet = CreateSyncedWallet(*m_node.chain, m_node.chainman->ActiveChain(), m_args, coinbaseKey);
530+
wallet = CreateSyncedWallet(*m_node.chain, WITH_LOCK(Assert(m_node.chainman)->GetMutex(), return m_node.chainman->ActiveChain()), m_args, coinbaseKey);
524531
}
525532

526533
~ListCoinsTestingSetup()
@@ -547,6 +554,7 @@ class ListCoinsTestingSetup : public TestChain100Setup
547554
CreateAndProcessBlock({CMutableTransaction(blocktx)}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
548555

549556
LOCK(wallet->cs_wallet);
557+
LOCK(Assert(m_node.chainman)->GetMutex());
550558
wallet->SetLastBlockProcessed(wallet->GetLastBlockHeight() + 1, m_node.chainman->ActiveChain().Tip()->GetBlockHash());
551559
auto it = wallet->mapWallet.find(tx->GetHash());
552560
BOOST_CHECK(it != wallet->mapWallet.end());

0 commit comments

Comments
 (0)