Skip to content

Commit b316be7

Browse files
Merge dashpay#6078: refactor: drop usage of chainstate globals in Dash-specific code, merge bitcoin#21866 (goodbye to a global chainstate)
0213fbe merge bitcoin#21866: Farewell, global Chainstate! (Kittywhiskers Van Gogh) e3687f7 test, bench: remove globals vCoins and testWallet from test and bench (Kittywhiskers Van Gogh) 0f4184c refactor: drop usage of chainstate globals in spork logic (Kittywhiskers Van Gogh) 208b1c0 refactor: drop usage of chainstate globals in masternode logic (Kittywhiskers Van Gogh) 303c6bb refactor: drop usage of chainstate globals in llmq logic (Kittywhiskers Van Gogh) fa20718 refactor: drop usage of chainstate globals in asset locks logic (Kittywhiskers Van Gogh) 21cc12c refactor: drop usage of chainstate globals in governance logic (Kittywhiskers Van Gogh) a475f5f refactor: drop usage of chainstate globals in coinjoin logic (Kittywhiskers Van Gogh) ed56dbd refactor: don't use globals to access members we can directly access (Kittywhiskers Van Gogh) c48c0e7 refactor: stop using `::ChainstateActive()` in `GetBlockHash` (Kittywhiskers Van Gogh) 6abf7f8 refactor: stop using `::Chain`{`state`}`Active()` in `GetUTXO*` (Kittywhiskers Van Gogh) f6f7df3 rpc: don't use GetUTXOCoin in CDeterministicMN::ToJson() (Kittywhiskers Van Gogh) Pull request description: ``` Thank you, I'll say goodbye soon Though its the end of these globals, don't blame yourself now And if its true, I will surround you and give life to a chainstate That's our own ``` ## Additional Information * In `CDeterministicMN::ToJson()`, `collateralAddress` is extracted by finding the `scriptPubKey` of a transaction output for a masternode, originally this used `GetUTXOCoin` but doesn't work for spent tranasction outputs (as they're _not_ UTXOs), so in [dash#5607](dashpay#5607), a fallback was introduced that looks through the general transaction set if going through the UTXO set yielded nothing. `GetUTXOCoin` accesses the active chainstate to get ahold of the UTXO set, this was done through globals. The removal of chainstate globals meant that whoever was calling `GetUTXOCoin` should have access to the chainstate handy. This is trivial in RPC code where `ToJson()` is used ([source](https://github.com/dashpay/dash/blob/5baa5222258f5cf2be0a3ce0f335dfd2fee931bc/src/rpc/evo.cpp#L1286)) through `Ensure`(`Any`)`Chainman`. Not the case in Qt code ([source](https://github.com/dashpay/dash/blob/5baa5222258f5cf2be0a3ce0f335dfd2fee931bc/src/qt/masternodelist.cpp#L369)), which is supposed to be given restricted access to information by the interface. As the fallback seems to be capable of fetching UTXOs and spent outputs, we can remove the `GetUTXOCoin` method and make the fallback the only method. * In `develop`, as of this writing, `CChainState` members `FlushStateToDisk` and {`Enforce`, `Invalidate`, `MarkConflicting`}`Block` were accessing their internals through the global, despite having direct access to them. As the globals they were calling are going to be bid farewell, they needed to be changed to access its members instead. The reason for going the roundabout way is unknown. * `CDSNotificationInterface` takes in a `ChainstateManager` (instead of the `CChainState` it actually requires) as at the time of interface initialization ([source](https://github.com/dashpay/dash/blob/5baa5222258f5cf2be0a3ce0f335dfd2fee931bc/src/init.cpp#L1915-L1918)), the active chainstate hasn't been loaded in yet as that happens further down ([source](https://github.com/dashpay/dash/blob/5baa5222258f5cf2be0a3ce0f335dfd2fee931bc/src/init.cpp#L1988-L1991)). As `CDSNotificationInterface::InitializeCurrentBlockTip()` is called well after it is initialized, we can resolve to the active chainstate in there. * As `GetCreditPoolDiffForBlock` requires access to `ChainstateManager` as `GetCreditPoolDiffForBlock` > `ProcessLockUnlockTransaction` > `CheckAssetLockUnlockTx` > `CheckAssetUnlockTx` > `ChainstateManager::m_blockman.LookupBlockIndex()` and `BlockAssembler` only has `CChainState`, it had to be reworked around `ChainstateManager`. ~~`CChainState` is passed as a direct argument while `ChainstateManager` can be fetched from `NodeContext`. Unlike `CTxMemPool`, which can be passed custom instances ([source](https://github.com/dashpay/dash/blob/5baa5222258f5cf2be0a3ce0f335dfd2fee931bc/src/rpc/mining.cpp#L381-L382), [source](https://github.com/dashpay/dash/blob/5baa5222258f5cf2be0a3ce0f335dfd2fee931bc/src/test/util/setup_common.cpp#L391-L392)), `CChainState`'s argument value is taken from `NodeContext::chainstate.ActiveChainstate()` and since we're now accepting `ChainstateManager` wholesale, we can dispense with accepting `CChainState` as an argument.~~ ~~Changes to that effect have been made.~~ AssumeUTXO introduces the need to be able to use different `CChainState`s, so this underlying assumption no longer holds true, the above described changes have been reverted. Asset locks code has been refactored to use `BlockManager` directly (which does come with the downside of needing to hold `cs_main` for longer than strictly necessary, this is why only asset locks uses `BlockManager` directly while other cases still benefit from having `ChainstateManager` as a whole). * `CMNHFManager::ConnectManagers` will be taking in a `ChainstateManager` pointer due to the `GetSignalsStage` > `GetForBlock` > `ProcessBlock` > `extractSignals` > `CheckMNHFTx` > `ChainstateManager::m_blockman.LookupBlockIndex()` chain. * The use of a bespoke `NodeContext` in `coinselector_tests` breaks tests if any interface call relies on a chainstate as `testNode` doesn't initialize one. For the most part, this was masked by `WalletTestingSetup` populating the chainstate globals from its own `NodeContext` even if the tests themselves preferred to use their own stripped down `testNode`. Though, removing the chainstate globals meant that they can no longer rely on `WalletTestingSetup`'s `NodeContext` to mask the barebones `testNode` global being used in the test (specifically, `addCoins` > `listMNCollaterials` > `ChainActive()` worked because `ChainActive()` accessed `WalletTestingSetup`'s `NodeContext` but when `ChainActive()` was gone and replaced with `NodeContext::chainman.ActiveChain()`, it uses `testNode`'s `ChainstateManager`, which doesn't exist, which causes it to crash). To remedy this, a5595b1 and 5e54aa9 from [bitcoin#23288](bitcoin#23288) were adapted for the limited purpose of eliminating `testNode` and using `WalletTestingSetup`'s `NodeContext` instead. This comes with the unfortunate effect of skipping a lot of the refactoring, cleanups and optimizations done before and adapting the ones after them non-trivial. It is therefore best recommended that the commit be reverted and changes implemented step-by-step in a pull request at some point in the future. For now, it's kept around here for the sake of this pull request, which, if merged, should prevent more chainstate globals use from leaking into the codebase. <details> <summary>Pre-fix crash stacktrace: </summary> ``` dash@71aecd6afb45:/src/dash$ lldb-16 ./src/test/test_dash (lldb) target create "./src/test/test_dash" Current executable set to '/src/dash/src/test/test_dash' (x86_64). (lldb) r -t coinselector_tests Process 395006 launched: '/src/dash/src/test/test_dash' (x86_64) Running 4 test cases... node/interfaces.cpp:711 chainman: Assertion `m_node.chainman' failed. Process 395006 stopped * thread #1, name = 'd-test', stop reason = signal SIGABRT frame #0: 0x00007ffff7a7300b libc.so.6`__GI_raise(sig=<unavailable>) at raise.c:51:1 (lldb) bt * thread #1, name = 'd-test', stop reason = signal SIGABRT * frame #0: 0x00007ffff7a7300b libc.so.6`__GI_raise(sig=<unavailable>) at raise.c:51:1 frame #1: 0x00007ffff7a52859 libc.so.6`__GI_abort at abort.c:79:7 frame #2: 0x00005555563cba33 test_dash`assertion_fail(file="node/interfaces.cpp", line=711, func="chainman", assertion="m_node.chainman") at check.cpp:13:5 frame #3: 0x0000555555fb47aa test_dash`node::(anonymous namespace)::ChainImpl::listMNCollaterials(std::vector<std::pair<std::shared_ptr<CTransaction const> const&, unsigned int>, std::allocator<std::pair<std::shared_ptr<CTransaction const> const&, unsigned int>>> const&) [inlined] std::unique_ptr<ChainstateManager, std::default_delete<ChainstateManager>>& inline_assertion_check<true, std::unique_ptr<ChainstateManager, std::default_delete<ChainstateManager>>&>(val=nullptr, file=<unavailable>, line=711, func=<unavailable>, assertion=<unavailable>) at check.h:62:13 frame #4: 0x0000555555fb4781 test_dash`node::(anonymous namespace)::ChainImpl::listMNCollaterials(std::vector<std::pair<std::shared_ptr<CTransaction const> const&, unsigned int>, std::allocator<std::pair<std::shared_ptr<CTransaction const> const&, unsigned int>>> const&) [inlined] node::(anonymous namespace)::ChainImpl::chainman(this=0x000055555723e830)at interfaces.cpp:711:45 frame #5: 0x0000555555fb477d test_dash`node::(anonymous namespace)::ChainImpl::listMNCollaterials(std::vector<std::pair<std::shared_ptr<CTransaction const> const&, unsigned int>, std::allocator<std::pair<std::shared_ptr<CTransaction const> const&, unsigned int>>> const&) [inlined] node::(anonymous namespace)::ChainImpl::listMNCollaterials(this=<unavailable>)::'lambda'()::operator()() const at interfaces.cpp:788:34 frame #6: 0x0000555555fb474f test_dash`node::(anonymous namespace)::ChainImpl::listMNCollaterials(this=0x000055555723e830, outputs=size=0) at interfaces.cpp:788:34 frame #7: 0x00005555565bcd07 test_dash`CWallet::AddToWallet(this=0x00005555571701e0, tx=<unavailable>, confirm=<unavailable>, update_wtx=<unavailable>, fFlushOnClose=<unavailable>) at wallet.cpp:886:46 frame #8: 0x0000555555bed3ef test_dash`coinselector_tests::add_coin(wallet=0x00005555571701e0, nValue=0x00007fffffffc7c0, nAge=144, fIsFromMe=false, nInput=0, spendable=<unavailable>) at coinselector_tests.cpp:77:29 frame #9: 0x0000555555bead3e test_dash`coinselector_tests::bnb_search_test::test_method() [inlined] coinselector_tests::add_coin(nValue=0x00007fffffffc7c0, nAge=144, fIsFromMe=false, nInput=0, spendable=false) at coinselector_tests.cpp:88:5 frame #10: 0x0000555555bead20 test_dash`coinselector_tests::bnb_search_test::test_method(this=0x00007fffffffcad0) at coinselector_tests.cpp:278:5 frame #11: 0x0000555555be6607 test_dash`coinselector_tests::bnb_search_test_invoker() at coinselector_tests.cpp:138:1 ``` </details> ## Breaking Changes * Backporting `coinselector_tests` changes are now much more annoying. * The following RPCs, `protx list`, `protx listdiff`, `protx info` will no longer report `collateralAddress` if the transaction index has been disabled (`txindex=0`). ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)** - [x] I have added or updated relevant unit/integration/functional/e2e tests - [x] I have made corresponding changes to the documentation **(note: N/A)** - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: UdjinM6: utACK 0213fbe knst: utACK 0213fbe PastaPastaPasta: utACK dashpay@0213fbe Tree-SHA512: 839f3f5b2af018520f330c4f4727622471d6225640c98853f28c3d88c4b6c728091b5e0c35b320e82979e5cd1357902fa1212afa4b6977967f05c636a25cc3b0
2 parents 4a52099 + 0213fbe commit b316be7

