message: Add Try/Catch block to HandleBlockMessageThread()
  Also if we catch an exception we need to make sure to remove the thread
  from the trakcking map, reduce the reference count for this node and also
  release the semaphore grant.
diff: @@ -558,6 +558,10 @@ void CParallelValidation::HandleBlockMessage(CNode *pfrom, const string &strComm
  }
  void HandleBlockMessageThread(CNode *pfrom, const string strCommand, CBlockRef pblock, const CInv inv)
  +{
  + boost::thread::id this_id(boost::this_thread::get_id());
  +
  + try
  {
  uint64_t nSizeBlock = pblock->GetBlockSize();
  int64_t startTime = GetTimeMicros();
  @@ -568,7 +572,6 @@ void HandleBlockMessageThread(CNode *pfrom, const string strCommand, CBlockRef p
  // full block from the same node while the block is processing.
  thinrelay.BlockWasReceived(pfrom, inv.hash);
  - boost::thread::id this_id(boost::this_thread::get_id());
  PV->InitThread(this_id, pfrom, pblock, inv, nSizeBlock); // initialize the mapBlockValidationThread entries
  // Process all blocks from whitelisted peers, even if not requested,
  @@ -583,7 +586,8 @@ void HandleBlockMessageThread(CNode *pfrom, const string strCommand, CBlockRef p
  }
  else
  {
  - LOCK(cs_main); // locking cs_main here prevents any other thread from beginning starting a block validation.
  + // locking cs_main here prevents any other thread from beginning starting a block validation.
  + LOCK(cs_main);
  ProcessNewBlock(state, chainparams, pfrom, pblock.get(), forceProcessing, nullptr, false);
  }
  @@ -654,10 +658,24 @@ void HandleBlockMessageThread(CNode *pfrom, const string strCommand, CBlockRef p
  compactdata.ResetCompactBlockBytes();
  }
  -
  // Erase any txns from the orphan cache that are no longer needed
  PV->ClearOrphanCache(pblock);
  + // If chain is nearly caught up then flush the state after a block is finished processing and the
  + // performance timings have been updated. This way we don't include the flush time in our time to
  + // process the block advance the tip.
  + if (IsChainNearlySyncd())
  + FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
  + }
  + catch (const std::exception &e)
  + {
  + LOGA("Exception thrown in PV thread: %s\n", e.what());
  + }
  +
  + // Use a separate try catch block here. In the event that the upper block throws an exception we'll still be
  + // able to clean up the semaphore, tracking map and node reference.
  + try
  + {
  // Clear thread data - this must be done before the thread completes or else some other new
  // thread may grab the same thread id and we would end up deleting the entry for the new thread instead.
  PV->Erase(this_id);
  @@ -669,12 +687,11 @@ void HandleBlockMessageThread(CNode *pfrom, const string strCommand, CBlockRef p
  // Remove the CNode reference we aquired just before we launched this thread.
  pfrom->Release();
  -
  - // If chain is nearly caught up then flush the state after a block is finished processing and the
  - // performance timings have been updated. This way we don't include the flush time in our time to
  - // process the block advance the tip.
  - if (IsChainNearlySyncd())
  - FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
  + }
  + catch (const std::exception &e)
  + {
  + LOGA("Exception thrown in PV thread while cleaning up: %s\n", e.what());
  + }
  }
  