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
//
void CDarksendPool::UnlockCoins(){
LOCK(pwalletMain->cs_wallet);
BOOST_FOREACH(CTxIn v, lockedCoins)
pwalletMain->UnlockCoin(v.prevout);
while(true) {
TRY_LOCK(pwalletMain->cs_wallet, lockWallet);
if(!lockWallet) {MilliSleep(10); continue;}
BOOST_FOREACH(CTxIn v, lockedCoins)
pwalletMain->UnlockCoin(v.prevout);
break;
}
lockedCoins.clear();
}
@ -1155,14 +1159,16 @@ void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<
LogPrintf("Submitting tx %s\n", tx.ToString());
{
LOCK(cs_main);
while(true){
TRY_LOCK(cs_main, lockMain);
if(!lockMain) { MilliSleep(10); continue;}
if(!AcceptableInputs(mempool, state, CTransaction(tx), false, NULL, false, true)){
LogPrintf("dsi -- transaction not valid! %s \n", tx.ToString());
UnlockCoins();
SetNull();
return;
}
break;
}
}
@ -1352,25 +1358,24 @@ void CDarksendPool::ClearLastMessage()
//
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);
if(!lockDS) {
strAutoDenomResult = _("Lock is already in place.");
return false;
}
LOCK(cs_darksend);
if(!masternodeSync.IsBlockchainSynced()) {
strAutoDenomResult = _("Can't mix while sync in progress.");
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()){
strAutoDenomResult = _("Wallet is locked.");

View File

@ -2616,8 +2616,10 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
boost::this_thread::interruption_point();
bool fInitialDownload;
{
LOCK(cs_main);
while(true) {
TRY_LOCK(cs_main, lockMain);
if(!lockMain) { MilliSleep(10); continue; }
pindexMostWork = FindMostWorkChain();
// Whether we have anything to do at all.
@ -2629,6 +2631,7 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
pindexNewTip = chainActive.Tip();
fInitialDownload = IsInitialBlockDownload();
break;
}
// 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
bool checked = CheckBlock(*pblock, state);
{
LOCK(cs_main);
while(true) {
TRY_LOCK(cs_main, lockMain);
if(!lockMain) { MilliSleep(10); continue; }
MarkBlockAsReceived(pblock->GetHash());
if (!checked) {
return error("%s : CheckBlock FAILED", __func__);
@ -3277,6 +3282,7 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis
CheckBlockIndex();
if (!ret)
return error("%s : AcceptBlock FAILED", __func__);
break;
}
if (!ActivateBestChain(state, pblock))
@ -4876,12 +4882,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
CBlock 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());
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(),
state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
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;
int64_t nBalance = pwalletMain->GetBalance();
QString strAmountAndRounds;
QString strAnonymizeDarkcoinAmount = BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, nAnonymizeDarkcoinAmount * COIN, false, BitcoinUnits::separatorAlways);
if(nBalance == 0)
if(currentBalance == 0)
{
ui->darksendProgress->setValue(0);
ui->darksendProgress->setToolTip(tr("No inputs detected"));
@ -336,9 +335,24 @@ void OverviewPage::updateDarksendProgress()
return;
}
int64_t nDenominatedUnconfirmedBalance = pwalletMain->GetDenominatedBalance(true);
int64_t nMaxToAnonymize = pwalletMain->GetAnonymizableBalance() +
pwalletMain->GetAnonymizedBalance() + nDenominatedUnconfirmedBalance;
CAmount nDenominatedConfirmedBalance;
CAmount 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(nMaxToAnonymize > nAnonymizeDarkcoinAmount*COIN) nMaxToAnonymize = nAnonymizeDarkcoinAmount*COIN;
@ -371,16 +385,16 @@ void OverviewPage::updateDarksendProgress()
// completeness of full amount anonimization
float anonFullPart = 0;
int64_t denominatedBalance = pwalletMain->GetDenominatedBalance() + nDenominatedUnconfirmedBalance;
CAmount denominatedBalance = nDenominatedConfirmedBalance + nDenominatedUnconfirmedBalance;
denomPart = (float)denominatedBalance / nMaxToAnonymize;
denomPart = denomPart > 1 ? 1 : denomPart;
denomPart *= 100;
anonNormPart = (float)pwalletMain->GetNormalizedAnonymizedBalance() / nMaxToAnonymize;
anonNormPart = (float)nNormalizedAnonymizedBalance / nMaxToAnonymize;
anonNormPart = anonNormPart > 1 ? 1 : anonNormPart;
anonNormPart *= 100;
anonFullPart = (float)pwalletMain->GetAnonymizedBalance() / nMaxToAnonymize;
anonFullPart = (float)currentAnonymizedBalance / nMaxToAnonymize;
anonFullPart = anonFullPart > 1 ? 1 : anonFullPart;
anonFullPart *= 100;
@ -404,7 +418,7 @@ void OverviewPage::updateDarksendProgress()
tr("Anonymized") + ": %4%<br/>" +
tr("Denominated inputs have %5 of %n rounds on average", "", nDarksendRounds))
.arg(progress).arg(denomPart).arg(anonNormPart).arg(anonFullPart)
.arg(pwalletMain->GetAverageAnonymizedRounds());
.arg(nAverageAnonymizedRounds);
ui->darksendProgress->setToolTip(strToolPip);
}
@ -486,7 +500,7 @@ void OverviewPage::toggleDarksend(){
settings.setValue("hasMixed", "hasMixed");
}
if(!fEnableDarksend){
int64_t balance = pwalletMain->GetBalance();
int64_t balance = currentBalance;
float minAmount = 1.49 * COIN;
if(balance < 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()
{
TRY_LOCK(cs_main, lockMain);
if(!lockMain) return;
setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(), model->getAnonymizedBalance(),
model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance());
CoinControlDialog::coinControl->useDarkSend = ui->checkUseDarksend->isChecked();

View File

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