Auto merge of #2101 - str4d:2074-tests, r=arcalinea
Bitcoin 0.12 test PRs 1 Cherry-picked from the following upstream PRs: - bitcoin/bitcoin#6337 - bitcoin/bitcoin#6390 - bitcoin/bitcoin#5515 - bitcoin/bitcoin#6287 (partial, remainder included in bitcoin/bitcoin#6703) - bitcoin/bitcoin#6465 Part of #2074.
This commit is contained in:
commit
dadb1ab74c
|
@ -140,8 +140,8 @@ class TestNode(NodeConnCB):
|
|||
# or false, then only the last tx is tested against outcome.)
|
||||
|
||||
class TestInstance(object):
|
||||
def __init__(self, objects=[], sync_every_block=True, sync_every_tx=False):
|
||||
self.blocks_and_transactions = objects
|
||||
def __init__(self, objects=None, sync_every_block=True, sync_every_tx=False):
|
||||
self.blocks_and_transactions = objects if objects else []
|
||||
self.sync_every_block = sync_every_block
|
||||
self.sync_every_tx = sync_every_tx
|
||||
|
||||
|
|
|
@ -985,6 +985,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
|
||||
fAlerts = GetBoolArg("-alerts", DEFAULT_ALERTS);
|
||||
|
||||
// Option to startup with mocktime set (used for regression testing):
|
||||
SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op
|
||||
|
||||
#ifdef ENABLE_MINING
|
||||
if (mapArgs.count("-mineraddress")) {
|
||||
CBitcoinAddress addr;
|
||||
|
|
14
src/main.cpp
14
src/main.cpp
|
@ -79,9 +79,9 @@ struct COrphanTx {
|
|||
CTransaction tx;
|
||||
NodeId fromPeer;
|
||||
};
|
||||
map<uint256, COrphanTx> mapOrphanTransactions;
|
||||
map<uint256, set<uint256> > mapOrphanTransactionsByPrev;
|
||||
void EraseOrphansFor(NodeId peer);
|
||||
map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main);;
|
||||
map<uint256, set<uint256> > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);;
|
||||
void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
||||
/**
|
||||
* Returns true if there are nRequired or more blocks of minVersion or above
|
||||
|
@ -554,7 +554,7 @@ CBlockTreeDB *pblocktree = NULL;
|
|||
// mapOrphanTransactions
|
||||
//
|
||||
|
||||
bool AddOrphanTx(const CTransaction& tx, NodeId peer)
|
||||
bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
{
|
||||
uint256 hash = tx.GetHash();
|
||||
if (mapOrphanTransactions.count(hash))
|
||||
|
@ -584,7 +584,7 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer)
|
|||
return true;
|
||||
}
|
||||
|
||||
void static EraseOrphanTx(uint256 hash)
|
||||
void static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
{
|
||||
map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
|
||||
if (it == mapOrphanTransactions.end())
|
||||
|
@ -618,7 +618,7 @@ void EraseOrphansFor(NodeId peer)
|
|||
}
|
||||
|
||||
|
||||
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
|
||||
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
{
|
||||
unsigned int nEvicted = 0;
|
||||
while (mapOrphanTransactions.size() > nMaxOrphans)
|
||||
|
@ -4131,7 +4131,7 @@ std::string GetWarnings(const std::string& strFor)
|
|||
//
|
||||
|
||||
|
||||
bool static AlreadyHave(const CInv& inv)
|
||||
bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
{
|
||||
switch (inv.type)
|
||||
{
|
||||
|
|
|
@ -452,10 +452,19 @@ UniValue setmocktime(const UniValue& params, bool fHelp)
|
|||
if (!Params().MineBlocksOnDemand())
|
||||
throw runtime_error("setmocktime for regression testing (-regtest mode) only");
|
||||
|
||||
LOCK(cs_main);
|
||||
// cs_vNodes is locked and node send/receive times are updated
|
||||
// atomically with the time change to prevent peers from being
|
||||
// disconnected because we think we haven't communicated with them
|
||||
// in a long time.
|
||||
LOCK2(cs_main, cs_vNodes);
|
||||
|
||||
RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM));
|
||||
SetMockTime(params[0].get_int64());
|
||||
|
||||
uint64_t t = GetTime();
|
||||
BOOST_FOREACH(CNode* pnode, vNodes) {
|
||||
pnode->nLastSend = pnode->nLastRecv = t;
|
||||
}
|
||||
|
||||
return NullUniValue;
|
||||
}
|
||||
|
|
49
src/sync.cpp
49
src/sync.cpp
|
@ -33,20 +33,22 @@ void PrintLockContention(const char* pszName, const char* pszFile, int nLine)
|
|||
//
|
||||
|
||||
struct CLockLocation {
|
||||
CLockLocation(const char* pszName, const char* pszFile, int nLine)
|
||||
CLockLocation(const char* pszName, const char* pszFile, int nLine, bool fTryIn)
|
||||
{
|
||||
mutexName = pszName;
|
||||
sourceFile = pszFile;
|
||||
sourceLine = nLine;
|
||||
fTry = fTryIn;
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
return mutexName + " " + sourceFile + ":" + itostr(sourceLine);
|
||||
return mutexName + " " + sourceFile + ":" + itostr(sourceLine) + (fTry ? " (TRY)" : "");
|
||||
}
|
||||
|
||||
std::string MutexName() const { return mutexName; }
|
||||
|
||||
bool fTry;
|
||||
private:
|
||||
std::string mutexName;
|
||||
std::string sourceFile;
|
||||
|
@ -62,23 +64,52 @@ static boost::thread_specific_ptr<LockStack> lockstack;
|
|||
|
||||
static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2)
|
||||
{
|
||||
// We attempt to not assert on probably-not deadlocks by assuming that
|
||||
// a try lock will immediately have otherwise bailed if it had
|
||||
// failed to get the lock
|
||||
// We do this by, for the locks which triggered the potential deadlock,
|
||||
// in either lockorder, checking that the second of the two which is locked
|
||||
// is only a TRY_LOCK, ignoring locks if they are reentrant.
|
||||
bool firstLocked = false;
|
||||
bool secondLocked = false;
|
||||
bool onlyMaybeDeadlock = false;
|
||||
|
||||
LogPrintf("POTENTIAL DEADLOCK DETECTED\n");
|
||||
LogPrintf("Previous lock order was:\n");
|
||||
BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s2) {
|
||||
if (i.first == mismatch.first)
|
||||
if (i.first == mismatch.first) {
|
||||
LogPrintf(" (1)");
|
||||
if (i.first == mismatch.second)
|
||||
if (!firstLocked && secondLocked && i.second.fTry)
|
||||
onlyMaybeDeadlock = true;
|
||||
firstLocked = true;
|
||||
}
|
||||
if (i.first == mismatch.second) {
|
||||
LogPrintf(" (2)");
|
||||
if (!secondLocked && firstLocked && i.second.fTry)
|
||||
onlyMaybeDeadlock = true;
|
||||
secondLocked = true;
|
||||
}
|
||||
LogPrintf(" %s\n", i.second.ToString());
|
||||
}
|
||||
firstLocked = false;
|
||||
secondLocked = false;
|
||||
LogPrintf("Current lock order is:\n");
|
||||
BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s1) {
|
||||
if (i.first == mismatch.first)
|
||||
if (i.first == mismatch.first) {
|
||||
LogPrintf(" (1)");
|
||||
if (i.first == mismatch.second)
|
||||
if (!firstLocked && secondLocked && i.second.fTry)
|
||||
onlyMaybeDeadlock = true;
|
||||
firstLocked = true;
|
||||
}
|
||||
if (i.first == mismatch.second) {
|
||||
LogPrintf(" (2)");
|
||||
if (!secondLocked && firstLocked && i.second.fTry)
|
||||
onlyMaybeDeadlock = true;
|
||||
secondLocked = true;
|
||||
}
|
||||
LogPrintf(" %s\n", i.second.ToString());
|
||||
}
|
||||
assert(onlyMaybeDeadlock);
|
||||
}
|
||||
|
||||
static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
|
||||
|
@ -101,10 +132,8 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
|
|||
lockorders[p1] = (*lockstack);
|
||||
|
||||
std::pair<void*, void*> p2 = std::make_pair(c, i.first);
|
||||
if (lockorders.count(p2)) {
|
||||
if (lockorders.count(p2))
|
||||
potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dd_mutex.unlock();
|
||||
|
@ -119,7 +148,7 @@ static void pop_lock()
|
|||
|
||||
void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry)
|
||||
{
|
||||
push_lock(cs, CLockLocation(pszName, pszFile, nLine), fTry);
|
||||
push_lock(cs, CLockLocation(pszName, pszFile, nLine, fTry), fTry);
|
||||
}
|
||||
|
||||
void LeaveCritical()
|
||||
|
|
|
@ -101,7 +101,7 @@ void PrintLockContention(const char* pszName, const char* pszFile, int nLine);
|
|||
|
||||
/** Wrapper around boost::unique_lock<Mutex> */
|
||||
template <typename Mutex>
|
||||
class CMutexLock
|
||||
class SCOPED_LOCKABLE CMutexLock
|
||||
{
|
||||
private:
|
||||
boost::unique_lock<Mutex> lock;
|
||||
|
@ -129,7 +129,7 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
CMutexLock(Mutex& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) : lock(mutexIn, boost::defer_lock)
|
||||
CMutexLock(Mutex& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : lock(mutexIn, boost::defer_lock)
|
||||
{
|
||||
if (fTry)
|
||||
TryEnter(pszName, pszFile, nLine);
|
||||
|
@ -137,7 +137,7 @@ public:
|
|||
Enter(pszName, pszFile, nLine);
|
||||
}
|
||||
|
||||
CMutexLock(Mutex* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false)
|
||||
CMutexLock(Mutex* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn)
|
||||
{
|
||||
if (!pmutexIn) return;
|
||||
|
||||
|
@ -148,7 +148,7 @@ public:
|
|||
Enter(pszName, pszFile, nLine);
|
||||
}
|
||||
|
||||
~CMutexLock()
|
||||
~CMutexLock() UNLOCK_FUNCTION()
|
||||
{
|
||||
if (lock.owns_lock())
|
||||
LeaveCritical();
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
["-create",
|
||||
"in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0",
|
||||
"set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]",
|
||||
"set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\"}]",
|
||||
"set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]",
|
||||
"sign=ALL",
|
||||
"outaddr=0.001:t1Ruz6gK4QPZoPPGpHaieupnnh62mktjQE7"],
|
||||
"output_cmp": "txcreatesign.hex"
|
||||
|
|
|
@ -1 +1 @@
|
|||
01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d0000000000ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000
|
||||
01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d000000008b48304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e201410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000
|
||||
|
|
Loading…
Reference in New Issue