Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NET] Inv, mempool and validation improvements #2118

Merged
merged 32 commits into from
Jan 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
c30fa16
CTxMemPool::removeForBlock now uses RemoveStaged
furszy Dec 24, 2020
ba32375
Rename CTxMemPool::remove -> removeRecursive remove is no longer cal…
furszy Dec 24, 2020
1fa40ac
Remove work limit in UpdateForDescendants() The work limit served to…
furszy Dec 24, 2020
8325bb4
Fix mempool limiting for PrioritiseTransaction
furszy Dec 24, 2020
64e84e2
Add ancestor tracking to mempool This implements caching of ancestor…
furszy Dec 24, 2020
91c6096
Add ancestor feerate index to mempool
sdaftuar Oct 19, 2015
8c0016e
Check all ancestor state in CTxMemPool::check()
furszy Dec 24, 2020
6ebfd17
tiny test fix for mempool_tests
morcos Dec 6, 2016
23c9f3e
Eliminate TX trickle bypass, sort TX invs for privacy and priority.
furszy Dec 26, 2020
191c62e
Return mempool queries in dependency order
sipa Apr 10, 2016
7624823
mapNextTx: use pointer as key, simplify value
furszy Dec 26, 2020
68bc68f
Don't do mempool lookups for "mempool" command without a filter
furszy Dec 28, 2020
9645775
Split up and optimize transaction and block inv queues
furszy Dec 31, 2020
cb4fc6c
An adapted version of btc@ed7068302c7490e8061cb3a558a0f83a465beeea
furszy Dec 31, 2020
d10583b
An adapted version of btc@b5599147533103efea896a1fc4ff51f2d3ad5808
furszy Dec 31, 2020
35bc2a9
Finished the switch CTransaction storage in mempool to CTransactionRe…
furszy Dec 31, 2020
54cf7c0
Get rid of CTxMempool::lookup() entirely
furszy Dec 31, 2020
e51c4b8
Bypass removeRecursive in removeForReorg
sipa Jan 13, 2021
4f672c2
Make removed and conflicted arguments optional to remove
sipa Jan 13, 2021
9979f3d
[mempool] move removed and conflicts transaction ref list to vector.
furszy Jan 13, 2021
6bbc6a9
Add feedelta to TxMempoolInfo
sipa Jul 31, 2016
44c635d
Add AcceptToMemoryPoolWithTime function
sipa Jan 13, 2021
8e52226
Add DumpMempool and LoadMempool
sipa Jan 14, 2021
f0c2255
Add mempool.dat to doc/files.md
furszy Jan 14, 2021
c0a0e81
Moving TxMempoolInfo tx member to CTransactionRef
furszy Jan 14, 2021
e60da98
Allow shutdown during LoadMempool, dump only when necessary
jonasschnelli Dec 22, 2016
5d949de
[Qt] Do proper shutdown
jonasschnelli Jan 14, 2021
4f26a4e
Control mempool persistence using a command line parameter.
jnewbery Jan 14, 2021
c6d45c6
Adapting and connecting mempool_persist.py functional test to the tes…
furszy Jan 17, 2021
006c503
[wallet] fix zapwallettxes interaction with persistent mempool
jnewbery Jan 17, 2021
d6d0ad9
[logs] fix zapwallettxes startup logs
jnewbery Jan 17, 2021
9b9c616
Fix missing zapwallettxes mode in wallet_hd.py functional test
furszy Jan 18, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ set(SERVER_SOURCES
./src/checkpoints.cpp
./src/httprpc.cpp
./src/httpserver.cpp
./src/indirectmap.h
./src/init.cpp
./src/interfaces/handler.cpp
./src/interfaces/wallet.cpp
Expand Down
1 change: 1 addition & 0 deletions doc/files.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ database/* | BDB database environment; only used for wallet since 0.8.0
db.log | wallet database log file; moved to wallets/ directory on new installs since 0.16.0
debug.log | contains debug information and general logging generated by pivxd or pivx-qt
fee_estimates.dat | stores statistics used to estimate minimum transaction fees and priorities required for confirmation; since 0.10.0
mempool.dat | dump of the mempool's transactions; since 5.0.2
budget.dat | stores data for budget objects
masternode.conf | contains configuration settings for remote masternodes
mncache.dat | stores data for masternode list
Expand Down
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ BITCOIN_CORE_H = \
hash.h \
httprpc.h \
httpserver.h \
indirectmap.h \
init.h \
interfaces/handler.h \
interfaces/wallet.h \
Expand Down
58 changes: 58 additions & 0 deletions src/indirectmap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) 2016-2020 The Bitcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_INDIRECTMAP_H
#define BITCOIN_INDIRECTMAP_H

#include <map>

template <class T>
struct DereferencingComparator { bool operator()(const T a, const T b) const { return *a < *b; } };

/* Map whose keys are pointers, but are compared by their dereferenced values.
*
* Differs from a plain std::map<const K*, T, DereferencingComparator<K*> > in
* that methods that take a key for comparison take a K rather than taking a K*
* (taking a K* would be confusing, since it's the value rather than the address
* of the object for comparison that matters due to the dereferencing comparator).
*
* Objects pointed to by keys must not be modified in any way that changes the
* result of DereferencingComparator.
*/
template <class K, class T>
class indirectmap {
private:
typedef std::map<const K*, T, DereferencingComparator<const K*> > base;
base m;
public:
typedef typename base::iterator iterator;
typedef typename base::const_iterator const_iterator;
typedef typename base::size_type size_type;
typedef typename base::value_type value_type;

// passthrough (pointer interface)
std::pair<iterator, bool> insert(const value_type& value) { return m.insert(value); }

// pass address (value interface)
iterator find(const K& key) { return m.find(&key); }
const_iterator find(const K& key) const { return m.find(&key); }
iterator lower_bound(const K& key) { return m.lower_bound(&key); }
const_iterator lower_bound(const K& key) const { return m.lower_bound(&key); }
size_type erase(const K& key) { return m.erase(&key); }
size_type count(const K& key) const { return m.count(&key); }

// passthrough
bool empty() const { return m.empty(); }
size_type size() const { return m.size(); }
size_type max_size() const { return m.max_size(); }
void clear() { m.clear(); }
iterator begin() { return m.begin(); }
iterator end() { return m.end(); }
const_iterator begin() const { return m.begin(); }
const_iterator end() const { return m.end(); }
const_iterator cbegin() const { return m.cbegin(); }
const_iterator cend() const { return m.cend(); }
};

#endif // BITCOIN_INDIRECTMAP_H
22 changes: 19 additions & 3 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ CClientUIInterface uiInterface; // Declared but not defined in guiinterface.h
//

volatile bool fRequestShutdown = false;
std::atomic<bool> fDumpMempoolLater(false);

void StartShutdown()
{
Expand Down Expand Up @@ -245,6 +246,9 @@ void PrepareShutdown()
DumpBudgets(g_budgetman);
DumpMasternodePayments();
UnregisterNodeSignals(GetNodeSignals());
if (fDumpMempoolLater && gArgs.GetBoolArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
DumpMempool();
}

// After everything has been shut down, but before things get flushed, stop the
// CScheduler/checkqueue threadGroup
Expand Down Expand Up @@ -418,6 +422,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
strUsage += HelpMessageOpt("-maxmempool=<n>", strprintf(_("Keep the transaction memory pool below <n> megabytes (default: %u)"), DEFAULT_MAX_MEMPOOL_SIZE));
strUsage += HelpMessageOpt("-mempoolexpiry=<n>", strprintf(_("Do not keep transactions in the mempool longer than <n> hours (default: %u)"), DEFAULT_MEMPOOL_EXPIRY));
strUsage += HelpMessageOpt("-persistmempool", strprintf(_("Whether to save the mempool on shutdown and load on restart (default: %u)"), DEFAULT_PERSIST_MEMPOOL));
strUsage += HelpMessageOpt("-par=<n>", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -GetNumCores(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS));
#ifndef WIN32
strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), PIVX_PID_FILENAME));
Expand Down Expand Up @@ -700,6 +705,11 @@ void ThreadImport(std::vector<fs::path> vImportFiles)
LogPrintf("Stopping after block import\n");
StartShutdown();
}

