Locks fixes:
- trylock for updateDarksendProgress, checkBalanceChanged, "block" - trylock+wait for UnlockCoins, SendDarksendDenominate, ProcessNewBlock, ActivateBestChain - move trylock in DoAutomaticDenominating lower
This commit is contained in:
parent
b8e7b84916
commit
ec3848c5dd
@ -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.");
|
||||||
|
23
src/main.cpp
23
src/main.cpp
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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));
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user