message: Add check for the stake reward when the block is connecting
diff: @@ -2250,6 +2250,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
  std::vector<int> prevheights;
  CAmount nFees = 0;
  + CAmount nActualStakeReward = 0;
  int nInputs = 0;
  int64_t nSigOpsCost = 0;
  CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
  @@ -2299,6 +2300,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
  if (!tx.IsCoinBase())
  {
  + if (tx.IsCoinStake())
  + nActualStakeReward = tx.GetValueOut()-view.GetValueIn(tx);
  + else
  nFees += view.GetValueIn(tx)-tx.GetValueOut();
  std::vector<CScriptCheck> vChecks;
  @@ -2341,12 +2345,28 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
  int64_t nTime3 = GetTimeMicros(); nTimeConnect += nTime3 - nTime2;
  LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime3 - nTime2), 0.001 * (nTime3 - nTime2) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime3 - nTime2) / (nInputs-1), nTimeConnect * 0.000001);
  + if (block.IsProofOfWork())
  + {
  CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus());
  if (block.vtx[0]->GetValueOut() > blockReward)
  return state.DoS(100,
  error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
  block.vtx[0]->GetValueOut(), blockReward),
  REJECT_INVALID, "bad-cb-amount");
  + }
  + else
  + {
  + if (!CheckTransactionTimestamp(*block.vtx[1], *pblocktree))
  + return error("ConnectBlock() : %s unable to get coin age for coinstake", block.vtx[1]->GetHash().ToString());
  +
  + CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus());
  + if (nActualStakeReward > blockReward)
  + return state.DoS(100,
  + error("ConnectBlock(): coinstake pays too much (actual=%d vs limit=%d)",
  + block.vtx[0]->GetValueOut(), blockReward),
  + REJECT_INVALID, "bad-cs-amount");
  +
  + }
  if (!control.Wait())
  return state.DoS(100, false);
  