Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2db55b4
Merge #11524: [net] De-duplicate connection eviction logic
laanwj Nov 8, 2017
78cd1f0
Merge #11635: trivial: Fix typo – alreardy → already
Nov 8, 2017
948863c
Merge #11499: [Qt] Add upload and download info to the peerlist (debu…
jonasschnelli Oct 23, 2017
72d8f89
Merge #10409: [tests] Add fuzz testing for BlockTransactions and Bloc…
laanwj Oct 28, 2017
0160203
Merge #11435: build: Make "make clean" remove all files created when …
laanwj Oct 4, 2017
980a053
Merge #11107: Fix races in AppInitMain and others with lock and atomi…
Oct 5, 2017
aef1eb0
remove explicit on FreespaceChecker
PastaPastaPasta Dec 22, 2019
6d4839f
Merge #11552: Improve wallet-accounts test
laanwj Nov 9, 2017
9c914a1
Merge #10529: Improve bitcoind systemd service file
PastaPastaPasta Dec 22, 2019
79e841f
Merge #11594: Improve -disablewallet parameter interaction
laanwj Nov 9, 2017
3bae57a
Merge #10696: Remove redundant nullptr checks before deallocation
laanwj Nov 9, 2017
354f57a
Merge #10368: [wallet] Remove helper conversion operator from wallet
laanwj Nov 9, 2017
134392f
Merge #11074: Assert that CWallet::SyncMetaData finds oldest transact…
laanwj Nov 9, 2017
bb43baf
Merge #11316: [qt] Add use available balance in send coins dialog (Cr…
Nov 10, 2017
efea728
Merge #11623: tests: Add missing locks to tests
Nov 10, 2017
be98dc3
test_dash continued
PastaPastaPasta Dec 27, 2019
767030b
remove test_bitcoin.cpp
PastaPastaPasta Dec 27, 2019
a969c8d
Merge #11353: Small refactor of CCoinsViewCache::BatchWrite()
Nov 10, 2017
1990f11
Merge #11269: [Mempool] CTxMemPoolEntry::UpdateAncestorState: modifyS…
Nov 10, 2017
c5a7046
Merge #11258: [rpc] Add initialblockdownload to getblockchaininfo
sipa Nov 10, 2017
cc5b2f1
Merge #11055: [wallet] [rpc] getreceivedbyaddress should return error…
Nov 11, 2017
abc0fb0
Merge #3716: GUI: Receive: Remove option to reuse a previous address
Nov 11, 2017
aeaf3c5
Merge #10749: Use compile-time constants instead of unnamed enumerati…
Nov 11, 2017
62e947d
fix receivedby.py
PastaPastaPasta Jan 22, 2020
e211295
fix test/functional/receivedby.py
PastaPastaPasta Jan 22, 2020
7bbe84b
Revert "remove explicit on FreespaceChecker"
PastaPastaPasta Jan 22, 2020
0ca31d1
Fix tests
UdjinM6 Jan 22, 2020
87b9990
Merge branch 'backports-0.16-pr5' of github.com:PastaPastaPasta/dash …
PastaPastaPasta Jan 22, 2020
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
27 changes: 15 additions & 12 deletions contrib/init/dashd.service
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
# It is not recommended to modify this file in-place, because it will
# be overwritten during package upgrades. If you want to add further
# options or overwrite existing ones then use
# $ systemctl edit dashd.service
# See "man systemd.service" for details.

# Note that almost all daemon options could be specified in
# /etc/dash/dash.conf

[Unit]
Description=Dash's distributed currency daemon
Description=Dash daemon
After=network.target

[Service]
ExecStart=/usr/bin/dashd -daemon -conf=/etc/dash/dash.conf -pid=/run/dashd/dashd.pid
# Creates /run/dash owned by dashcore
RuntimeDirectory=dashd
User=dashcore
Group=dashcore

