Skip to content

Commit

Permalink
Merge #6078: refactor: drop usage of chainstate globals in Dash-speci…
Browse files Browse the repository at this point in the history
…fic 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](#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 0213fbe

Tree-SHA512: 839f3f5b2af018520f330c4f4727622471d6225640c98853f28c3d88c4b6c728091b5e0c35b320e82979e5cd1357902fa1212afa4b6977967f05c636a25cc3b0
  • Loading branch information
PastaPastaPasta committed Jun 27, 2024
2 parents 4a52099 + 0213fbe commit b316be7
Show file tree
Hide file tree
Showing 96 changed files with 919 additions and 962 deletions.
4 changes: 4 additions & 0 deletions doc/release-notes-6078.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
RPC changes
-----------

- The following RPCs, `protx list`, `protx listdiff`, `protx info` will no longer report `collateralAddress` if the transaction index has been disabled (`txindex=0`).
10 changes: 2 additions & 8 deletions src/bench/coin_selection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,16 @@ static void CoinSelection(benchmark::Bench& bench)
}

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

// Copied from src/wallet/test/coinselector_tests.cpp
static void add_coin(const CAmount& nValue, int nInput, std::vector<OutputGroup>& set)
{
CMutableTransaction tx;
tx.vout.resize(nInput + 1);
tx.vout[nInput].nValue = nValue;
std::unique_ptr<CWalletTx> wtx = std::make_unique<CWalletTx>(&testWallet, MakeTransactionRef(std::move(tx)));
CInputCoin coin(MakeTransactionRef(tx), nInput);
set.emplace_back();
set.back().Insert(COutput(wtx.get(), nInput, 0, true, true, true).GetInputCoin(), 0, true, 0, 0, false);
wtxn.emplace_back(std::move(wtx));
set.back().Insert(coin, 0, true, 0, 0, false);
}
// Copied from src/wallet/test/coinselector_tests.cpp
static CAmount make_hard_case(int utxos, std::vector<OutputGroup>& utxo_pool)
Expand All @@ -93,7 +88,6 @@ static CAmount make_hard_case(int utxos, std::vector<OutputGroup>& utxo_pool)
static void BnBExhaustion(benchmark::Bench& bench)
{
// Setup
testWallet.SetupLegacyScriptPubKeyMan();
std::vector<OutputGroup> utxo_pool;
CoinSet selection;
CAmount value_ret = 0;
Expand Down
1 change: 0 additions & 1 deletion src/bench/duplicate_inputs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ static void DuplicateInputs(benchmark::Bench& bench)
CMutableTransaction coinbaseTx{};
CMutableTransaction naughtyTx{};

assert(std::addressof(::ChainActive()) == std::addressof(testing_setup->m_node.chainman->ActiveChain()));
CBlockIndex* pindexPrev = testing_setup->m_node.chainman->ActiveChain().Tip();
assert(pindexPrev != nullptr);
block.nBits = GetNextWorkRequired(pindexPrev, &block, chainparams.GetConsensus());
Expand Down
27 changes: 14 additions & 13 deletions src/coinjoin/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ PeerMsgRet CCoinJoinClientQueueManager::ProcessDSQueue(const CNode& peer, CDataS
return {};
}

void CCoinJoinClientManager::ProcessMessage(CNode& peer, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv)
void CCoinJoinClientManager::ProcessMessage(CNode& peer, CChainState& active_chainstate, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv)
{
if (m_is_masternode) return;
if (!CCoinJoinClientOptions::IsEnabled()) return;
Expand All @@ -150,7 +150,7 @@ void CCoinJoinClientManager::ProcessMessage(CNode& peer, CConnman& connman, cons
AssertLockNotHeld(cs_deqsessions);
LOCK(cs_deqsessions);
for (auto& session : deqSessions) {
session.ProcessMessage(peer, connman, mempool, msg_type, vRecv);
session.ProcessMessage(peer, active_chainstate, connman, mempool, msg_type, vRecv);
}
}
}
Expand All @@ -167,7 +167,7 @@ CCoinJoinClientSession::CCoinJoinClientSession(CWallet& wallet, CoinJoinWalletMa
m_is_masternode{is_masternode}
{}

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

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

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

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

// Make sure all inputs/outputs are valid
PoolMessage nMessageID{MSG_NOERR};
if (!IsValidInOuts(mempool, finalMutableTransaction.vin, finalMutableTransaction.vout, nMessageID, nullptr)) {
if (!IsValidInOuts(active_chainstate, mempool, finalMutableTransaction.vin, finalMutableTransaction.vout, nMessageID, nullptr)) {
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::%s -- ERROR! IsValidInOuts() failed: %s\n", __func__, CoinJoin::GetMessageByID(nMessageID).translated);
UnlockCoins();
keyHolderStorage.ReturnAll();
Expand Down Expand Up @@ -781,7 +781,7 @@ bool CCoinJoinClientManager::CheckAutomaticBackup()
//
// Passively run mixing in the background to mix funds based on the given configuration.
//
bool CCoinJoinClientSession::DoAutomaticDenominating(CConnman& connman, CTxMemPool& mempool, bool fDryRun)
bool CCoinJoinClientSession::DoAutomaticDenominating(CChainState& active_chainstate, CConnman& connman, CTxMemPool& mempool, bool fDryRun)
{
if (m_is_masternode) return false; // no client-side mixing on masternodes
if (nState != POOL_STATE_IDLE) return false;
Expand Down Expand Up @@ -934,7 +934,7 @@ bool CCoinJoinClientSession::DoAutomaticDenominating(CConnman& connman, CTxMemPo
return false;
}
} else {
if (!CoinJoin::IsCollateralValid(mempool, CTransaction(txMyCollateral))) {
if (!CoinJoin::IsCollateralValid(active_chainstate, mempool, CTransaction(txMyCollateral))) {
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::DoAutomaticDenominating -- invalid collateral, recreating...\n");
if (!CreateCollateralTransaction(txMyCollateral, strReason)) {
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::DoAutomaticDenominating -- create collateral error: %s\n", strReason);
Expand All @@ -961,7 +961,7 @@ bool CCoinJoinClientSession::DoAutomaticDenominating(CConnman& connman, CTxMemPo
return false;
}

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

fResult &= session.DoAutomaticDenominating(connman, mempool, fDryRun);
fResult &= session.DoAutomaticDenominating(active_chainstate, connman, mempool, fDryRun);
}

return fResult;
Expand Down Expand Up @@ -1840,7 +1840,7 @@ void CCoinJoinClientQueueManager::DoMaintenance()
CheckQueue();
}

void CCoinJoinClientManager::DoMaintenance(CConnman& connman, CTxMemPool& mempool)
void CCoinJoinClientManager::DoMaintenance(CChainState& active_chainstate, CConnman& connman, CTxMemPool& mempool)
{
if (!CCoinJoinClientOptions::IsEnabled()) return;
if (m_is_masternode) return; // no client-side mixing on masternodes
Expand All @@ -1854,7 +1854,7 @@ void CCoinJoinClientManager::DoMaintenance(CConnman& connman, CTxMemPool& mempoo
CheckTimeout();
ProcessPendingDsaRequest(connman);
if (nDoAutoNextRun == nTick) {
DoAutomaticDenominating(connman, mempool);
DoAutomaticDenominating(active_chainstate, connman, mempool);
nDoAutoNextRun = nTick + COINJOIN_AUTO_TIMEOUT_MIN + GetRandInt(COINJOIN_AUTO_TIMEOUT_MAX - COINJOIN_AUTO_TIMEOUT_MIN);
}
}
Expand Down Expand Up @@ -1901,9 +1901,10 @@ void CoinJoinWalletManager::Add(CWallet& wallet) {

void CoinJoinWalletManager::DoMaintenance() {
for (auto& [wallet_str, walletman] : m_wallet_manager_map) {
walletman->DoMaintenance(m_connman, m_mempool);
walletman->DoMaintenance(m_chainstate, m_connman, m_mempool);
}
}

void CoinJoinWalletManager::Remove(const std::string& name) {
m_wallet_manager_map.erase(name);
g_wallet_init_interface.InitCoinJoinSettings(*this);
Expand Down
19 changes: 10 additions & 9 deletions src/coinjoin/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ class CoinJoinWalletManager {
using wallet_name_cjman_map = std::map<const std::string, std::unique_ptr<CCoinJoinClientManager>>;

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

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

private:
CChainState& m_chainstate;
CConnman& m_connman;
CDeterministicMNManager& m_dmnman;
CMasternodeMetaMan& m_mn_metaman;
Expand Down Expand Up @@ -160,7 +161,7 @@ class CCoinJoinClientSession : public CCoinJoinBaseSession
void CompletedTransaction(PoolMessage nMessageID);

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

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

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

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

void UnlockCoins();

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

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

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

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

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

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

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

void UpdatedBlockTip(const CBlockIndex* pindex);

void DoMaintenance(CConnman& connman, CTxMemPool& mempool) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
void DoMaintenance(CChainState& active_chainstate, CConnman& connman, CTxMemPool& mempool) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);

void GetJsonInfo(UniValue& obj) const EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
};
Expand Down
10 changes: 5 additions & 5 deletions src/coinjoin/coinjoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ std::string CCoinJoinBaseSession::GetStateString() const
}
}

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

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

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

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

{
LOCK(cs_main);
if (!ATMPIfSaneFee(::ChainstateActive(), mempool, MakeTransactionRef(txCollateral), /*test_accept=*/true)) {
if (!ATMPIfSaneFee(active_chainstate, mempool, MakeTransactionRef(txCollateral), /*test_accept=*/true)) {
LogPrint(BCLog::COINJOIN, "CoinJoin::IsCollateralValid -- didn't pass AcceptToMemoryPool()\n");
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions src/coinjoin/coinjoin.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ class CCoinJoinBaseSession

virtual void SetNull() EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin);

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

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

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

}

Expand Down
2 changes: 1 addition & 1 deletion src/coinjoin/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ CJContext::CJContext(CChainState& chainstate, CConnman& connman, CDeterministicM
const std::unique_ptr<PeerManager>& peerman, bool relay_txes) :
dstxman{std::make_unique<CDSTXManager>()},
#ifdef ENABLE_WALLET
walletman{std::make_unique<CoinJoinWalletManager>(connman, dmnman, mn_metaman, mempool, mn_sync, queueman, /* is_masternode = */ mn_activeman != nullptr)},
walletman{std::make_unique<CoinJoinWalletManager>(chainstate, connman, dmnman, mn_metaman, mempool, mn_sync, queueman, /* is_masternode = */ mn_activeman != nullptr)},
queueman {relay_txes ? std::make_unique<CCoinJoinClientQueueManager>(connman, *walletman, dmnman, mn_metaman, mn_sync, /* is_masternode = */ mn_activeman != nullptr) : nullptr},
#endif // ENABLE_WALLET
server{std::make_unique<CCoinJoinServer>(chainstate, connman, dmnman, *dstxman, mn_metaman, mempool, mn_activeman, mn_sync, peerman)}
Expand Down
6 changes: 3 additions & 3 deletions src/coinjoin/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ bool CCoinJoinServer::AddEntry(const CCoinJoinEntry& entry, PoolMessage& nMessag
return false;
}

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

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

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

0 comments on commit b316be7

Please sign in to comment.