File tree

96 files changed

+919
-962
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+919
-962
lines changed

doc/release-notes-6078.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
RPC changes
2+
-----------
3+
4+
- The following RPCs, `protx list`, `protx listdiff`, `protx info` will no longer report `collateralAddress` if the transaction index has been disabled (`txindex=0`).

src/bench/coin_selection.cpp

+2-8
Original file line numberDiff line numberDiff line change
@@ -61,21 +61,16 @@ static void CoinSelection(benchmark::Bench& bench)
6161
}
6262

6363
typedef std::set<CInputCoin> CoinSet;
64-
static NodeContext testNode;
65-
static auto testChain = interfaces::MakeChain(testNode);
66-
static CWallet testWallet(testChain.get(), /*coinjoin_loader=*/ nullptr, "", CreateDummyWalletDatabase());
67-
std::vector<std::unique_ptr<CWalletTx>> wtxn;
6864

6965
// Copied from src/wallet/test/coinselector_tests.cpp
7066
static void add_coin(const CAmount& nValue, int nInput, std::vector<OutputGroup>& set)
7167
{
7268
CMutableTransaction tx;
7369
tx.vout.resize(nInput + 1);
7470
tx.vout[nInput].nValue = nValue;
75-
std::unique_ptr<CWalletTx> wtx = std::make_unique<CWalletTx>(&testWallet, MakeTransactionRef(std::move(tx)));
71+
CInputCoin coin(MakeTransactionRef(tx), nInput);
7672
set.emplace_back();
77-
set.back().Insert(COutput(wtx.get(), nInput, 0, true, true, true).GetInputCoin(), 0, true, 0, 0, false);
78-
wtxn.emplace_back(std::move(wtx));
73+
set.back().Insert(coin, 0, true, 0, 0, false);
7974
}
8075
// Copied from src/wallet/test/coinselector_tests.cpp
8176
static CAmount make_hard_case(int utxos, std::vector<OutputGroup>& utxo_pool)
@@ -93,7 +88,6 @@ static CAmount make_hard_case(int utxos, std::vector<OutputGroup>& utxo_pool)
9388
static void BnBExhaustion(benchmark::Bench& bench)
9489
{
9590
// Setup
96-
testWallet.SetupLegacyScriptPubKeyMan();
9791
std::vector<OutputGroup> utxo_pool;
9892
CoinSet selection;
9993
CAmount value_ret = 0;

src/bench/duplicate_inputs.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ static void DuplicateInputs(benchmark::Bench& bench)
2525
CMutableTransaction coinbaseTx{};
2626
CMutableTransaction naughtyTx{};
2727

28-
assert(std::addressof(::ChainActive()) == std::addressof(testing_setup->m_node.chainman->ActiveChain()));
2928
CBlockIndex* pindexPrev = testing_setup->m_node.chainman->ActiveChain().Tip();
3029
assert(pindexPrev != nullptr);
3130
block.nBits = GetNextWorkRequired(pindexPrev, &block, chainparams.GetConsensus());

src/coinjoin/client.cpp

+14-13
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ PeerMsgRet CCoinJoinClientQueueManager::ProcessDSQueue(const CNode& peer, CDataS
131131
return {};
132132
}
133133

134-
void CCoinJoinClientManager::ProcessMessage(CNode& peer, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv)
134+
void CCoinJoinClientManager::ProcessMessage(CNode& peer, CChainState& active_chainstate, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv)
135135
{
136136
if (m_is_masternode) return;
137137
if (!CCoinJoinClientOptions::IsEnabled()) return;
@@ -150,7 +150,7 @@ void CCoinJoinClientManager::ProcessMessage(CNode& peer, CConnman& connman, cons
150150
AssertLockNotHeld(cs_deqsessions);
151151
LOCK(cs_deqsessions);
152152
for (auto& session : deqSessions) {
153-
session.ProcessMessage(peer, connman, mempool, msg_type, vRecv);
153+
session.ProcessMessage(peer, active_chainstate, connman, mempool, msg_type, vRecv);
154154
}
155155
}
156156
}
@@ -167,7 +167,7 @@ CCoinJoinClientSession::CCoinJoinClientSession(CWallet& wallet, CoinJoinWalletMa
167167
m_is_masternode{is_masternode}
168168
{}
169169

170-
void CCoinJoinClientSession::ProcessMessage(CNode& peer, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv)
170+
void CCoinJoinClientSession::ProcessMessage(CNode& peer, CChainState& active_chainstate, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv)
171171
{
172172
if (m_is_masternode) return;
173173
if (!CCoinJoinClientOptions::IsEnabled()) return;
@@ -202,7 +202,7 @@ void CCoinJoinClientSession::ProcessMessage(CNode& peer, CConnman& connman, cons
202202
WalletCJLogPrint(m_wallet, "DSFINALTX -- txNew %s", txNew.ToString()); /* Continued */
203203

204204
// check to see if input is spent already? (and probably not confirmed)
205-
SignFinalTransaction(mempool, txNew, peer, connman);
205+
SignFinalTransaction(peer, active_chainstate, connman, mempool, txNew);
206206

207207
} else if (msg_type == NetMsgType::DSCOMPLETE) {
208208
if (!mixingMasternode) return;
@@ -548,7 +548,7 @@ void CCoinJoinClientSession::ProcessPoolStateUpdate(CCoinJoinStatusUpdate psssup
548548
// check it to make sure it's what we want, then sign it if we agree.
549549
// If we refuse to sign, it's possible we'll be charged collateral
550550
//
551-
bool CCoinJoinClientSession::SignFinalTransaction(const CTxMemPool& mempool, const CTransaction& finalTransactionNew, CNode& peer, CConnman& connman)
551+
bool CCoinJoinClientSession::SignFinalTransaction(CNode& peer, CChainState& active_chainstate, CConnman& connman, const CTxMemPool& mempool, const CTransaction& finalTransactionNew)
552552
{
553553
if (!CCoinJoinClientOptions::IsEnabled()) return false;
554554

@@ -577,7 +577,7 @@ bool CCoinJoinClientSession::SignFinalTransaction(const CTxMemPool& mempool, con
577577

578578
// Make sure all inputs/outputs are valid
579579
PoolMessage nMessageID{MSG_NOERR};
580-
if (!IsValidInOuts(mempool, finalMutableTransaction.vin, finalMutableTransaction.vout, nMessageID, nullptr)) {
580+
if (!IsValidInOuts(active_chainstate, mempool, finalMutableTransaction.vin, finalMutableTransaction.vout, nMessageID, nullptr)) {
581581
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::%s -- ERROR! IsValidInOuts() failed: %s\n", __func__, CoinJoin::GetMessageByID(nMessageID).translated);
582582
UnlockCoins();
583583
keyHolderStorage.ReturnAll();
@@ -781,7 +781,7 @@ bool CCoinJoinClientManager::CheckAutomaticBackup()
781781
//
782782
// Passively run mixing in the background to mix funds based on the given configuration.
783783
//
784-
bool CCoinJoinClientSession::DoAutomaticDenominating(CConnman& connman, CTxMemPool& mempool, bool fDryRun)
784+
bool CCoinJoinClientSession::DoAutomaticDenominating(CChainState& active_chainstate, CConnman& connman, CTxMemPool& mempool, bool fDryRun)
785785
{
786786
if (m_is_masternode) return false; // no client-side mixing on masternodes
787787
if (nState != POOL_STATE_IDLE) return false;
@@ -934,7 +934,7 @@ bool CCoinJoinClientSession::DoAutomaticDenominating(CConnman& connman, CTxMemPo
934934
return false;
935935
}
936936
} else {
937-
if (!CoinJoin::IsCollateralValid(mempool, CTransaction(txMyCollateral))) {
937+
if (!CoinJoin::IsCollateralValid(active_chainstate, mempool, CTransaction(txMyCollateral))) {
938938
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::DoAutomaticDenominating -- invalid collateral, recreating...\n");
939939
if (!CreateCollateralTransaction(txMyCollateral, strReason)) {
940940
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::DoAutomaticDenominating -- create collateral error: %s\n", strReason);
@@ -961,7 +961,7 @@ bool CCoinJoinClientSession::DoAutomaticDenominating(CConnman& connman, CTxMemPo
961961
return false;
962962
}
963963

964-
bool CCoinJoinClientManager::DoAutomaticDenominating(CConnman& connman, CTxMemPool& mempool, bool fDryRun)
964+
bool CCoinJoinClientManager::DoAutomaticDenominating(CChainState& active_chainstate, CConnman& connman, CTxMemPool& mempool, bool fDryRun)
965965
{
966966
if (m_is_masternode) return false; // no client-side mixing on masternodes
967967
if (!CCoinJoinClientOptions::IsEnabled() || !IsMixing()) return false;
@@ -1003,7 +1003,7 @@ bool CCoinJoinClientManager::DoAutomaticDenominating(CConnman& connman, CTxMemPo
10031003
return false;
10041004
}
10051005

1006-
fResult &= session.DoAutomaticDenominating(connman, mempool, fDryRun);
1006+
fResult &= session.DoAutomaticDenominating(active_chainstate, connman, mempool, fDryRun);
10071007
}
10081008

10091009
return fResult;
@@ -1840,7 +1840,7 @@ void CCoinJoinClientQueueManager::DoMaintenance()
18401840
CheckQueue();
18411841
}
18421842

1843-
void CCoinJoinClientManager::DoMaintenance(CConnman& connman, CTxMemPool& mempool)
1843+
void CCoinJoinClientManager::DoMaintenance(CChainState& active_chainstate, CConnman& connman, CTxMemPool& mempool)
18441844
{
18451845
if (!CCoinJoinClientOptions::IsEnabled()) return;
18461846
if (m_is_masternode) return; // no client-side mixing on masternodes
@@ -1854,7 +1854,7 @@ void CCoinJoinClientManager::DoMaintenance(CConnman& connman, CTxMemPool& mempoo
18541854
CheckTimeout();
18551855
ProcessPendingDsaRequest(connman);
18561856
if (nDoAutoNextRun == nTick) {
1857-
DoAutomaticDenominating(connman, mempool);
1857+
DoAutomaticDenominating(active_chainstate, connman, mempool);
18581858
nDoAutoNextRun = nTick + COINJOIN_AUTO_TIMEOUT_MIN + GetRandInt(COINJOIN_AUTO_TIMEOUT_MAX - COINJOIN_AUTO_TIMEOUT_MIN);
18591859
}
18601860
}
@@ -1901,9 +1901,10 @@ void CoinJoinWalletManager::Add(CWallet& wallet) {
19011901

19021902
void CoinJoinWalletManager::DoMaintenance() {
19031903
for (auto& [wallet_str, walletman] : m_wallet_manager_map) {
1904-
walletman->DoMaintenance(m_connman, m_mempool);
1904+
walletman->DoMaintenance(m_chainstate, m_connman, m_mempool);
19051905
}
19061906
}
1907+
19071908
void CoinJoinWalletManager::Remove(const std::string& name) {
19081909
m_wallet_manager_map.erase(name);
19091910
g_wallet_init_interface.InitCoinJoinSettings(*this);

src/coinjoin/client.h

+10-9
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ class CoinJoinWalletManager {
7373
using wallet_name_cjman_map = std::map<const std::string, std::unique_ptr<CCoinJoinClientManager>>;
7474

7575
public:
76-
CoinJoinWalletManager(CConnman& connman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool,
76+
CoinJoinWalletManager(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool,
7777
const CMasternodeSync& mn_sync, const std::unique_ptr<CCoinJoinClientQueueManager>& queueman, bool is_masternode)
78-
: m_connman(connman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mempool(mempool), m_mn_sync(mn_sync), m_queueman(queueman),
79-
m_is_masternode{is_masternode}
78+
: m_chainstate(chainstate), m_connman(connman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mempool(mempool), m_mn_sync(mn_sync),
79+
m_queueman(queueman), m_is_masternode{is_masternode}
8080
{}
8181

8282
~CoinJoinWalletManager() {
@@ -96,6 +96,7 @@ class CoinJoinWalletManager {
9696
const wallet_name_cjman_map& raw() const { return m_wallet_manager_map; }
9797

9898
private:
99+
CChainState& m_chainstate;
99100
CConnman& m_connman;
100101
CDeterministicMNManager& m_dmnman;
101102
CMasternodeMetaMan& m_mn_metaman;
@@ -160,7 +161,7 @@ class CCoinJoinClientSession : public CCoinJoinBaseSession
160161
void CompletedTransaction(PoolMessage nMessageID);
161162

162163
/// As a client, check and sign the final transaction
163-
bool SignFinalTransaction(const CTxMemPool& mempool, const CTransaction& finalTransactionNew, CNode& peer, CConnman& connman) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin);
164+
bool SignFinalTransaction(CNode& peer, CChainState& active_chainstate, CConnman& connman, const CTxMemPool& mempool, const CTransaction& finalTransactionNew) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin);
164165

165166
void RelayIn(const CCoinJoinEntry& entry, CConnman& connman) const;
166167

@@ -170,7 +171,7 @@ class CCoinJoinClientSession : public CCoinJoinBaseSession
170171
explicit CCoinJoinClientSession(CWallet& wallet, CoinJoinWalletManager& walletman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman,
171172
const CMasternodeSync& mn_sync, const std::unique_ptr<CCoinJoinClientQueueManager>& queueman, bool is_masternode);
172173

173-
void ProcessMessage(CNode& peer, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv);
174+
void ProcessMessage(CNode& peer, CChainState& active_chainstate, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv);
174175

175176
void UnlockCoins();
176177

@@ -181,7 +182,7 @@ class CCoinJoinClientSession : public CCoinJoinBaseSession
181182
bool GetMixingMasternodeInfo(CDeterministicMNCPtr& ret) const;
182183

183184
/// Passively run mixing in the background according to the configuration in settings
184-
bool DoAutomaticDenominating(CConnman& connman, CTxMemPool& mempool, bool fDryRun = false) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin);
185+
bool DoAutomaticDenominating(CChainState& active_chainstate, CConnman& connman, CTxMemPool& mempool, bool fDryRun = false) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin);
185186

186187
/// As a client, submit part of a future mixing transaction to a Masternode to start the process
187188
bool SubmitDenominate(CConnman& connman);
@@ -267,7 +268,7 @@ class CCoinJoinClientManager
267268
m_wallet(wallet), m_walletman(walletman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mn_sync(mn_sync), m_queueman(queueman),
268269
m_is_masternode{is_masternode} {}
269270

270-
void ProcessMessage(CNode& peer, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
271+
void ProcessMessage(CNode& peer, CChainState& active_chainstate, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
271272

272273
bool StartMixing();
273274
void StopMixing();
@@ -280,7 +281,7 @@ class CCoinJoinClientManager
280281
bool GetMixingMasternodesInfo(std::vector<CDeterministicMNCPtr>& vecDmnsRet) const EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
281282

282283
/// Passively run mixing in the background according to the configuration in settings
283-
bool DoAutomaticDenominating(CConnman& connman, CTxMemPool& mempool, bool fDryRun = false) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
284+
bool DoAutomaticDenominating(CChainState& active_chainstate, CConnman& connman, CTxMemPool& mempool, bool fDryRun = false) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
284285

285286
bool TrySubmitDenominate(const CService& mnAddr, CConnman& connman) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
286287
bool MarkAlreadyJoinedQueueAsTried(CCoinJoinQueue& dsq) const EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
@@ -296,7 +297,7 @@ class CCoinJoinClientManager
296297

297298
void UpdatedBlockTip(const CBlockIndex* pindex);
298299

299-
void DoMaintenance(CConnman& connman, CTxMemPool& mempool) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
300+
void DoMaintenance(CChainState& active_chainstate, CConnman& connman, CTxMemPool& mempool) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
300301

301302
void GetJsonInfo(UniValue& obj) const EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
302303
};

src/coinjoin/coinjoin.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ std::string CCoinJoinBaseSession::GetStateString() const
217217
}
218218
}
219219

220-
bool CCoinJoinBaseSession::IsValidInOuts(const CTxMemPool& mempool, const std::vector<CTxIn>& vin, const std::vector<CTxOut>& vout, PoolMessage& nMessageIDRet, bool* fConsumeCollateralRet) const
220+
bool CCoinJoinBaseSession::IsValidInOuts(CChainState& active_chainstate, const CTxMemPool& mempool, const std::vector<CTxIn>& vin, const std::vector<CTxOut>& vout, PoolMessage& nMessageIDRet, bool* fConsumeCollateralRet) const
221221
{
222222
std::set<CScript> setScripPubKeys;
223223
nMessageIDRet = MSG_NOERR;
@@ -264,7 +264,7 @@ bool CCoinJoinBaseSession::IsValidInOuts(const CTxMemPool& mempool, const std::v
264264
nFees -= txout.nValue;
265265
}
266266

267-
CCoinsViewMemPool viewMemPool(WITH_LOCK(cs_main, return &::ChainstateActive().CoinsTip()), mempool);
267+
CCoinsViewMemPool viewMemPool(WITH_LOCK(cs_main, return &active_chainstate.CoinsTip()), mempool);
268268

269269
for (const auto& txin : vin) {
270270
LogPrint(BCLog::COINJOIN, "CCoinJoinBaseSession::%s -- txin=%s\n", __func__, txin.ToString());
@@ -322,7 +322,7 @@ bool ATMPIfSaneFee(CChainState& active_chainstate, CTxMemPool& pool, const CTran
322322
}
323323

324324
// check to make sure the collateral provided by the client is valid
325-
bool CoinJoin::IsCollateralValid(CTxMemPool& mempool, const CTransaction& txCollateral)
325+
bool CoinJoin::IsCollateralValid(CChainState& active_chainstate, CTxMemPool& mempool, const CTransaction& txCollateral)
326326
{
327327
if (txCollateral.vout.empty()) return false;
328328
if (txCollateral.nLockTime != 0) return false;
@@ -348,7 +348,7 @@ bool CoinJoin::IsCollateralValid(CTxMemPool& mempool, const CTransaction& txColl
348348
return false;
349349
}
350350
nValueIn += mempoolTx->vout[txin.prevout.n].nValue;
351-
} else if (GetUTXOCoin(txin.prevout, coin)) {
351+
} else if (GetUTXOCoin(active_chainstate, txin.prevout, coin)) {
352352
nValueIn += coin.out.nValue;
353353
} else {
354354
LogPrint(BCLog::COINJOIN, "CoinJoin::IsCollateralValid -- Unknown inputs in collateral transaction, txCollateral=%s", txCollateral.ToString()); /* Continued */
@@ -366,7 +366,7 @@ bool CoinJoin::IsCollateralValid(CTxMemPool& mempool, const CTransaction& txColl
366366

367367
{
368368
LOCK(cs_main);
369-
if (!ATMPIfSaneFee(::ChainstateActive(), mempool, MakeTransactionRef(txCollateral), /*test_accept=*/true)) {
369+
if (!ATMPIfSaneFee(active_chainstate, mempool, MakeTransactionRef(txCollateral), /*test_accept=*/true)) {
370370
LogPrint(BCLog::COINJOIN, "CoinJoin::IsCollateralValid -- didn't pass AcceptToMemoryPool()\n");
371371
return false;
372372
}

src/coinjoin/coinjoin.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ class CCoinJoinBaseSession
309309

310310
virtual void SetNull() EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin);
311311

312-
bool IsValidInOuts(const CTxMemPool& mempool, const std::vector<CTxIn>& vin, const std::vector<CTxOut>& vout, PoolMessage& nMessageIDRet, bool* fConsumeCollateralRet) const;
312+
bool IsValidInOuts(CChainState& active_chainstate, const CTxMemPool& mempool, const std::vector<CTxIn>& vin, const std::vector<CTxOut>& vout, PoolMessage& nMessageIDRet, bool* fConsumeCollateralRet) const;
313313

314314
public:
315315
int nSessionDenom{0}; // Users must submit a denom matching this
@@ -354,7 +354,7 @@ namespace CoinJoin
354354
constexpr CAmount GetMaxPoolAmount() { return COINJOIN_ENTRY_MAX_SIZE * vecStandardDenominations.front(); }
355355

356356
/// If the collateral is valid given by a client
357-
bool IsCollateralValid(CTxMemPool& mempool, const CTransaction& txCollateral);
357+
bool IsCollateralValid(CChainState& active_chainstate, CTxMemPool& mempool, const CTransaction& txCollateral);
358358

359359
}
360360

src/coinjoin/context.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ CJContext::CJContext(CChainState& chainstate, CConnman& connman, CDeterministicM
1414
const std::unique_ptr<PeerManager>& peerman, bool relay_txes) :
1515
dstxman{std::make_unique<CDSTXManager>()},
1616
#ifdef ENABLE_WALLET
17-
walletman{std::make_unique<CoinJoinWalletManager>(connman, dmnman, mn_metaman, mempool, mn_sync, queueman, /* is_masternode = */ mn_activeman != nullptr)},
17+
walletman{std::make_unique<CoinJoinWalletManager>(chainstate, connman, dmnman, mn_metaman, mempool, mn_sync, queueman, /* is_masternode = */ mn_activeman != nullptr)},
1818
queueman {relay_txes ? std::make_unique<CCoinJoinClientQueueManager>(connman, *walletman, dmnman, mn_metaman, mn_sync, /* is_masternode = */ mn_activeman != nullptr) : nullptr},
1919
#endif // ENABLE_WALLET
2020
server{std::make_unique<CCoinJoinServer>(chainstate, connman, dmnman, *dstxman, mn_metaman, mempool, mn_activeman, mn_sync, peerman)}

src/coinjoin/server.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ bool CCoinJoinServer::AddEntry(const CCoinJoinEntry& entry, PoolMessage& nMessag
574574
return false;
575575
}
576576

577-
if (!CoinJoin::IsCollateralValid(mempool, *entry.txCollateral)) {
577+
if (!CoinJoin::IsCollateralValid(m_chainstate, mempool, *entry.txCollateral)) {
578578
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::%s -- ERROR: collateral not valid!\n", __func__);
579579
nMessageIDRet = ERR_INVALID_COLLATERAL;
580580
return false;
@@ -608,7 +608,7 @@ bool CCoinJoinServer::AddEntry(const CCoinJoinEntry& entry, PoolMessage& nMessag
608608
}
609609

610610
bool fConsumeCollateral{false};
611-
if (!IsValidInOuts(mempool, vin, entry.vecTxOut, nMessageIDRet, &fConsumeCollateral)) {
611+
if (!IsValidInOuts(m_chainstate, mempool, vin, entry.vecTxOut, nMessageIDRet, &fConsumeCollateral)) {
612612
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::%s -- ERROR! IsValidInOuts() failed: %s\n", __func__, CoinJoin::GetMessageByID(nMessageIDRet).translated);
613613
if (fConsumeCollateral) {
614614
ConsumeCollateral(entry.txCollateral);
@@ -685,7 +685,7 @@ bool CCoinJoinServer::IsAcceptableDSA(const CCoinJoinAccept& dsa, PoolMessage& n
685685
}
686686

687687
// check collateral
688-
if (!fUnitTest && !CoinJoin::IsCollateralValid(mempool, CTransaction(dsa.txCollateral))) {
688+
if (!fUnitTest && !CoinJoin::IsCollateralValid(m_chainstate, mempool, CTransaction(dsa.txCollateral))) {
689689
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::%s -- collateral not valid!\n", __func__);
690690
nMessageIDRet = ERR_INVALID_COLLATERAL;
691691
return false;

0 commit comments

Comments
 (0)