mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 20:42:59 +01:00
evo/llmq/spork: Fix various (potential) locking issues (#3829)
* Fix potential deadlock in `CSporkManager::UpdateSpork()` * Protect `inputRequestIds` with cs lock * Protect `curDBTransaction` in `CEvoDB::CommitRootTransaction()` * Check for `AssertLockNotHeld` in `EnforceBestChainLock()` instead of just having a comment in code * Protect spork maps on (de)serialization
This commit is contained in:
parent
ff1ecb67f1
commit
757c99eb20
@ -53,6 +53,7 @@ void CEvoDB::RollbackCurTransaction()
|
|||||||
|
|
||||||
bool CEvoDB::CommitRootTransaction()
|
bool CEvoDB::CommitRootTransaction()
|
||||||
{
|
{
|
||||||
|
LOCK(cs);
|
||||||
assert(curDBTransaction.IsClean());
|
assert(curDBTransaction.IsClean());
|
||||||
rootDBTransaction.Commit();
|
rootDBTransaction.Commit();
|
||||||
bool ret = db.WriteBatch(rootBatch);
|
bool ret = db.WriteBatch(rootBatch);
|
||||||
|
@ -488,6 +488,9 @@ bool CChainLocksHandler::IsTxSafeForMining(const uint256& txid)
|
|||||||
// This should also not be called from validation signals, as this might result in recursive calls
|
// This should also not be called from validation signals, as this might result in recursive calls
|
||||||
void CChainLocksHandler::EnforceBestChainLock()
|
void CChainLocksHandler::EnforceBestChainLock()
|
||||||
{
|
{
|
||||||
|
AssertLockNotHeld(cs);
|
||||||
|
AssertLockNotHeld(cs_main);
|
||||||
|
|
||||||
CChainLockSig clsig;
|
CChainLockSig clsig;
|
||||||
const CBlockIndex* pindex;
|
const CBlockIndex* pindex;
|
||||||
const CBlockIndex* currentBestChainLockBlockIndex;
|
const CBlockIndex* currentBestChainLockBlockIndex;
|
||||||
|
@ -458,7 +458,10 @@ bool CInstantSendManager::ProcessTx(const CTransaction& tx, bool allowReSigning,
|
|||||||
for (size_t i = 0; i < tx.vin.size(); i++) {
|
for (size_t i = 0; i < tx.vin.size(); i++) {
|
||||||
auto& in = tx.vin[i];
|
auto& in = tx.vin[i];
|
||||||
auto& id = ids[i];
|
auto& id = ids[i];
|
||||||
|
{
|
||||||
|
LOCK(cs);
|
||||||
inputRequestIds.emplace(id);
|
inputRequestIds.emplace(id);
|
||||||
|
}
|
||||||
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s: trying to vote on input %s with id %s. allowReSigning=%d\n", __func__,
|
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s: trying to vote on input %s with id %s. allowReSigning=%d\n", __func__,
|
||||||
tx.GetHash().ToString(), in.prevout.ToStringShort(), id.ToString(), allowReSigning);
|
tx.GetHash().ToString(), in.prevout.ToStringShort(), id.ToString(), allowReSigning);
|
||||||
if (quorumSigningManager->AsyncSignIfMember(llmqType, id, tx.GetHash(), allowReSigning)) {
|
if (quorumSigningManager->AsyncSignIfMember(llmqType, id, tx.GetHash(), allowReSigning)) {
|
||||||
@ -1119,6 +1122,7 @@ void CInstantSendManager::RemoveConflictedTx(const CTransaction& tx)
|
|||||||
|
|
||||||
void CInstantSendManager::TruncateRecoveredSigsForInputs(const llmq::CInstantSendLock& islock)
|
void CInstantSendManager::TruncateRecoveredSigsForInputs(const llmq::CInstantSendLock& islock)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs);
|
||||||
auto& consensusParams = Params().GetConsensus();
|
auto& consensusParams = Params().GetConsensus();
|
||||||
|
|
||||||
for (auto& in : islock.inputs) {
|
for (auto& in : islock.inputs) {
|
||||||
|
@ -186,8 +186,6 @@ bool CSporkManager::UpdateSpork(SporkId nSporkID, int64_t nValue, CConnman& conn
|
|||||||
{
|
{
|
||||||
CSporkMessage spork = CSporkMessage(nSporkID, nValue, GetAdjustedTime());
|
CSporkMessage spork = CSporkMessage(nSporkID, nValue, GetAdjustedTime());
|
||||||
|
|
||||||
LOCK(cs);
|
|
||||||
|
|
||||||
if (!spork.Sign(sporkPrivKey)) {
|
if (!spork.Sign(sporkPrivKey)) {
|
||||||
LogPrintf("CSporkManager::%s -- ERROR: signing failed for spork %d\n", __func__, nSporkID);
|
LogPrintf("CSporkManager::%s -- ERROR: signing failed for spork %d\n", __func__, nSporkID);
|
||||||
return false;
|
return false;
|
||||||
@ -201,8 +199,11 @@ bool CSporkManager::UpdateSpork(SporkId nSporkID, int64_t nValue, CConnman& conn
|
|||||||
|
|
||||||
LogPrintf("CSporkManager::%s -- signed %d %s\n", __func__, nSporkID, spork.GetHash().ToString());
|
LogPrintf("CSporkManager::%s -- signed %d %s\n", __func__, nSporkID, spork.GetHash().ToString());
|
||||||
|
|
||||||
|
{
|
||||||
|
LOCK(cs);
|
||||||
mapSporksByHash[spork.GetHash()] = spork;
|
mapSporksByHash[spork.GetHash()] = spork;
|
||||||
mapSporksActive[nSporkID][keyIDSigner] = spork;
|
mapSporksActive[nSporkID][keyIDSigner] = spork;
|
||||||
|
}
|
||||||
|
|
||||||
spork.Relay(connman);
|
spork.Relay(connman);
|
||||||
return true;
|
return true;
|
||||||
|
@ -191,6 +191,7 @@ public:
|
|||||||
// we don't serialize pubkey ids because pubkeys should be
|
// we don't serialize pubkey ids because pubkeys should be
|
||||||
// hardcoded or be setted with cmdline or options, should
|
// hardcoded or be setted with cmdline or options, should
|
||||||
// not reuse pubkeys from previous dashd run
|
// not reuse pubkeys from previous dashd run
|
||||||
|
LOCK(cs);
|
||||||
READWRITE(mapSporksByHash);
|
READWRITE(mapSporksByHash);
|
||||||
READWRITE(mapSporksActive);
|
READWRITE(mapSporksActive);
|
||||||
// we don't serialize private key to prevent its leakage
|
// we don't serialize private key to prevent its leakage
|
||||||
|
Loading…
Reference in New Issue
Block a user