| 410 | } |
| 411 | |
| 412 | bool VerifyCoinbaseAmount(const CTransaction& tx, const CAmountMap& mapFees) { |
| 413 | assert(tx.IsCoinBase()); |
| 414 | |
| 415 | // Miner shouldn't be stuffing witness data |
| 416 | for (const auto& outwit : tx.witness.vtxoutwit) { |
| 417 | if (!outwit.IsNull()) { |
| 418 | return false; |
| 419 | } |
| 420 | } |
| 421 | |
| 422 | CAmountMap remaining = mapFees; |
| 423 | for (unsigned int i = 0; i < tx.vout.size(); i++) { |
| 424 | const CTxOut& out = tx.vout[i]; |
| 425 | if (!out.nValue.IsExplicit() || !out.nAsset.IsExplicit()) { |
| 426 | return false; |
| 427 | } |
| 428 | if (!MoneyRange(out.nValue.GetAmount())) { |
| 429 | return false; |
| 430 | } |
| 431 | if (g_con_elementsmode && |
| 432 | out.nValue.GetAmount() == 0 && !out.scriptPubKey.IsUnspendable()) { |
| 433 | return false; |
| 434 | } |
| 435 | remaining[out.nAsset.GetAsset()] -= out.nValue.GetAmount(); |
| 436 | } |
| 437 | return MoneyRange(remaining); |
| 438 | } |
no test coverage detected