Skip to content

Conversation

sriramdvt
Copy link
Contributor

Make m_mempool an optional pointer in PeerManager, instead of a reference. This is a prerequisite for the introduction of a -nomempool option.

To test that the null-pointer-dereference checks in PeerManagerImpl work, build the test-peerman-mempool-ptr branch that does not have a mempool initialized, and run it on signet/testnet (the functional tests would not work on test-peerman-mempool-ptr since the mempool is absent).

- Make m_mempool a pointer in the initialization of PeerManager
- Check that m_mempool exists before dereferencing the pointer in PeerManager functions
- If m_mempool is a nullptr, turn off transaction relay with all peers by setting m_tx_relay to nullptr
@sriramdvt sriramdvt force-pushed the peerman-mempool-ptr branch from 8d21453 to 0e07e48 Compare August 31, 2021 19:29
@DrahtBot
Copy link
Contributor

DrahtBot commented Aug 31, 2021

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #22976 (scripted-diff: Rename overloaded int GetArg to GetIntArg by ryanofsky)
  • #22955 (p2p: Rename fBlocksOnly, Add test by MarcoFalke)
  • #22777 (net processing: don't request tx relay on feeler connections by jnewbery)
  • #22677 (cut the validation <-> txmempool circular dependency by glozow)
  • #22564 ([WIP] refactor: Move mutable globals cleared in ::UnloadBlockIndex to BlockManager by dongcarl)
  • #22340 (p2p: Use legacy relaying to download blocks in blocks-only mode by dergoegge)
  • #21527 (net_processing: lock clean up by ajtowns)
  • #20799 (net processing: Only support version 2 compact blocks by jnewbery)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice work.

review ACK 0e07e48, but the BLOCKTXN issue might need a fix 🏠

Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

review ACK 0e07e48a3b049eaa1c7b779187e56cf7ea85ead9, but the BLOCKTXN issue might need a fix 🏠
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUhRdgwAuw0KGr//qvSM+oqAA0grsBdt1Y86BZF9Gs7IGZJbuD453SgnPKBA6K10
BaoPE4cYiFEBXTe6AywC6hOONmsyl4VjOu8DKPD3OX2AXU2bDiQDZ87jUdEAnM9P
+9blZsyfdwf99wEKRFxUmJcYKIJp7TKAW/4OZnADIp+BjLUEncLRExK8pPIXI2iV
5hlLZ9ixdP3oTpcpsWZt8SsgGbH0tMgSpeT6DewnasXJke/kEp/dA1W7qb6bJkh/
BiZ/t9xRqwOUnHNJi1KW8VBn8mTPOrs7j3FP7IAKl+Y5ylNH7hCQiUA4m0h1n6Bh
ei1OOqUk2X4O3P2H7uzr+pCOEbK41zSG3okpRbGGxhvj4S2koQUdmFXVjMEMB835
P1r9RKnuIrC1M+O5zStTB9D4Kj+BnGUV5stZSnMknp9x60oyUywrxZ8o7mB7h8c1
FqVEp72xwL/O+VzHkrJFF/7cByqvJo3XpW1xnTAHTSR3+BrjdAbzL9mhyjre57z7
RBs48w0X
=K8hA
-----END PGP SIGNATURE-----

Timestamp of file with hash 87c58d73cd67339e790adac6db8ebc82ad4d33283928162ce202a7ff346e816b -

// Ignore cmpctblock received while importing
if (fImporting || fReindex) {
// Ignore cmpctblock received while importing, or when there is no mempool
if (fImporting || fReindex || !m_mempool) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't the same check be needed for BLOCKTXN?


std::list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(),
{&block, std::unique_ptr<PartiallyDownloadedBlock>(pit ? new PartiallyDownloadedBlock(&m_mempool) : nullptr)});
{&block, std::unique_ptr<PartiallyDownloadedBlock>(pit ? new PartiallyDownloadedBlock(m_mempool) : nullptr)});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be safer to set the block to nullptr when the mempool is nullptr?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you pick this suggestion, you can also add a separate commit to document the expectation that PartiallyDownloadedBlock assumes a reference (doesn't accept nullptr) and that InitData without a pool is UB/Crash.

diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp
index aa111b5939..8f77c4afd6 100644
--- a/src/blockencodings.cpp
+++ b/src/blockencodings.cpp
@@ -45,8 +45,9 @@ uint64_t CBlockHeaderAndShortTxIDs::GetShortID(const uint256& txhash) const {
 }
 
 
-
-ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<std::pair<uint256, CTransactionRef>>& extra_txn) {
+ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<std::pair<uint256, CTransactionRef>>& extra_txn)
+{
+    Assert(pool);
     if (cmpctblock.header.IsNull() || (cmpctblock.shorttxids.empty() && cmpctblock.prefilledtxn.empty()))
         return READ_STATUS_INVALID;
     if (cmpctblock.shorttxids.size() + cmpctblock.prefilledtxn.size() > MAX_BLOCK_WEIGHT / MIN_SERIALIZABLE_TRANSACTION_WEIGHT)
diff --git a/src/blockencodings.h b/src/blockencodings.h
index 326db1b4a7..ce3284bfd5 100644
--- a/src/blockencodings.h
+++ b/src/blockencodings.h
@@ -6,6 +6,7 @@
 #define BITCOIN_BLOCKENCODINGS_H
 
 #include <primitives/block.h>
+#include <util/check.h>
 
 
 class CTxMemPool;
@@ -127,9 +128,10 @@ protected:
     std::vector<CTransactionRef> txn_available;
     size_t prefilled_count = 0, mempool_count = 0, extra_count = 0;
     const CTxMemPool* pool;
+
 public:
     CBlockHeader header;
-    explicit PartiallyDownloadedBlock(CTxMemPool* poolIn) : pool(poolIn) {}
+    explicit PartiallyDownloadedBlock(CTxMemPool* poolIn) : pool(Assume(poolIn)) {}
 
     // extra_txn is a list of extra transactions to look at, in <witness hash, reference> form
     ReadStatus InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<std::pair<uint256, CTransactionRef>>& extra_txn);


