Locks fixes:

- trylock for updateDarksendProgress, checkBalanceChanged, "block"
- trylock+wait for UnlockCoins, SendDarksendDenominate, ProcessNewBlock, ActivateBestChain
- move trylock in DoAutomaticDenominating lower
This commit is contained in:
UdjinM6 2015-08-07 07:08:37 +03:00
parent b8e7b84916
commit ec3848c5dd
5 changed files with 61 additions and 35 deletions

View File

@ -432,9 +432,13 @@ bool CDarksendPool::SetCollateralAddress(std::string strAddress){
// Unlock coins after Darksend fails or succeeds // Unlock coins after Darksend fails or succeeds
// //
void CDarksendPool::UnlockCoins(){ void CDarksendPool::UnlockCoins(){
LOCK(pwalletMain->cs_wallet); while(true) {
TRY_LOCK(pwalletMain->cs_wallet, lockWallet);
if(!lockWallet) {MilliSleep(10); continue;}
BOOST_FOREACH(CTxIn v, lockedCoins) BOOST_FOREACH(CTxIn v, lockedCoins)
pwalletMain->UnlockCoin(v.prevout); pwalletMain->UnlockCoin(v.prevout);
break;
}
lockedCoins.clear(); lockedCoins.clear();
} }
@ -1155,14 +1159,16 @@ void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<
LogPrintf("Submitting tx %s\n", tx.ToString()); LogPrintf("Submitting tx %s\n", tx.ToString());
{ while(true){
LOCK(cs_main); TRY_LOCK(cs_main, lockMain);
if(!lockMain) { MilliSleep(10); continue;}
if(!AcceptableInputs(mempool, state, CTransaction(tx), false, NULL, false, true)){ if(!AcceptableInputs(mempool, state, CTransaction(tx), false, NULL, false, true)){
LogPrintf("dsi -- transaction not valid! %s \n", tx.ToString()); LogPrintf("dsi -- transaction not valid! %s \n", tx.ToString());
UnlockCoins(); UnlockCoins();
SetNull(); SetNull();
return; return;
} }
break;
} }
} }
@ -1352,25 +1358,24 @@ void CDarksendPool::ClearLastMessage()
// //
bool CDarksendPool::DoAutomaticDenominating(bool fDryRun, bool ready) bool CDarksendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
{ {
if(!fEnableDarksend) return false;
if(fMasterNode) return false;
if(state == POOL_STATUS_ERROR || state == POOL_STATUS_SUCCESS) return false;
if(GetEntriesCount() > 0) {
strAutoDenomResult = _("Mixing in progress...");
return false;
}
TRY_LOCK(cs_darksend, lockDS); TRY_LOCK(cs_darksend, lockDS);
if(!lockDS) { if(!lockDS) {
strAutoDenomResult = _("Lock is already in place."); strAutoDenomResult = _("Lock is already in place.");
return false; return false;
} }
LOCK(cs_darksend);
if(!masternodeSync.IsBlockchainSynced()) { if(!masternodeSync.IsBlockchainSynced()) {
strAutoDenomResult = _("Can't mix while sync in progress."); strAutoDenomResult = _("Can't mix while sync in progress.");
return false; return false;
} }
if(!fEnableDarksend) return false;
if(fMasterNode) return false;
if(state == POOL_STATUS_ERROR || state == POOL_STATUS_SUCCESS) return false;
if(GetEntriesCount() > 0) {
strAutoDenomResult = _("Mixing in progress...");
return false;
}
if (!fDryRun && pwalletMain->IsLocked()){ if (!fDryRun && pwalletMain->IsLocked()){
strAutoDenomResult = _("Wallet is locked."); strAutoDenomResult = _("Wallet is locked.");

View File

@ -2616,8 +2616,10 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
bool fInitialDownload; bool fInitialDownload;
{ while(true) {
LOCK(cs_main); TRY_LOCK(cs_main, lockMain);
if(!lockMain) { MilliSleep(10); continue; }
pindexMostWork = FindMostWorkChain(); pindexMostWork = FindMostWorkChain();
// Whether we have anything to do at all. // Whether we have anything to do at all.
@ -2629,6 +2631,7 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
pindexNewTip = chainActive.Tip(); pindexNewTip = chainActive.Tip();
fInitialDownload = IsInitialBlockDownload(); fInitialDownload = IsInitialBlockDownload();
break;
} }
// When we reach this point, we switched to a new tip (stored in pindexNewTip). // When we reach this point, we switched to a new tip (stored in pindexNewTip).
@ -3261,8 +3264,10 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis
// Preliminary checks // Preliminary checks
bool checked = CheckBlock(*pblock, state); bool checked = CheckBlock(*pblock, state);
{ while(true) {
LOCK(cs_main); TRY_LOCK(cs_main, lockMain);
if(!lockMain) { MilliSleep(10); continue; }
MarkBlockAsReceived(pblock->GetHash()); MarkBlockAsReceived(pblock->GetHash());
if (!checked) { if (!checked) {
return error("%s : CheckBlock FAILED", __func__); return error("%s : CheckBlock FAILED", __func__);
@ -3277,6 +3282,7 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis
CheckBlockIndex(); CheckBlockIndex();
if (!ret) if (!ret)
return error("%s : AcceptBlock FAILED", __func__); return error("%s : AcceptBlock FAILED", __func__);
break;
} }
if (!ActivateBestChain(state, pblock)) if (!ActivateBestChain(state, pblock))
@ -4876,12 +4882,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
CBlock block; CBlock block;
vRecv >> block; vRecv >> block;
TRY_LOCK(cs_main, lockMainBlock);
if(!lockMainBlock && masternodeSync.IsBlockchainSynced()) {
LogPrintf("block -- failed to lock cs_main - %s\n", block.GetHash().ToString());
return false;
}
CInv inv(MSG_BLOCK, block.GetHash()); CInv inv(MSG_BLOCK, block.GetHash());
LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id); LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id);
@ -4894,7 +4894,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
if (nDoS > 0) { if (nDoS > 0) {
Misbehaving(pfrom->GetId(), nDoS); TRY_LOCK(cs_main, lockMain);
if(lockMain) Misbehaving(pfrom->GetId(), nDoS);
} }
} }

View File

@ -318,11 +318,10 @@ void OverviewPage::updateDarksendProgress()
if(!pwalletMain) return; if(!pwalletMain) return;
int64_t nBalance = pwalletMain->GetBalance();
QString strAmountAndRounds; QString strAmountAndRounds;
QString strAnonymizeDarkcoinAmount = BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, nAnonymizeDarkcoinAmount * COIN, false, BitcoinUnits::separatorAlways); QString strAnonymizeDarkcoinAmount = BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, nAnonymizeDarkcoinAmount * COIN, false, BitcoinUnits::separatorAlways);
if(nBalance == 0) if(currentBalance == 0)
{ {
ui->darksendProgress->setValue(0); ui->darksendProgress->setValue(0);
ui->darksendProgress->setToolTip(tr("No inputs detected")); ui->darksendProgress->setToolTip(tr("No inputs detected"));
@ -336,9 +335,24 @@ void OverviewPage::updateDarksendProgress()
return; return;
} }
int64_t nDenominatedUnconfirmedBalance = pwalletMain->GetDenominatedBalance(true); CAmount nDenominatedConfirmedBalance;
int64_t nMaxToAnonymize = pwalletMain->GetAnonymizableBalance() + CAmount nDenominatedUnconfirmedBalance;
pwalletMain->GetAnonymizedBalance() + nDenominatedUnconfirmedBalance; CAmount nAnonymizableBalance;
CAmount nNormalizedAnonymizedBalance;
double nAverageAnonymizedRounds;
{
TRY_LOCK(cs_main, lockMain);
if(!lockMain) return;
nDenominatedConfirmedBalance = pwalletMain->GetDenominatedBalance();
nDenominatedUnconfirmedBalance = pwalletMain->GetDenominatedBalance(true);
nAnonymizableBalance = pwalletMain->GetAnonymizableBalance();
nNormalizedAnonymizedBalance = pwalletMain->GetNormalizedAnonymizedBalance();
nAverageAnonymizedRounds = pwalletMain->GetAverageAnonymizedRounds();
}
CAmount nMaxToAnonymize = nAnonymizableBalance + currentAnonymizedBalance + nDenominatedUnconfirmedBalance;
// If it's more than the anon threshold, limit to that. // If it's more than the anon threshold, limit to that.
if(nMaxToAnonymize > nAnonymizeDarkcoinAmount*COIN) nMaxToAnonymize = nAnonymizeDarkcoinAmount*COIN; if(nMaxToAnonymize > nAnonymizeDarkcoinAmount*COIN) nMaxToAnonymize = nAnonymizeDarkcoinAmount*COIN;
@ -371,16 +385,16 @@ void OverviewPage::updateDarksendProgress()
// completeness of full amount anonimization // completeness of full amount anonimization
float anonFullPart = 0; float anonFullPart = 0;
int64_t denominatedBalance = pwalletMain->GetDenominatedBalance() + nDenominatedUnconfirmedBalance; CAmount denominatedBalance = nDenominatedConfirmedBalance + nDenominatedUnconfirmedBalance;
denomPart = (float)denominatedBalance / nMaxToAnonymize; denomPart = (float)denominatedBalance / nMaxToAnonymize;
denomPart = denomPart > 1 ? 1 : denomPart; denomPart = denomPart > 1 ? 1 : denomPart;
denomPart *= 100; denomPart *= 100;
anonNormPart = (float)pwalletMain->GetNormalizedAnonymizedBalance() / nMaxToAnonymize; anonNormPart = (float)nNormalizedAnonymizedBalance / nMaxToAnonymize;
anonNormPart = anonNormPart > 1 ? 1 : anonNormPart; anonNormPart = anonNormPart > 1 ? 1 : anonNormPart;
anonNormPart *= 100; anonNormPart *= 100;
anonFullPart = (float)pwalletMain->GetAnonymizedBalance() / nMaxToAnonymize; anonFullPart = (float)currentAnonymizedBalance / nMaxToAnonymize;
anonFullPart = anonFullPart > 1 ? 1 : anonFullPart; anonFullPart = anonFullPart > 1 ? 1 : anonFullPart;
anonFullPart *= 100; anonFullPart *= 100;
@ -404,7 +418,7 @@ void OverviewPage::updateDarksendProgress()
tr("Anonymized") + ": %4%<br/>" + tr("Anonymized") + ": %4%<br/>" +
tr("Denominated inputs have %5 of %n rounds on average", "", nDarksendRounds)) tr("Denominated inputs have %5 of %n rounds on average", "", nDarksendRounds))
.arg(progress).arg(denomPart).arg(anonNormPart).arg(anonFullPart) .arg(progress).arg(denomPart).arg(anonNormPart).arg(anonFullPart)
.arg(pwalletMain->GetAverageAnonymizedRounds()); .arg(nAverageAnonymizedRounds);
ui->darksendProgress->setToolTip(strToolPip); ui->darksendProgress->setToolTip(strToolPip);
} }
@ -486,7 +500,7 @@ void OverviewPage::toggleDarksend(){
settings.setValue("hasMixed", "hasMixed"); settings.setValue("hasMixed", "hasMixed");
} }
if(!fEnableDarksend){ if(!fEnableDarksend){
int64_t balance = pwalletMain->GetBalance(); int64_t balance = currentBalance;
float minAmount = 1.49 * COIN; float minAmount = 1.49 * COIN;
if(balance < minAmount){ if(balance < minAmount){
QString strMinAmount(BitcoinUnits::formatWithUnit(nDisplayUnit, minAmount)); QString strMinAmount(BitcoinUnits::formatWithUnit(nDisplayUnit, minAmount));

View File

@ -580,6 +580,9 @@ void SendCoinsDialog::setBalance(const CAmount& balance, const CAmount& unconfir
void SendCoinsDialog::updateDisplayUnit() void SendCoinsDialog::updateDisplayUnit()
{ {
TRY_LOCK(cs_main, lockMain);
if(!lockMain) return;
setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(), model->getAnonymizedBalance(), setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(), model->getAnonymizedBalance(),
model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance()); model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance());
CoinControlDialog::coinControl->useDarkSend = ui->checkUseDarksend->isChecked(); CoinControlDialog::coinControl->useDarkSend = ui->checkUseDarksend->isChecked();

View File

@ -146,6 +146,9 @@ void WalletModel::pollBalanceChanged()
void WalletModel::checkBalanceChanged() void WalletModel::checkBalanceChanged()
{ {
TRY_LOCK(cs_main, lockMain);
if(!lockMain) return;
CAmount newBalance = getBalance(); CAmount newBalance = getBalance();
CAmount newUnconfirmedBalance = getUnconfirmedBalance(); CAmount newUnconfirmedBalance = getUnconfirmedBalance();
CAmount newImmatureBalance = getImmatureBalance(); CAmount newImmatureBalance = getImmatureBalance();