if (gArgs.GetBoolArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
LoadMempool();
fDumpMempoolLater = !fRequestShutdown;
}
}

/** Sanity checks
Expand Down Expand Up @@ -899,10 +909,16 @@ void InitParameterInteraction()
LogPrintf("%s : parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__);
}

// -zapwallettx implies a rescan
if (gArgs.GetBoolArg("-zapwallettxes", false)) {
int zapwallettxes = gArgs.GetArg("-zapwallettxes", 0);
// -zapwallettxes implies dropping the mempool on startup
if (zapwallettxes != 0 && gArgs.SoftSetBoolArg("-persistmempool", false)) {
LogPrintf("%s: parameter interaction: -zapwallettxes=%s -> setting -persistmempool=0\n", __func__, zapwallettxes);
}

// -zapwallettxes implies a rescan
if (zapwallettxes != 0) {
if (gArgs.SoftSetBoolArg("-rescan", true))
LogPrintf("%s : parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n", __func__);
LogPrintf("%s : parameter interaction: -zapwallettxes=%s -> setting -rescan=1\n", __func__, zapwallettxes);
}
}

Expand Down
15 changes: 15 additions & 0 deletions src/memusage.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef BITCOIN_MEMUSAGE_H
#define BITCOIN_MEMUSAGE_H

#include "indirectmap.h"
#include "prevector.h"

#include <stdlib.h>
Expand Down Expand Up @@ -185,6 +186,20 @@ static inline size_t DynamicUsage(const std::shared_ptr<X>& p)
return p ? MallocUsage(sizeof(X)) + MallocUsage(sizeof(stl_shared_counter)) : 0;
}

// indirectmap has underlying map with pointer as key

template<typename X, typename Y>
static inline size_t DynamicUsage(const indirectmap<X, Y>& m)
{
return MallocUsage(sizeof(stl_tree_node<std::pair<const X*, Y> >)) * m.size();
}

template<typename X, typename Y>
static inline size_t IncrementalDynamicUsage(const indirectmap<X, Y>& m)
{
return MallocUsage(sizeof(stl_tree_node<std::pair<const X*, Y> >));
}

// Boost data structures

template<typename X>
Expand Down
2 changes: 2 additions & 0 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2438,12 +2438,14 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
hashContinue = UINT256_ZERO;
nStartingHeight = -1;
filterInventoryKnown.reset();
fSendMempool = false;
fGetAddr = false;
nNextLocalAddrSend = 0;
nNextAddrSend = 0;
nNextInvSend = 0;
fRelayTxes = false;
pfilter = new CBloomFilter();
timeLastMempoolReq = 0;
nPingNonceSent = 0;
nPingUsecStart = 0;
nPingUsecTime = 0;
Expand Down
31 changes: 24 additions & 7 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ class CNode
// a) it allows us to not relay tx invs before receiving the peer's version message
// b) the peer may tell us in their version message that we should not relay tx invs
// until they have initialized their bloom filter.
bool fRelayTxes;
bool fRelayTxes; //protected by cs_filter
CSemaphoreGrant grantOutbound;
RecursiveMutex cs_filter;
CBloomFilter* pfilter;
Expand Down Expand Up @@ -610,11 +610,24 @@ class CNode

// inventory based relay
CRollingBloomFilter filterInventoryKnown;
std::vector<CInv> vInventoryToSend;
// Set of transaction ids we still have to announce.
// They are sorted by the mempool before relay, so the order is not important.
std::set<uint256> setInventoryTxToSend;
// List of block ids we still have announce.
// There is no final sorting before sending, as they are always sent immediately
// and in the order requested.
std::vector<uint256> vInventoryBlockToSend;
// Set of tier two messages ids we still have to announce.
std::vector<CInv> vInventoryTierTwoToSend;
RecursiveMutex cs_inventory;
std::multimap<int64_t, CInv> mapAskFor;
std::vector<uint256> vBlockRequested;
int64_t nNextInvSend;
// Used for BIP35 mempool sending, also protected by cs_inventory
bool fSendMempool;

// Last time a "MEMPOOL" request was serviced.
std::atomic<int64_t> timeLastMempoolReq{0};

// Ping time measurement:
// The pong reply we're expecting, or 0 if no pong expected.
Expand Down Expand Up @@ -735,11 +748,15 @@ class CNode

void PushInventory(const CInv& inv)
{
{
LOCK(cs_inventory);
if (inv.type == MSG_TX && filterInventoryKnown.contains(inv.hash))
return;
vInventoryToSend.push_back(inv);
LOCK(cs_inventory);
if (inv.type == MSG_TX) {
if (!filterInventoryKnown.contains(inv.hash)) {
setInventoryTxToSend.insert(inv.hash);
}
} else if (inv.type == MSG_BLOCK) {
vInventoryBlockToSend.push_back(inv.hash);
} else {
vInventoryTierTwoToSend.emplace_back(inv);
}
}

Expand Down
Loading