diff --git a/src/test/blind_tests.cpp b/src/test/blind_tests.cpp index baee74b896..261800d8dc 100644 --- a/src/test/blind_tests.cpp +++ b/src/test/blind_tests.cpp @@ -87,6 +87,31 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test) tx3.vout.push_back(CTxOut(bitcoinID, 22, CScript())); BOOST_CHECK(VerifyAmounts(cache, tx3)); + // Malleate the output and check for correct handling of bad commitments + // These will fail IsValid checks + std::vector asset_copy(tx3.vout[0].nAsset.vchCommitment); + std::vector value_copy(tx3.vout[0].nValue.vchCommitment); + tx3.vout[0].nAsset.vchCommitment[0] = 122; + BOOST_CHECK(!VerifyAmounts(cache, tx3)); + tx3.vout[0].nAsset.vchCommitment = asset_copy; + tx3.vout[0].nValue.vchCommitment[0] = 122; + BOOST_CHECK(!VerifyAmounts(cache, tx3)); + tx3.vout[0].nValue.vchCommitment = value_copy; + + // Make sure null values are handled correctly + tx3.vout[0].nAsset.SetNull(); + BOOST_CHECK(!VerifyAmounts(cache, tx3)); + tx3.vout[0].nAsset.vchCommitment = asset_copy; + tx3.vout[0].nValue.SetNull(); + BOOST_CHECK(!VerifyAmounts(cache, tx3)); + tx3.vout[0].nValue.vchCommitment = value_copy; + + // Bad nonce values will result in failure to deserialize + tx3.vout[0].nNonce.SetNull(); + BOOST_CHECK(VerifyAmounts(cache, tx3)); + tx3.vout[0].nNonce.vchCommitment = tx3.vout[0].nValue.vchCommitment; + BOOST_CHECK(!VerifyAmounts(cache, tx3)); + // Try to blind with a single non-fee output, which fails as its blinding factor ends up being zero. std::vector input_blinds; std::vector input_asset_blinds; diff --git a/src/validation.cpp b/src/validation.cpp index a54a4d9820..5fc4efb698 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -735,15 +735,14 @@ bool VerifyAmounts(const CCoinsViewCache& cache, const CTransaction& tx, std::ve if (!MoneyRange(val.GetAmount())) return false; - assert(val.GetAmount() != 0); - if (secp256k1_pedersen_commit(secp256k1_ctx_verify_amounts, &commit, explBlinds, val.GetAmount(), &gen) != 1) return false; } - else { - assert(val.IsCommitment()); + else if (val.IsCommitment()) { if (secp256k1_pedersen_commitment_parse(secp256k1_ctx_verify_amounts, &commit, &val.vchCommitment[0]) != 1) return false; + } else { + return false; } vData.push_back(commit); @@ -901,7 +900,6 @@ bool VerifyAmounts(const CCoinsViewCache& cache, const CTransaction& tx, std::ve return false; } else { - assert(false); return false; } @@ -921,10 +919,11 @@ bool VerifyAmounts(const CCoinsViewCache& cache, const CTransaction& tx, std::ve if (secp256k1_pedersen_commit(secp256k1_ctx_verify_amounts, &commit, explBlinds, val.GetAmount(), &gen) != 1) return false; } - else - { + else if (val.IsCommitment()) { if (secp256k1_pedersen_commitment_parse(secp256k1_ctx_verify_amounts, &commit, &val.vchCommitment[0]) != 1) return false; + } else { + return false; } vData.push_back(commit);