Type=forking
PIDFile=/var/lib/dashd/dashd.pid
ExecStart=/usr/bin/dashd -daemon -pid=/var/lib/dashd/dashd.pid \
-conf=/etc/dashcore/dash.conf -datadir=/var/lib/dashd -disablewallet

Restart=always
PIDFile=/run/dashd/dashd.pid
Restart=on-failure
PrivateTmp=true
TimeoutStopSec=60s
TimeoutStartSec=2s
StartLimitInterval=120s
StartLimitBurst=5

[Install]
WantedBy=multi-user.target
3 changes: 1 addition & 2 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -669,11 +669,10 @@ CLEANFILES += univalue/*.gcda univalue/*.gcno
CLEANFILES += wallet/*.gcda wallet/*.gcno
CLEANFILES += wallet/test/*.gcda wallet/test/*.gcno
CLEANFILES += zmq/*.gcda zmq/*.gcno
CLEANFILES += obj/build.h

IMMER_DIST = immer

DISTCLEANFILES = obj/build.h

EXTRA_DIST = $(CTAES_DIST)
EXTRA_DIST += $(IMMER_DIST)

Expand Down
9 changes: 5 additions & 4 deletions src/Makefile.bench.include
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ bin_PROGRAMS += bench/bench_dash
BENCH_SRCDIR = bench
BENCH_BINARY = bench/bench_dash$(EXEEXT)

RAW_TEST_FILES = \
RAW_BENCH_FILES = \
bench/data/block813851.raw
GENERATED_TEST_FILES = $(RAW_TEST_FILES:.raw=.raw.h)
GENERATED_BENCH_FILES = $(RAW_BENCH_FILES:.raw=.raw.h)

bench_bench_dash_SOURCES = \
$(RAW_BENCH_FILES) \
bench/bench_dash.cpp \
bench/bench.cpp \
bench/bench.h \
Expand All @@ -36,7 +37,7 @@ bench_bench_dash_SOURCES = \
bench/prevector.cpp \
bench/string_cast.cpp

nodist_bench_bench_dash_SOURCES = $(GENERATED_TEST_FILES)
nodist_bench_bench_dash_SOURCES = $(GENERATED_BENCH_FILES)

bench_bench_dash_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CLFAGS) $(EVENT_PTHREADS_CFLAGS) -I$(builddir)/bench/
bench_bench_dash_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
Expand Down Expand Up @@ -64,7 +65,7 @@ endif
bench_bench_dash_LDADD += $(BACKTRACE_LIB) $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(BLS_LIBS)
bench_bench_dash_LDFLAGS = $(LDFLAGS_WRAP_EXCEPTIONS) $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)

CLEAN_BITCOIN_BENCH = bench/*.gcda bench/*.gcno $(GENERATED_TEST_FILES)
CLEAN_BITCOIN_BENCH = bench/*.gcda bench/*.gcno $(GENERATED_BENCH_FILES)

CLEANFILES += $(CLEAN_BITCOIN_BENCH)

Expand Down
2 changes: 1 addition & 1 deletion src/arith_uint256.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ template<unsigned int BITS>
class base_uint
{
protected:
enum { WIDTH=BITS/32 };
static constexpr int WIDTH = BITS / 32;
uint32_t pn[WIDTH];
public:

Expand Down
2 changes: 1 addition & 1 deletion src/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ class CBlockIndex
return (int64_t)nTimeMax;
}

enum { nMedianTimeSpan=11 };
static constexpr int nMedianTimeSpan = 11;

int64_t GetMedianTimePast() const
{
Expand Down
94 changes: 48 additions & 46 deletions src/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,56 +146,58 @@ void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
}

bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
if (it->second.flags & CCoinsCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization).
CCoinsMap::iterator itUs = cacheCoins.find(it->first);
if (itUs == cacheCoins.end()) {
// The parent cache does not have an entry, while the child does
// We can ignore it if it's both FRESH and pruned in the child
if (!(it->second.flags & CCoinsCacheEntry::FRESH && it->second.coin.IsSpent())) {
// Otherwise we will need to create it in the parent
// and move the data up and mark it as dirty
CCoinsCacheEntry& entry = cacheCoins[it->first];
entry.coin = std::move(it->second.coin);
cachedCoinsUsage += entry.coin.DynamicMemoryUsage();
entry.flags = CCoinsCacheEntry::DIRTY;
// We can mark it FRESH in the parent if it was FRESH in the child
// Otherwise it might have just been flushed from the parent's cache
// and already exist in the grandparent
if (it->second.flags & CCoinsCacheEntry::FRESH)
entry.flags |= CCoinsCacheEntry::FRESH;
for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end(); it = mapCoins.erase(it)) {
// Ignore non-dirty entries (optimization).
if (!(it->second.flags & CCoinsCacheEntry::DIRTY)) {
continue;
}
CCoinsMap::iterator itUs = cacheCoins.find(it->first);
if (itUs == cacheCoins.end()) {
// The parent cache does not have an entry, while the child does
// We can ignore it if it's both FRESH and pruned in the child
if (!(it->second.flags & CCoinsCacheEntry::FRESH && it->second.coin.IsSpent())) {
// Otherwise we will need to create it in the parent
// and move the data up and mark it as dirty
CCoinsCacheEntry& entry = cacheCoins[it->first];
entry.coin = std::move(it->second.coin);
cachedCoinsUsage += entry.coin.DynamicMemoryUsage();
entry.flags = CCoinsCacheEntry::DIRTY;
// We can mark it FRESH in the parent if it was FRESH in the child
// Otherwise it might have just been flushed from the parent's cache
// and already exist in the grandparent
if (it->second.flags & CCoinsCacheEntry::FRESH) {
entry.flags |= CCoinsCacheEntry::FRESH;
}
} else {
// Assert that the child cache entry was not marked FRESH if the
// parent cache entry has unspent outputs. If this ever happens,
// it means the FRESH flag was misapplied and there is a logic
// error in the calling code.
if ((it->second.flags & CCoinsCacheEntry::FRESH) && !itUs->second.coin.IsSpent())
throw std::logic_error("FRESH flag misapplied to cache entry for base transaction with spendable outputs");
}
} else {
// Assert that the child cache entry was not marked FRESH if the
// parent cache entry has unspent outputs. If this ever happens,
// it means the FRESH flag was misapplied and there is a logic
// error in the calling code.
if ((it->second.flags & CCoinsCacheEntry::FRESH) && !itUs->second.coin.IsSpent()) {
throw std::logic_error("FRESH flag misapplied to cache entry for base transaction with spendable outputs");
}

// Found the entry in the parent cache
if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coin.IsSpent()) {
// The grandparent does not have an entry, and the child is
// modified and being pruned. This means we can just delete
// it from the parent.
cachedCoinsUsage -= itUs->second.coin.DynamicMemoryUsage();
cacheCoins.erase(itUs);
} else {
// A normal modification.
cachedCoinsUsage -= itUs->second.coin.DynamicMemoryUsage();
itUs->second.coin = std::move(it->second.coin);
cachedCoinsUsage += itUs->second.coin.DynamicMemoryUsage();
itUs->second.flags |= CCoinsCacheEntry::DIRTY;
// NOTE: It is possible the child has a FRESH flag here in
// the event the entry we found in the parent is pruned. But
// we must not copy that FRESH flag to the parent as that
// pruned state likely still needs to be communicated to the
// grandparent.
}
// Found the entry in the parent cache
if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coin.IsSpent()) {
// The grandparent does not have an entry, and the child is
// modified and being pruned. This means we can just delete
// it from the parent.
cachedCoinsUsage -= itUs->second.coin.DynamicMemoryUsage();
cacheCoins.erase(itUs);
} else {
// A normal modification.
cachedCoinsUsage -= itUs->second.coin.DynamicMemoryUsage();
itUs->second.coin = std::move(it->second.coin);
cachedCoinsUsage += itUs->second.coin.DynamicMemoryUsage();
itUs->second.flags |= CCoinsCacheEntry::DIRTY;
// NOTE: It is possible the child has a FRESH flag here in
// the event the entry we found in the parent is pruned. But
// we must not copy that FRESH flag to the parent as that
// pruned state likely still needs to be communicated to the
// grandparent.
}
}
CCoinsMap::iterator itOld = it++;
mapCoins.erase(itOld);
}
hashBlock = hashBlockIn;
return true;
Expand Down
11 changes: 4 additions & 7 deletions src/consensus/consensus.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,9 @@ static const unsigned int MAX_TX_EXTRA_PAYLOAD = 10000;
static const int COINBASE_MATURITY = 100;

/** Flags for nSequence and nLockTime locks */
enum {
/* Interpret sequence numbers as relative lock-time constraints. */
LOCKTIME_VERIFY_SEQUENCE = (1 << 0),

/* Use GetMedianTimePast() instead of nTime for end point timestamp. */
LOCKTIME_MEDIAN_TIME_PAST = (1 << 1),
};
/** Interpret sequence numbers as relative lock-time constraints. */
static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE = (1 << 0);
/** Use GetMedianTimePast() instead of nTime for end point timestamp. */
static constexpr unsigned int LOCKTIME_MEDIAN_TIME_PAST = (1 << 1);

#endif // BITCOIN_CONSENSUS_CONSENSUS_H
12 changes: 9 additions & 3 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2189,9 +2189,15 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)

// ********************************************************* Step 12: start node

int chain_active_height;

//// debug print
LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size());
LogPrintf("chainActive.Height() = %d\n", chainActive.Height());
{
LOCK(cs_main);
LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size());
chain_active_height = chainActive.Height();
}
LogPrintf("chainActive.Height() = %d\n", chain_active_height);
if (gArgs.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION))
StartTorControl(threadGroup, scheduler);

Expand All @@ -2206,7 +2212,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
connOptions.nMaxOutbound = std::min(MAX_OUTBOUND_CONNECTIONS, connOptions.nMaxConnections);
connOptions.nMaxAddnode = MAX_ADDNODE_CONNECTIONS;
connOptions.nMaxFeeler = 1;
connOptions.nBestHeight = chainActive.Height();
connOptions.nBestHeight = chain_active_height;
connOptions.uiInterface = &uiInterface;
connOptions.m_msgproc = peerLogic.get();
connOptions.nSendBufferMaxSize = 1000*gArgs.GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER);
Expand Down
52 changes: 21 additions & 31 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,16 @@ static bool CompareNodeTXTime(const NodeEvictionCandidate &a, const NodeEviction
return a.nTimeConnected > b.nTimeConnected;
}


//! Sort an array by the specified comparator, then erase the last K elements.
template<typename T, typename Comparator>
static void EraseLastKElements(std::vector<T> &elements, Comparator comparator, size_t k)
{
std::sort(elements.begin(), elements.end(), comparator);
size_t eraseSize = std::min(k, elements.size());
elements.erase(elements.end() - eraseSize, elements.end());
}

/** Try to find a connection to evict when the node is full.
* Extreme care must be taken to avoid opening the node to attacker
* triggered network partitioning.
Expand Down Expand Up @@ -1056,42 +1066,23 @@ bool CConnman::AttemptToEvictConnection()
}
}

if (vEvictionCandidates.empty()) return false;

// Protect connections with certain characteristics

// Deterministically select 4 peers to protect by netgroup.
// An attacker cannot predict which netgroups will be protected
std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNetGroupKeyed);
vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());

if (vEvictionCandidates.empty()) return false;

EraseLastKElements(vEvictionCandidates, CompareNetGroupKeyed, 4);
// Protect the 8 nodes with the lowest minimum ping time.
// An attacker cannot manipulate this metric without physically moving nodes closer to the target.
std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeMinPingTime);
vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(8, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());

if (vEvictionCandidates.empty()) return false;

EraseLastKElements(vEvictionCandidates, ReverseCompareNodeMinPingTime, 8);
// Protect 4 nodes that most recently sent us transactions.
// An attacker cannot manipulate this metric without performing useful work.
std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNodeTXTime);
vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());

if (vEvictionCandidates.empty()) return false;

EraseLastKElements(vEvictionCandidates, CompareNodeTXTime, 4);
// Protect 4 nodes that most recently sent us blocks.
// An attacker cannot manipulate this metric without performing useful work.
std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNodeBlockTime);
vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());

if (vEvictionCandidates.empty()) return false;

EraseLastKElements(vEvictionCandidates, CompareNodeBlockTime, 4);
// Protect the half of the remaining nodes which have been connected the longest.
// This replicates the non-eviction implicit behavior, and precludes attacks that start later.
std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
vEvictionCandidates.erase(vEvictionCandidates.end() - static_cast<int>(vEvictionCandidates.size() / 2), vEvictionCandidates.end());
EraseLastKElements(vEvictionCandidates, ReverseCompareNodeTimeConnected, vEvictionCandidates.size() / 2);

if (vEvictionCandidates.empty()) return false;

Expand All @@ -1102,12 +1093,12 @@ bool CConnman::AttemptToEvictConnection()
int64_t nMostConnectionsTime = 0;
std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
for (const NodeEvictionCandidate &node : vEvictionCandidates) {
mapNetGroupNodes[node.nKeyedNetGroup].push_back(node);
int64_t grouptime = mapNetGroupNodes[node.nKeyedNetGroup][0].nTimeConnected;
size_t groupsize = mapNetGroupNodes[node.nKeyedNetGroup].size();
std::vector<NodeEvictionCandidate> &group = mapNetGroupNodes[node.nKeyedNetGroup];
group.push_back(node);
int64_t grouptime = group[0].nTimeConnected;

if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) {
nMostConnections = groupsize;
if (group.size() > nMostConnections || (group.size() == nMostConnections && grouptime > nMostConnectionsTime)) {
nMostConnections = group.size();
nMostConnectionsTime = grouptime;
naMostConnections = node.nKeyedNetGroup;
}
Expand Down Expand Up @@ -3248,8 +3239,7 @@ CNode::~CNode()
{
CloseSocket(hSocket);

if (pfilter)
delete pfilter;
delete pfilter;
}

void CNode::AskFor(const CInv& inv, int64_t doubleRequestDelay)
Expand Down
17 changes: 7 additions & 10 deletions src/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,13 @@
class CMessageHeader
{
public:
enum {
MESSAGE_START_SIZE = 4,
COMMAND_SIZE = 12,
MESSAGE_SIZE_SIZE = 4,
CHECKSUM_SIZE = 4,

MESSAGE_SIZE_OFFSET = MESSAGE_START_SIZE + COMMAND_SIZE,
CHECKSUM_OFFSET = MESSAGE_SIZE_OFFSET + MESSAGE_SIZE_SIZE,
HEADER_SIZE = MESSAGE_START_SIZE + COMMAND_SIZE + MESSAGE_SIZE_SIZE + CHECKSUM_SIZE
};
static constexpr size_t MESSAGE_START_SIZE = 4;
static constexpr size_t COMMAND_SIZE = 12;
static constexpr size_t MESSAGE_SIZE_SIZE = 4;
static constexpr size_t CHECKSUM_SIZE = 4;
static constexpr size_t MESSAGE_SIZE_OFFSET = MESSAGE_START_SIZE + COMMAND_SIZE;
static constexpr size_t CHECKSUM_OFFSET = MESSAGE_SIZE_OFFSET + MESSAGE_SIZE_SIZE;
static constexpr size_t HEADER_SIZE = MESSAGE_START_SIZE + COMMAND_SIZE + MESSAGE_SIZE_SIZE + CHECKSUM_SIZE;
typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];

explicit CMessageHeader(const MessageStartChars& pchMessageStartIn);
Expand Down
Loading