Skip to content

Commit

Permalink
merge bitcoin#16033: Hold cs_main when reading chainActive via getTip…
Browse files Browse the repository at this point in the history
…Locator(). Remove assumeLocked().
  • Loading branch information
kwvg committed Dec 12, 2021
1 parent 0b5f527 commit 007ef7f
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 25 deletions.
10 changes: 3 additions & 7 deletions src/interfaces/chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
namespace interfaces {
namespace {

class LockImpl : public Chain::Lock
class LockImpl : public Chain::Lock, public UniqueLock<CCriticalSection>
{
Optional<int> getHeight() override
{
Expand Down Expand Up @@ -171,10 +171,7 @@ class LockImpl : public Chain::Lock
LockAnnotation lock(::cs_main);
return CheckFinalTx(tx);
}
};

class LockingStateImpl : public LockImpl, public UniqueLock<CCriticalSection>
{
using UniqueLock::UniqueLock;
};

Expand Down Expand Up @@ -273,13 +270,12 @@ class ChainImpl : public Chain
public:
std::unique_ptr<Chain::Lock> lock(bool try_lock) override
{
auto result = MakeUnique<LockingStateImpl>(::cs_main, "cs_main", __FILE__, __LINE__, try_lock);
auto result = MakeUnique<LockImpl>(::cs_main, "cs_main", __FILE__, __LINE__, try_lock);
if (try_lock && result && !*result) return {};
// std::move necessary on some compilers due to conversion from
// LockingStateImpl to Lock pointer
// LockImpl to Lock pointer
return std::move(result);
}
std::unique_ptr<Chain::Lock> assumeLocked() override { return MakeUnique<LockImpl>(); }
bool findBlock(const uint256& hash, CBlock* block, int64_t* time, int64_t* time_max) override
{
CBlockIndex* index;
Expand Down
5 changes: 0 additions & 5 deletions src/interfaces/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,6 @@ class Chain
//! unlocked when the returned interface is freed.
virtual std::unique_ptr<Lock> lock(bool try_lock = false) = 0;

//! Return Lock interface assuming chain is already locked. This
//! method is temporary and is only used in a few places to avoid changing
//! behavior while code is transitioned to use the Chain::Lock interface.
virtual std::unique_ptr<Lock> assumeLocked() = 0;

//! Return whether node has the block and optionally return block metadata
//! or contents.
//!
Expand Down
31 changes: 19 additions & 12 deletions src/wallet/test/wallet_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,10 @@ class ListCoinsTestingSetup : public TestChain100Setup
int changePos = -1;
std::string error;
CCoinControl dummy;
BOOST_CHECK(wallet->CreateTransaction(*m_locked_chain, {recipient}, tx, reservekey, fee, changePos, error, dummy));
{
auto locked_chain = m_chain->lock();
BOOST_CHECK(wallet->CreateTransaction(*locked_chain, {recipient}, tx, reservekey, fee, changePos, error, dummy));
}
CValidationState state;
BOOST_CHECK(wallet->CommitTransaction(tx, {}, {}, reservekey, state));
CMutableTransaction blocktx;
Expand All @@ -388,7 +391,6 @@ class ListCoinsTestingSetup : public TestChain100Setup
}

std::unique_ptr<interfaces::Chain> m_chain = interfaces::MakeChain();
std::unique_ptr<interfaces::Chain::Lock> m_locked_chain = m_chain->assumeLocked(); // Temporary. Removed in upcoming lock cleanup
std::unique_ptr<CWallet> wallet;
};

Expand All @@ -400,8 +402,9 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
// address.
std::map<CTxDestination, std::vector<COutput>> list;
{
LOCK2(cs_main, wallet->cs_wallet);
list = wallet->ListCoins(*m_locked_chain);
auto locked_chain = m_chain->lock();
LOCK(wallet->cs_wallet);
list = wallet->ListCoins(*locked_chain);
}
BOOST_CHECK_EQUAL(list.size(), 1U);
BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), coinbaseAddress);
Expand All @@ -416,18 +419,20 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
// pubkey.
AddTx(CRecipient{GetScriptForRawPubKey({}), 1 * COIN, false /* subtract fee */});
{
LOCK2(cs_main, wallet->cs_wallet);
list = wallet->ListCoins(*m_locked_chain);
auto locked_chain = m_chain->lock();
LOCK(wallet->cs_wallet);
list = wallet->ListCoins(*locked_chain);
}
BOOST_CHECK_EQUAL(list.size(), 1U);
BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), coinbaseAddress);
BOOST_CHECK_EQUAL(list.begin()->second.size(), 2U);

// Lock both coins. Confirm number of available coins drops to 0.
{
LOCK2(cs_main, wallet->cs_wallet);
auto locked_chain = m_chain->lock();
LOCK(wallet->cs_wallet);
std::vector<COutput> available;
wallet->AvailableCoins(*m_locked_chain, available);
wallet->AvailableCoins(*locked_chain, available);
BOOST_CHECK_EQUAL(available.size(), 2U);
}
for (const auto& group : list) {
Expand All @@ -437,16 +442,18 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
}
}
{
LOCK2(cs_main, wallet->cs_wallet);
auto locked_chain = m_chain->lock();
LOCK(wallet->cs_wallet);
std::vector<COutput> available;
wallet->AvailableCoins(*m_locked_chain, available);
wallet->AvailableCoins(*locked_chain, available);
BOOST_CHECK_EQUAL(available.size(), 0U);
}
// Confirm ListCoins still returns same result as before, despite coins
// being locked.
{
LOCK2(cs_main, wallet->cs_wallet);
list = wallet->ListCoins(*m_locked_chain);
auto locked_chain = m_chain->lock();
LOCK(wallet->cs_wallet);
list = wallet->ListCoins(*locked_chain);
}
BOOST_CHECK_EQUAL(list.size(), 1U);
BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), coinbaseAddress);
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5019,7 +5019,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
return error(_("Unable to generate initial keys"));
}

auto locked_chain = chain.assumeLocked(); // Temporary. Removed in upcoming lock cleanup
auto locked_chain = chain.lock();
walletInstance->ChainStateFlushed(locked_chain->getTipLocator());

// Try to create wallet backup right after new wallet was created
Expand Down

0 comments on commit 007ef7f

Please sign in to comment.