bool PeerManagerImpl::AlreadyHaveTx(const GenTxid& gtxid)
{
if (!m_mempool) return false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!m_mempool) return false;
if (!Assume(m_mempool)) return false;

It would be nice if this function wasn't called when no mempool exists. If you agree, I think it makes sense to skip calling this function when txs aren't expected at all:

diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 3ad34e83ba..68e381db60 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -2949,16 +2949,17 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
                     best_block = &inv.hash;
                 }
             } else if (inv.IsGenTxMsg()) {
+                if (fBlocksOnly) {
+                    LogPrint(BCLog::NET, "transaction (%s) inv sent in violation of protocol, disconnecting peer=%d\n", inv.hash.ToString(), pfrom.GetId());
+                    pfrom.fDisconnect = true;
+                    return;
+                }
                 const GenTxid gtxid = ToGenTxid(inv);
                 const bool fAlreadyHave = AlreadyHaveTx(gtxid);
                 LogPrint(BCLog::NET, "got inv: %s  %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom.GetId());
 
                 pfrom.AddKnownTx(inv.hash);
-                if (fBlocksOnly) {
-                    LogPrint(BCLog::NET, "transaction (%s) inv sent in violation of protocol, disconnecting peer=%d\n", inv.hash.ToString(), pfrom.GetId());
-                    pfrom.fDisconnect = true;
-                    return;
-                } else if (!fAlreadyHave && !m_chainman.ActiveChainstate().IsInitialBlockDownload()) {
+                if (!fAlreadyHave && !m_chainman.ActiveChainstate().IsInitialBlockDownload()) {
                     AddTxAnnouncement(pfrom, gtxid, current_time);
                 }
             } else {

Should be done in a separate commit, or even separate pull

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in #23042

@theStack
Copy link
Contributor

theStack commented Sep 5, 2021

Concept ACK

@DrahtBot
Copy link
Contributor

🐙 This pull request conflicts with the target branch and needs rebase.

Want to unsubscribe from rebase notifications on this pull request? Just convert this pull request to a "draft".

@jnewbery
Copy link
Contributor

Concept ACK

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a prerequisite for the introduction of a -nomempool option.

Concept NACK

I dont see any benefits for introducing this option or missing context. Based on related discussions on IRC and mailing list, I don't agree with the concept.

@maflcko
Copy link
Member

maflcko commented Dec 22, 2021

If the -nomempool setting is too abstract (or controversial), I think the changes make a lot of sense on their own.

Removing the requirement of PeerManager to hold a reference to a mempool makes (unit/fuzz) testing easier if there is a test that doesn't need the mempool. Also, it makes the coupling of CTxMemPool and PeerManager a bit more loose. (Maybe that additional motivation can be included in the OP)

Moreover, the mempool is already treated optional in pretty much every other part of the codebase (validation, RPC, ...), so doing it consistently is preferable.

@DrahtBot
Copy link
Contributor

DrahtBot commented Jan 3, 2022

There hasn't been much activity lately and the patch still needs rebase. What is the status here?
  • Is it still relevant? ➡️ Please solve the conflicts to make it ready for review and to ensure the CI passes.
  • Is it no longer relevant? ➡️ Please close.
  • Did the author lose interest or time to work on this? ➡️ Please close it and mark it 'Up for grabs' with the label, so that it can be picked up in the future.

Copy link
Contributor

@jnewbery jnewbery left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approach ACK. It'd be great to see this picked up again.


// Allow peers with relay permission to send data other than blocks in blocks only mode
if (pfrom.HasPermission(NetPermissionFlags::Relay)) {
// Allow peers with relay permission to send data other than blocks in blocks only mode, and if
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence is difficult to understand. Perhaps "If this peer has relay permissions and we have a mempool, allow transactions announcements."

PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& connman, CAddrMan& addrman,
BanMan* banman, ChainstateManager& chainman,
CTxMemPool& pool, bool ignore_incoming_txs)
CTxMemPool* pool, bool ignore_incoming_txs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you're touching this line, consider changing the parameter name to mempool, to match the member variable name m_mempool. Same for the PeerManager ctor.

@DrahtBot
Copy link
Contributor

There hasn't been much activity lately and the patch still needs rebase. What is the status here?
  • Is it still relevant? ➡️ Please solve the conflicts to make it ready for review and to ensure the CI passes.
  • Is it no longer relevant? ➡️ Please close.
  • Did the author lose interest or time to work on this? ➡️ Please close it and mark it 'Up for grabs' with the label, so that it can be picked up in the future.

@fanquake
Copy link
Member

fanquake commented Oct 2, 2022

There is certainly agreement that this is a change we want to make, but this PR has been dead for some time (and multiple pings). Closing and marking as up for grabs.

@bitcoin bitcoin locked and limited conversation to collaborators Oct 4, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants