Auto merge of #5265 - str4d:zip-239-prep-1, r=str4d
ZIP 239 preparations 1 This is the first of several backports to prepare for ZIP 239. The primary change is altering `mapRelay` to store `CTransaction`s, which we need because ZIP 239 requires changing `Inv` messages based on transaction versions. The other changes are mainly for conflict removal but are also independently useful. Backports the following upstream PRs: - bitcoin/bitcoin#6889 - bitcoin/bitcoin#7125 - bitcoin/bitcoin#7862 - bitcoin/bitcoin#7877
This commit is contained in:
commit
1cb1ed2653
|
@ -51,7 +51,7 @@ class TxExpiringSoonTest(BitcoinTestFramework):
|
||||||
testnode.send_message(msg_mempool())
|
testnode.send_message(msg_mempool())
|
||||||
|
|
||||||
# Sync up with node after p2p messages delivered
|
# Sync up with node after p2p messages delivered
|
||||||
testnode.sync_with_ping()
|
testnode.sync_with_ping(waiting_for=lambda x: x.last_inv)
|
||||||
|
|
||||||
with mininode_lock:
|
with mininode_lock:
|
||||||
msg = testnode.last_inv
|
msg = testnode.last_inv
|
||||||
|
|
|
@ -63,6 +63,7 @@ class ShorterBlockTimes(BitcoinTestFramework):
|
||||||
myopid = self.nodes[0].z_sendmany(node0_taddr, recipients, 1, 0)
|
myopid = self.nodes[0].z_sendmany(node0_taddr, recipients, 1, 0)
|
||||||
txid = wait_and_assert_operationid_status(self.nodes[0], myopid)
|
txid = wait_and_assert_operationid_status(self.nodes[0], myopid)
|
||||||
assert_equal(147, self.nodes[0].getrawtransaction(txid, 1)['expiryheight']) # height + 1 + 40
|
assert_equal(147, self.nodes[0].getrawtransaction(txid, 1)['expiryheight']) # height + 1 + 40
|
||||||
|
self.sync_all() # Ensure the transaction has propagated to node 1
|
||||||
self.nodes[1].generate(1)
|
self.nodes[1].generate(1)
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
assert_equal(20, Decimal(self.nodes[0].z_gettotalbalance()['private']))
|
assert_equal(20, Decimal(self.nodes[0].z_gettotalbalance()['private']))
|
||||||
|
|
|
@ -66,12 +66,13 @@ class TestNode(NodeConnCB):
|
||||||
|
|
||||||
# The following function is mostly copied from p2p-acceptblock.py
|
# The following function is mostly copied from p2p-acceptblock.py
|
||||||
# Sync up with the node after delivery of a message
|
# Sync up with the node after delivery of a message
|
||||||
def sync_with_ping(self, timeout=30):
|
def sync_with_ping(self, timeout=30, waiting_for=None):
|
||||||
self.connection.send_message(msg_ping(nonce=self.ping_counter))
|
self.connection.send_message(msg_ping(nonce=self.ping_counter))
|
||||||
sleep_time = 0.05
|
sleep_time = 0.05
|
||||||
while timeout > 0:
|
while timeout > 0:
|
||||||
with mininode_lock:
|
with mininode_lock:
|
||||||
if self.last_pong.nonce == self.ping_counter:
|
ready = True if waiting_for is None else waiting_for(self) is not None
|
||||||
|
if ready and self.last_pong.nonce == self.ping_counter:
|
||||||
self.ping_counter += 1
|
self.ping_counter += 1
|
||||||
return
|
return
|
||||||
time.sleep(sleep_time)
|
time.sleep(sleep_time)
|
||||||
|
|
43
src/main.cpp
43
src/main.cpp
|
@ -6150,7 +6150,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
||||||
// Send stream from relay memory
|
// Send stream from relay memory
|
||||||
{
|
{
|
||||||
LOCK(cs_mapRelay);
|
LOCK(cs_mapRelay);
|
||||||
map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
|
map<uint256, CTransaction>::iterator mi = mapRelay.find(inv.hash);
|
||||||
if (mi != mapRelay.end()) {
|
if (mi != mapRelay.end()) {
|
||||||
pfrom->PushMessage(inv.GetCommand(), (*mi).second);
|
pfrom->PushMessage(inv.GetCommand(), (*mi).second);
|
||||||
pushed = true;
|
pushed = true;
|
||||||
|
@ -6158,10 +6158,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
||||||
}
|
}
|
||||||
if (!pushed && inv.type == MSG_TX) {
|
if (!pushed && inv.type == MSG_TX) {
|
||||||
if (isInMempool) {
|
if (isInMempool) {
|
||||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
pfrom->PushMessage("tx", tx);
|
||||||
ss.reserve(1000);
|
|
||||||
ss << tx;
|
|
||||||
pfrom->PushMessage("tx", ss);
|
|
||||||
pushed = true;
|
pushed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6673,7 +6670,7 @@ bool static ProcessMessage(const CChainParams& chainparams, CNode* pfrom, string
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
|
|
||||||
pfrom->setAskFor.erase(inv.hash);
|
pfrom->setAskFor.erase(inv.hash);
|
||||||
mapAlreadyAskedFor.erase(inv);
|
mapAlreadyAskedFor.erase(inv.hash);
|
||||||
|
|
||||||
if (!AlreadyHave(inv) && AcceptToMemoryPool(chainparams, mempool, state, tx, true, &fMissingInputs))
|
if (!AlreadyHave(inv) && AcceptToMemoryPool(chainparams, mempool, state, tx, true, &fMissingInputs))
|
||||||
{
|
{
|
||||||
|
@ -7301,7 +7298,7 @@ bool ProcessMessages(const CChainParams& chainparams, CNode* pfrom)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SendMessages(const Consensus::Params& params, CNode* pto, bool fSendTrickle)
|
bool SendMessages(const Consensus::Params& params, CNode* pto)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
// Don't send anything until we get its version message
|
// Don't send anything until we get its version message
|
||||||
|
@ -7342,28 +7339,17 @@ bool SendMessages(const Consensus::Params& params, CNode* pto, bool fSendTrickle
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Address refresh broadcast
|
// Address refresh broadcast
|
||||||
static int64_t nLastRebroadcast;
|
int64_t nNow = GetTimeMicros();
|
||||||
if (!IsInitialBlockDownload(params) && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
|
if (!IsInitialBlockDownload(params) && pto->nNextLocalAddrSend < nNow) {
|
||||||
{
|
AdvertizeLocal(pto);
|
||||||
LOCK(cs_vNodes);
|
pto->nNextLocalAddrSend = PoissonNextSend(nNow, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
|
||||||
for (CNode* pnode : vNodes)
|
|
||||||
{
|
|
||||||
// Periodically clear addrKnown to allow refresh broadcasts
|
|
||||||
if (nLastRebroadcast)
|
|
||||||
pnode->addrKnown.reset();
|
|
||||||
|
|
||||||
// Rebroadcast our address
|
|
||||||
AdvertizeLocal(pnode);
|
|
||||||
}
|
|
||||||
if (!vNodes.empty())
|
|
||||||
nLastRebroadcast = GetTime();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Message: addr
|
// Message: addr
|
||||||
//
|
//
|
||||||
if (fSendTrickle)
|
if (pto->nNextAddrSend < nNow) {
|
||||||
{
|
pto->nNextAddrSend = PoissonNextSend(nNow, AVG_ADDRESS_BROADCAST_INTERVAL);
|
||||||
vector<CAddress> vAddr;
|
vector<CAddress> vAddr;
|
||||||
vAddr.reserve(pto->vAddrToSend.size());
|
vAddr.reserve(pto->vAddrToSend.size());
|
||||||
for (const CAddress& addr : pto->vAddrToSend)
|
for (const CAddress& addr : pto->vAddrToSend)
|
||||||
|
@ -7443,8 +7429,13 @@ bool SendMessages(const Consensus::Params& params, CNode* pto, bool fSendTrickle
|
||||||
vector<CInv> vInv;
|
vector<CInv> vInv;
|
||||||
vector<CInv> vInvWait;
|
vector<CInv> vInvWait;
|
||||||
{
|
{
|
||||||
|
bool fSendTrickle = pto->fWhitelisted;
|
||||||
|
if (pto->nNextInvSend < nNow) {
|
||||||
|
fSendTrickle = true;
|
||||||
|
pto->nNextInvSend = PoissonNextSend(nNow, AVG_INVENTORY_BROADCAST_INTERVAL);
|
||||||
|
}
|
||||||
LOCK(pto->cs_inventory);
|
LOCK(pto->cs_inventory);
|
||||||
vInv.reserve(pto->vInventoryToSend.size());
|
vInv.reserve(std::min<size_t>(1000, pto->vInventoryToSend.size()));
|
||||||
vInvWait.reserve(pto->vInventoryToSend.size());
|
vInvWait.reserve(pto->vInventoryToSend.size());
|
||||||
for (const CInv& inv : pto->vInventoryToSend)
|
for (const CInv& inv : pto->vInventoryToSend)
|
||||||
{
|
{
|
||||||
|
@ -7484,7 +7475,7 @@ bool SendMessages(const Consensus::Params& params, CNode* pto, bool fSendTrickle
|
||||||
pto->PushMessage("inv", vInv);
|
pto->PushMessage("inv", vInv);
|
||||||
|
|
||||||
// Detect whether we're stalling
|
// Detect whether we're stalling
|
||||||
int64_t nNow = GetTimeMicros();
|
nNow = GetTimeMicros();
|
||||||
if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
|
if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
|
||||||
// Stalling only triggers when the block download window cannot move. During normal steady state,
|
// Stalling only triggers when the block download window cannot move. During normal steady state,
|
||||||
// the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
|
// the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
|
||||||
|
|
11
src/main.h
11
src/main.h
|
@ -114,6 +114,14 @@ static const unsigned int WITNESS_WRITE_INTERVAL = 10 * 60;
|
||||||
static const unsigned int WITNESS_WRITE_UPDATES = 10000;
|
static const unsigned int WITNESS_WRITE_UPDATES = 10000;
|
||||||
/** Maximum length of reject messages. */
|
/** Maximum length of reject messages. */
|
||||||
static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111;
|
static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111;
|
||||||
|
/** Average delay between local address broadcasts in seconds. */
|
||||||
|
static const unsigned int AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL = 24 * 24 * 60;
|
||||||
|
/** Average delay between peer address broadcasts in seconds. */
|
||||||
|
static const unsigned int AVG_ADDRESS_BROADCAST_INTERVAL = 30;
|
||||||
|
/** Average delay between trickled inventory broadcasts in seconds.
|
||||||
|
* Blocks, whitelisted receivers, and a random 25% of transactions bypass this. */
|
||||||
|
static const unsigned int AVG_INVENTORY_BROADCAST_INTERVAL = 5;
|
||||||
|
|
||||||
static const unsigned int DEFAULT_LIMITFREERELAY = 15;
|
static const unsigned int DEFAULT_LIMITFREERELAY = 15;
|
||||||
static const bool DEFAULT_RELAYPRIORITY = false;
|
static const bool DEFAULT_RELAYPRIORITY = false;
|
||||||
static const int64_t DEFAULT_MAX_TIP_AGE = 24 * 60 * 60;
|
static const int64_t DEFAULT_MAX_TIP_AGE = 24 * 60 * 60;
|
||||||
|
@ -256,9 +264,8 @@ bool ProcessMessages(const CChainParams& chainparams, CNode* pfrom);
|
||||||
*
|
*
|
||||||
* @param[in] params Active chain parameters.
|
* @param[in] params Active chain parameters.
|
||||||
* @param[in] pto The node which we are sending messages to.
|
* @param[in] pto The node which we are sending messages to.
|
||||||
* @param[in] fSendTrickle When true send the trickled data, otherwise trickle the data until true.
|
|
||||||
*/
|
*/
|
||||||
bool SendMessages(const Consensus::Params& params, CNode* pto, bool fSendTrickle);
|
bool SendMessages(const Consensus::Params& params, CNode* pto);
|
||||||
/** Run an instance of the script checking thread */
|
/** Run an instance of the script checking thread */
|
||||||
void ThreadScriptCheck();
|
void ThreadScriptCheck();
|
||||||
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
|
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
|
||||||
|
|
39
src/net.cpp
39
src/net.cpp
|
@ -30,6 +30,8 @@
|
||||||
|
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include <rust/metrics.h>
|
#include <rust/metrics.h>
|
||||||
|
|
||||||
// Dump addresses to peers.dat and banlist.dat every 15 minutes (900s)
|
// Dump addresses to peers.dat and banlist.dat every 15 minutes (900s)
|
||||||
|
@ -71,10 +73,10 @@ std::string strSubVersion;
|
||||||
|
|
||||||
vector<CNode*> vNodes;
|
vector<CNode*> vNodes;
|
||||||
CCriticalSection cs_vNodes;
|
CCriticalSection cs_vNodes;
|
||||||
map<CInv, CDataStream> mapRelay;
|
map<uint256, CTransaction> mapRelay;
|
||||||
deque<pair<int64_t, CInv> > vRelayExpiration;
|
deque<pair<int64_t, uint256> > vRelayExpiration;
|
||||||
CCriticalSection cs_mapRelay;
|
CCriticalSection cs_mapRelay;
|
||||||
limitedmap<CInv, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
|
limitedmap<uint256, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
|
||||||
|
|
||||||
static deque<string> vOneShots;
|
static deque<string> vOneShots;
|
||||||
static CCriticalSection cs_vOneShots;
|
static CCriticalSection cs_vOneShots;
|
||||||
|
@ -1692,11 +1694,6 @@ void ThreadMessageHandler()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Poll the connected nodes for messages
|
|
||||||
CNode* pnodeTrickle = NULL;
|
|
||||||
if (!vNodesCopy.empty())
|
|
||||||
pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
|
|
||||||
|
|
||||||
bool fSleep = true;
|
bool fSleep = true;
|
||||||
|
|
||||||
for (CNode* pnode : vNodesCopy)
|
for (CNode* pnode : vNodesCopy)
|
||||||
|
@ -1729,7 +1726,7 @@ void ThreadMessageHandler()
|
||||||
{
|
{
|
||||||
TRY_LOCK(pnode->cs_vSend, lockSend);
|
TRY_LOCK(pnode->cs_vSend, lockSend);
|
||||||
if (lockSend)
|
if (lockSend)
|
||||||
g_signals.SendMessages(chainparams.GetConsensus(), pnode, pnode == pnodeTrickle || pnode->fWhitelisted);
|
g_signals.SendMessages(chainparams.GetConsensus(), pnode);
|
||||||
}
|
}
|
||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
}
|
}
|
||||||
|
@ -2036,14 +2033,6 @@ instance_of_cnetcleanup;
|
||||||
|
|
||||||
|
|
||||||
void RelayTransaction(const CTransaction& tx)
|
void RelayTransaction(const CTransaction& tx)
|
||||||
{
|
|
||||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
|
||||||
ss.reserve(10000);
|
|
||||||
ss << tx;
|
|
||||||
RelayTransaction(tx, ss);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RelayTransaction(const CTransaction& tx, const CDataStream& ss)
|
|
||||||
{
|
{
|
||||||
CInv inv(MSG_TX, tx.GetHash());
|
CInv inv(MSG_TX, tx.GetHash());
|
||||||
{
|
{
|
||||||
|
@ -2055,9 +2044,8 @@ void RelayTransaction(const CTransaction& tx, const CDataStream& ss)
|
||||||
vRelayExpiration.pop_front();
|
vRelayExpiration.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save original serialized message so newer versions are preserved
|
mapRelay.insert(std::make_pair(inv.hash, tx));
|
||||||
mapRelay.insert(std::make_pair(inv, ss));
|
vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv.hash));
|
||||||
vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
|
|
||||||
}
|
}
|
||||||
LOCK(cs_vNodes);
|
LOCK(cs_vNodes);
|
||||||
for (CNode* pnode : vNodes)
|
for (CNode* pnode : vNodes)
|
||||||
|
@ -2258,6 +2246,9 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
|
||||||
nStartingHeight = -1;
|
nStartingHeight = -1;
|
||||||
filterInventoryKnown.reset();
|
filterInventoryKnown.reset();
|
||||||
fGetAddr = false;
|
fGetAddr = false;
|
||||||
|
nNextLocalAddrSend = 0;
|
||||||
|
nNextAddrSend = 0;
|
||||||
|
nNextInvSend = 0;
|
||||||
fRelayTxes = false;
|
fRelayTxes = false;
|
||||||
fSentAddr = false;
|
fSentAddr = false;
|
||||||
pfilter = new CBloomFilter();
|
pfilter = new CBloomFilter();
|
||||||
|
@ -2318,7 +2309,7 @@ void CNode::AskFor(const CInv& inv)
|
||||||
// We're using mapAskFor as a priority queue,
|
// We're using mapAskFor as a priority queue,
|
||||||
// the key is the earliest time the request can be sent
|
// the key is the earliest time the request can be sent
|
||||||
int64_t nRequestTime;
|
int64_t nRequestTime;
|
||||||
limitedmap<CInv, int64_t>::const_iterator it = mapAlreadyAskedFor.find(inv);
|
limitedmap<uint256, int64_t>::const_iterator it = mapAlreadyAskedFor.find(inv.hash);
|
||||||
if (it != mapAlreadyAskedFor.end())
|
if (it != mapAlreadyAskedFor.end())
|
||||||
nRequestTime = it->second;
|
nRequestTime = it->second;
|
||||||
else
|
else
|
||||||
|
@ -2337,7 +2328,7 @@ void CNode::AskFor(const CInv& inv)
|
||||||
if (it != mapAlreadyAskedFor.end())
|
if (it != mapAlreadyAskedFor.end())
|
||||||
mapAlreadyAskedFor.update(it, nRequestTime);
|
mapAlreadyAskedFor.update(it, nRequestTime);
|
||||||
else
|
else
|
||||||
mapAlreadyAskedFor.insert(std::make_pair(inv, nRequestTime));
|
mapAlreadyAskedFor.insert(std::make_pair(inv.hash, nRequestTime));
|
||||||
mapAskFor.insert(std::make_pair(nRequestTime, inv));
|
mapAskFor.insert(std::make_pair(nRequestTime, inv));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2418,3 +2409,7 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
|
||||||
|
|
||||||
return CSipHasher(k0, k1).Write(&vchNetGroup[0], vchNetGroup.size()).Finalize();
|
return CSipHasher(k0, k1).Write(&vchNetGroup[0], vchNetGroup.size()).Finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
|
||||||
|
return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
|
||||||
|
}
|
||||||
|
|
15
src/net.h
15
src/net.h
|
@ -117,7 +117,7 @@ struct CNodeSignals
|
||||||
{
|
{
|
||||||
boost::signals2::signal<int ()> GetHeight;
|
boost::signals2::signal<int ()> GetHeight;
|
||||||
boost::signals2::signal<bool (const CChainParams&, CNode*), CombinerAll> ProcessMessages;
|
boost::signals2::signal<bool (const CChainParams&, CNode*), CombinerAll> ProcessMessages;
|
||||||
boost::signals2::signal<bool (const Consensus::Params&, CNode*, bool), CombinerAll> SendMessages;
|
boost::signals2::signal<bool (const Consensus::Params&, CNode*), CombinerAll> SendMessages;
|
||||||
boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
|
boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
|
||||||
boost::signals2::signal<void (NodeId)> FinalizeNode;
|
boost::signals2::signal<void (NodeId)> FinalizeNode;
|
||||||
};
|
};
|
||||||
|
@ -164,10 +164,10 @@ extern int nMaxConnections;
|
||||||
|
|
||||||
extern std::vector<CNode*> vNodes;
|
extern std::vector<CNode*> vNodes;
|
||||||
extern CCriticalSection cs_vNodes;
|
extern CCriticalSection cs_vNodes;
|
||||||
extern std::map<CInv, CDataStream> mapRelay;
|
extern std::map<uint256, CTransaction> mapRelay;
|
||||||
extern std::deque<std::pair<int64_t, CInv> > vRelayExpiration;
|
extern std::deque<std::pair<int64_t, uint256> > vRelayExpiration;
|
||||||
extern CCriticalSection cs_mapRelay;
|
extern CCriticalSection cs_mapRelay;
|
||||||
extern limitedmap<CInv, int64_t> mapAlreadyAskedFor;
|
extern limitedmap<uint256, int64_t> mapAlreadyAskedFor;
|
||||||
|
|
||||||
extern std::vector<std::string> vAddedNodes;
|
extern std::vector<std::string> vAddedNodes;
|
||||||
extern CCriticalSection cs_vAddedNodes;
|
extern CCriticalSection cs_vAddedNodes;
|
||||||
|
@ -336,6 +336,8 @@ public:
|
||||||
CRollingBloomFilter addrKnown;
|
CRollingBloomFilter addrKnown;
|
||||||
bool fGetAddr;
|
bool fGetAddr;
|
||||||
std::set<uint256> setKnown;
|
std::set<uint256> setKnown;
|
||||||
|
int64_t nNextAddrSend;
|
||||||
|
int64_t nNextLocalAddrSend;
|
||||||
|
|
||||||
// inventory based relay
|
// inventory based relay
|
||||||
CRollingBloomFilter filterInventoryKnown;
|
CRollingBloomFilter filterInventoryKnown;
|
||||||
|
@ -343,6 +345,7 @@ public:
|
||||||
CCriticalSection cs_inventory;
|
CCriticalSection cs_inventory;
|
||||||
std::set<uint256> setAskFor;
|
std::set<uint256> setAskFor;
|
||||||
std::multimap<int64_t, CInv> mapAskFor;
|
std::multimap<int64_t, CInv> mapAskFor;
|
||||||
|
int64_t nNextInvSend;
|
||||||
|
|
||||||
// Ping time measurement:
|
// Ping time measurement:
|
||||||
// The pong reply we're expecting, or 0 if no pong expected.
|
// The pong reply we're expecting, or 0 if no pong expected.
|
||||||
|
@ -720,7 +723,9 @@ public:
|
||||||
|
|
||||||
class CTransaction;
|
class CTransaction;
|
||||||
void RelayTransaction(const CTransaction& tx);
|
void RelayTransaction(const CTransaction& tx);
|
||||||
void RelayTransaction(const CTransaction& tx, const CDataStream& ss);
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Return a timestamp in the future (in microseconds) for exponentially distributed events. */
|
||||||
|
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds);
|
||||||
|
|
||||||
#endif // BITCOIN_NET_H
|
#endif // BITCOIN_NET_H
|
||||||
|
|
|
@ -54,7 +54,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
|
||||||
CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
|
CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
|
||||||
dummyNode1.nVersion = 1;
|
dummyNode1.nVersion = 1;
|
||||||
Misbehaving(dummyNode1.GetId(), 100); // Should get banned
|
Misbehaving(dummyNode1.GetId(), 100); // Should get banned
|
||||||
SendMessages(params, &dummyNode1, false);
|
SendMessages(params, &dummyNode1);
|
||||||
BOOST_CHECK(CNode::IsBanned(addr1));
|
BOOST_CHECK(CNode::IsBanned(addr1));
|
||||||
BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned
|
BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned
|
||||||
|
|
||||||
|
@ -62,11 +62,11 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
|
||||||
CNode dummyNode2(INVALID_SOCKET, addr2, "", true);
|
CNode dummyNode2(INVALID_SOCKET, addr2, "", true);
|
||||||
dummyNode2.nVersion = 1;
|
dummyNode2.nVersion = 1;
|
||||||
Misbehaving(dummyNode2.GetId(), 50);
|
Misbehaving(dummyNode2.GetId(), 50);
|
||||||
SendMessages(params, &dummyNode2, false);
|
SendMessages(params, &dummyNode2);
|
||||||
BOOST_CHECK(!CNode::IsBanned(addr2)); // 2 not banned yet...
|
BOOST_CHECK(!CNode::IsBanned(addr2)); // 2 not banned yet...
|
||||||
BOOST_CHECK(CNode::IsBanned(addr1)); // ... but 1 still should be
|
BOOST_CHECK(CNode::IsBanned(addr1)); // ... but 1 still should be
|
||||||
Misbehaving(dummyNode2.GetId(), 50);
|
Misbehaving(dummyNode2.GetId(), 50);
|
||||||
SendMessages(params, &dummyNode2, false);
|
SendMessages(params, &dummyNode2);
|
||||||
BOOST_CHECK(CNode::IsBanned(addr2));
|
BOOST_CHECK(CNode::IsBanned(addr2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,13 +79,13 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
|
||||||
CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
|
CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
|
||||||
dummyNode1.nVersion = 1;
|
dummyNode1.nVersion = 1;
|
||||||
Misbehaving(dummyNode1.GetId(), 100);
|
Misbehaving(dummyNode1.GetId(), 100);
|
||||||
SendMessages(params, &dummyNode1, false);
|
SendMessages(params, &dummyNode1);
|
||||||
BOOST_CHECK(!CNode::IsBanned(addr1));
|
BOOST_CHECK(!CNode::IsBanned(addr1));
|
||||||
Misbehaving(dummyNode1.GetId(), 10);
|
Misbehaving(dummyNode1.GetId(), 10);
|
||||||
SendMessages(params, &dummyNode1, false);
|
SendMessages(params, &dummyNode1);
|
||||||
BOOST_CHECK(!CNode::IsBanned(addr1));
|
BOOST_CHECK(!CNode::IsBanned(addr1));
|
||||||
Misbehaving(dummyNode1.GetId(), 1);
|
Misbehaving(dummyNode1.GetId(), 1);
|
||||||
SendMessages(params, &dummyNode1, false);
|
SendMessages(params, &dummyNode1);
|
||||||
BOOST_CHECK(CNode::IsBanned(addr1));
|
BOOST_CHECK(CNode::IsBanned(addr1));
|
||||||
mapArgs.erase("-banscore");
|
mapArgs.erase("-banscore");
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
|
||||||
dummyNode.nVersion = 1;
|
dummyNode.nVersion = 1;
|
||||||
|
|
||||||
Misbehaving(dummyNode.GetId(), 100);
|
Misbehaving(dummyNode.GetId(), 100);
|
||||||
SendMessages(params, &dummyNode, false);
|
SendMessages(params, &dummyNode);
|
||||||
BOOST_CHECK(CNode::IsBanned(addr));
|
BOOST_CHECK(CNode::IsBanned(addr));
|
||||||
|
|
||||||
SetMockTime(nStartTime+60*60);
|
SetMockTime(nStartTime+60*60);
|
||||||
|
|
|
@ -59,6 +59,8 @@ CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const
|
||||||
CTxMemPool::CTxMemPool(const CFeeRate& _minRelayFee) :
|
CTxMemPool::CTxMemPool(const CFeeRate& _minRelayFee) :
|
||||||
nTransactionsUpdated(0)
|
nTransactionsUpdated(0)
|
||||||
{
|
{
|
||||||
|
_clear(); // unlocked clear
|
||||||
|
|
||||||
// Sanity checks off by default for performance, because otherwise
|
// Sanity checks off by default for performance, because otherwise
|
||||||
// accepting transactions becomes O(N^2) where N is the number
|
// accepting transactions becomes O(N^2) where N is the number
|
||||||
// of transactions in the pool
|
// of transactions in the pool
|
||||||
|
@ -494,9 +496,8 @@ void CTxMemPool::removeWithoutBranchId(uint32_t nMemPoolBranchId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTxMemPool::clear()
|
void CTxMemPool::_clear()
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
|
||||||
mapTx.clear();
|
mapTx.clear();
|
||||||
mapNextTx.clear();
|
mapNextTx.clear();
|
||||||
totalTxSize = 0;
|
totalTxSize = 0;
|
||||||
|
@ -504,6 +505,12 @@ void CTxMemPool::clear()
|
||||||
++nTransactionsUpdated;
|
++nTransactionsUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CTxMemPool::clear()
|
||||||
|
{
|
||||||
|
LOCK(cs);
|
||||||
|
_clear();
|
||||||
|
}
|
||||||
|
|
||||||
void CTxMemPool::check(const CCoinsViewCache *pcoins) const
|
void CTxMemPool::check(const CCoinsViewCache *pcoins) const
|
||||||
{
|
{
|
||||||
if (nCheckFrequency == 0)
|
if (nCheckFrequency == 0)
|
||||||
|
|
|
@ -210,6 +210,7 @@ public:
|
||||||
std::list<CTransaction>& conflicts, bool fCurrentEstimate = true);
|
std::list<CTransaction>& conflicts, bool fCurrentEstimate = true);
|
||||||
void removeWithoutBranchId(uint32_t nMemPoolBranchId);
|
void removeWithoutBranchId(uint32_t nMemPoolBranchId);
|
||||||
void clear();
|
void clear();
|
||||||
|
void _clear(); // unlocked
|
||||||
void queryHashes(std::vector<uint256>& vtxid);
|
void queryHashes(std::vector<uint256>& vtxid);
|
||||||
void pruneSpent(const uint256& hash, CCoins &coins);
|
void pruneSpent(const uint256& hash, CCoins &coins);
|
||||||
unsigned int GetTransactionsUpdated() const;
|
unsigned int GetTransactionsUpdated() const;
|
||||||
|
|
Loading…
Reference in New Issue