message: Do contextual checks to zerocoin tx's when adding to mempool.
diff: @@ -711,6 +711,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
  if (fHasBasecoinInputs && fHasZerocoinInputs)
  return state.Invalid(error("%s: tx mixes zerocoin and basecoin inputs", __func__, REJECT_INVALID, "txn-mixed-zerocoin-inputs"));
  + std::vector<libzerocoin::SerialNumberSoKProof> vProofs;
  {
  CCoinsView dummy;
  CCoinsViewCache view(&dummy);
  @@ -744,6 +745,12 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
  return state.Invalid(false, REJECT_DUPLICATE, "zcspend-already-in-mempool");
  }
  + if (!ContextualCheckZerocoinSpend(tx, *spend, pindexBestHeader->GetBlockHash(), pindexBestHeader, /*fSkipVerify*/true))
  + return state.Invalid(false, REJECT_INVALID, "failed-zcspend-context-checks");
  +
  + libzerocoin::SerialNumberSoKProof proof(spend->getSmallSoK(), spend->getCoinSerialNumber(),
  + spend->getSerialComm(), spend->getHashSig());
  + vProofs.emplace_back(proof);
  setSerials.emplace(bnSerial);
  continue;
  }
  @@ -786,6 +793,13 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
  return false;
  }
  }
  +
  + //Do context checks of mint
  + if (!setPubcoins.empty()) {
  + libzerocoin::PublicCoin pubcoin(Params().Zerocoin_Params());
  + if (!OutputToPublicCoin(pout.get(), pubcoin) || !ContextualCheckZerocoinMint(tx, pubcoin, chainActive.Tip()))
  + return state.Invalid(false, REJECT_INVALID, "zcmint-fail-context-check");
  + }
  }
  if (!AllAnonOutputsUnknown(tx, state)) // set state.fHasAnonOutput
  @@ -1063,6 +1077,14 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
  __func__, hash.ToString(), FormatStateMessage(state));
  }
  + // Last we batch verify zerocoin spend proofs
  + if (!vProofs.empty()) {
  + if (!libzerocoin::SerialNumberSoKProof::BatchVerify(vProofs)) {
  + return state.DoS(100, error("%s: Failed to verify zerocoinspend proofs for tx %s", __func__,
  + tx.GetHash().GetHex()), REJECT_INVALID);
  + }
  + }
  +
  if (test_accept) {
  // Tx was accepted, but not added
  return true;
  