Skip to content

Commit

Permalink
Fix deadlock between blockchain and spv (#1139)
Browse files Browse the repository at this point in the history
Signed-off-by: Anthony Fieroni <[email protected]>

Co-authored-by: Prasanna Loganathar <[email protected]>
  • Loading branch information
bvbfan and prasannavl authored Mar 10, 2022
1 parent 76c94bb commit 86f554f
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 10 deletions.
12 changes: 6 additions & 6 deletions src/masternodes/anchors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,9 @@ int CAnchorIndex::GetAnchorConfirmations(const CAnchorIndex::AnchorRec * rec) co

void CAnchorIndex::CheckPendingAnchors()
{
AssertLockHeld(cs_main);
uint32_t height = spv::pspv ? spv::pspv->GetLastBlockHeight() : 0;

LOCK(cs_main);

spv::PendingSet anchorsPending(spv::PendingOrder);
ForEachPending([&anchorsPending](uint256 const &, AnchorRec & rec) {
Expand Down Expand Up @@ -559,24 +561,22 @@ void CAnchorIndex::CheckPendingAnchors()

// Recheck anchors
possibleReActivation = true;
CheckActiveAnchor();
CheckActiveAnchor(height);
}

for (const auto& hash : deletePending) {
DeletePendingByBtcTx(hash);
}
}

void CAnchorIndex::CheckActiveAnchor(bool forced)
void CAnchorIndex::CheckActiveAnchor(uint32_t height, bool forced)
{
// Only continue with context of chain
if (ShutdownRequested()) return;

{
// fix spv height to avoid datarace while choosing best anchor
uint32_t const tmp = spv::pspv ? spv::pspv->GetLastBlockHeight() : 0;
LOCK(cs_main);
spvLastHeight = tmp;
spvLastHeight = height;

panchors->ActivateBestAnchor(forced);

Expand Down
2 changes: 1 addition & 1 deletion src/masternodes/anchors.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ class CAnchorIndex
int GetAnchorConfirmations(uint256 const & txHash) const;
int GetAnchorConfirmations(AnchorRec const * rec) const;

void CheckActiveAnchor(bool forced = false);
void CheckActiveAnchor(uint32_t height, bool forced = false);
void UpdateLastHeight(uint32_t height);

// Post-fork anchor pending, requires chain context to validate. Some pending may be bogus, intentional or not.
Expand Down
2 changes: 1 addition & 1 deletion src/spv/spv_rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ UniValue spv_setlastheight(const JSONRPCRequest& request)
throw JSONRPCError(RPC_INVALID_REQUEST, "command disabled");

fake_spv->lastBlockHeight = request.params[0].get_int();
panchors->CheckActiveAnchor(true);
panchors->CheckActiveAnchor(fake_spv->lastBlockHeight, true);
return UniValue();
}

Expand Down
3 changes: 2 additions & 1 deletion src/spv/spv_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,8 @@ void CSpvWrapper::OnSyncStopped(int error)
void CSpvWrapper::OnTxStatusUpdate()
{
LogPrint(BCLog::SPV, "tx status update\n");
panchors->CheckActiveAnchor();
uint32_t height = spv::pspv->GetLastBlockHeight();
panchors->CheckActiveAnchor(height);
}

void CSpvWrapper::OnSaveBlocks(int replace, BRMerkleBlock * blocks[], size_t blocksCount)
Expand Down
1 change: 0 additions & 1 deletion src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5272,7 +5272,6 @@ bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<cons
ProcessAuthsIfTipChanged(oldTip, tip, chainparams.GetConsensus());

if (tip->nHeight >= chainparams.GetConsensus().DakotaHeight) {
LOCK(cs_main);
panchors->CheckPendingAnchors();
}
}
Expand Down

0 comments on commit 86f554f

Please sign in to comment.