@@ -618,15 +618,17 @@ class CSurjectionCheck : public CCheck
618618 bool operator ()();
619619};
620620
621- // Does *not* destroy the check in the case of no queue, or passes its ownership to the queue.
622- static inline bool QueueCheck (std::vector<CCheck*>* queue, CCheck* check)
621+ // Destroys the check in the case of no queue, or passes its ownership to the queue.
622+ static inline ScriptError QueueCheck (std::vector<CCheck*>* queue, CCheck* check)
623623{
624624 if (queue != NULL ) {
625625 queue->push_back (check);
626- return true ;
626+ return SCRIPT_ERR_OK ;
627627 }
628- bool ret = (*check)();
629- return ret;
628+ bool success = (*check)();
629+ ScriptError err = check->GetScriptError ();
630+ delete check;
631+ return success ? SCRIPT_ERR_OK : err;
630632}
631633
632634
@@ -636,13 +638,19 @@ bool CRangeCheck::operator()()
636638 return true ;
637639 }
638640
639- return CachingRangeProofChecker (store).VerifyRangeProof (rangeproof, val->vchCommitment , assetCommitment, scriptPubKey, secp256k1_ctx_verify_amounts);
641+ if (!CachingRangeProofChecker (store).VerifyRangeProof (rangeproof, val->vchCommitment , assetCommitment, scriptPubKey, secp256k1_ctx_verify_amounts)) {
642+ error = SCRIPT_ERR_RANGEPROOF;
643+ return false ;
644+ }
645+
646+ return true ;
640647};
641648
642649bool CBalanceCheck::operator ()()
643650{
644651 if (!secp256k1_pedersen_verify_tally (secp256k1_ctx_verify_amounts, vpCommitsIn.data (), vpCommitsIn.size (), vpCommitsOut.data (), vpCommitsOut.size ())) {
645652 fAmountError = true ;
653+ error = SCRIPT_ERR_PEDERSEN_TALLY;
646654 return false ;
647655 }
648656
@@ -822,7 +830,7 @@ bool VerifyAmounts(const CCoinsViewCache& cache, const CTransaction& tx, std::ve
822830 p++;
823831
824832 // Rangecheck must be done for blinded amount
825- if (issuance.nAmount .IsCommitment () && ! QueueCheck (pvChecks, new CRangeCheck (&issuance.nAmount , tx.wit .vtxinwit [i].vchIssuanceAmountRangeproof , issuanceAsset.vchCommitment , CScript (), cacheStore))) {
833+ if (issuance.nAmount .IsCommitment () && QueueCheck (pvChecks, new CRangeCheck (&issuance.nAmount , tx.wit .vtxinwit [i].vchIssuanceAmountRangeproof , issuanceAsset.vchCommitment , CScript (), cacheStore)) != SCRIPT_ERR_OK ) {
826834 return false ;
827835 }
828836 }
@@ -863,7 +871,7 @@ bool VerifyAmounts(const CCoinsViewCache& cache, const CTransaction& tx, std::ve
863871 vpCommitsIn.push_back (p);
864872 p++;
865873
866- if (issuance.nInflationKeys .IsCommitment () && ! QueueCheck (pvChecks, new CRangeCheck (&issuance.nInflationKeys , tx.wit .vtxinwit [i].vchInflationKeysRangeproof , tokenAsset.vchCommitment , CScript (), cacheStore))) {
874+ if (issuance.nInflationKeys .IsCommitment () && QueueCheck (pvChecks, new CRangeCheck (&issuance.nInflationKeys , tx.wit .vtxinwit [i].vchInflationKeysRangeproof , tokenAsset.vchCommitment , CScript (), cacheStore)) != SCRIPT_ERR_OK ) {
867875 return false ;
868876 }
869877 } else if (!issuance.nInflationKeys .IsNull ()) {
@@ -925,7 +933,7 @@ bool VerifyAmounts(const CCoinsViewCache& cache, const CTransaction& tx, std::ve
925933 }
926934
927935 // Check balance
928- if (! QueueCheck (pvChecks, new CBalanceCheck (vData, vpCommitsIn, vpCommitsOut))) {
936+ if (QueueCheck (pvChecks, new CBalanceCheck (vData, vpCommitsIn, vpCommitsOut)) != SCRIPT_ERR_OK ) {
929937 return false ;
930938 }
931939
@@ -949,7 +957,7 @@ bool VerifyAmounts(const CCoinsViewCache& cache, const CTransaction& tx, std::ve
949957 if (!ptxoutwit || ptxoutwit->vchRangeproof .size () > 5000 ) {
950958 return false ;
951959 }
952- if (! QueueCheck (pvChecks, new CRangeCheck (&val, ptxoutwit->vchRangeproof , vchAssetCommitment, tx.vout [i].scriptPubKey , cacheStore))) {
960+ if (QueueCheck (pvChecks, new CRangeCheck (&val, ptxoutwit->vchRangeproof , vchAssetCommitment, tx.vout [i].scriptPubKey , cacheStore)) != SCRIPT_ERR_OK ) {
953961 return false ;
954962 }
955963 }
@@ -976,7 +984,7 @@ bool VerifyAmounts(const CCoinsViewCache& cache, const CTransaction& tx, std::ve
976984 if (secp256k1_surjectionproof_parse (secp256k1_ctx_verify_amounts, &proof, &ptxoutwit->vchSurjectionproof [0 ], ptxoutwit->vchSurjectionproof .size ()) != 1 )
977985 return false ;
978986
979- if (! QueueCheck (pvChecks, new CSurjectionCheck (proof, targetGenerators, gen, cacheStore))) {
987+ if (QueueCheck (pvChecks, new CSurjectionCheck (proof, targetGenerators, gen, cacheStore)) != SCRIPT_ERR_OK ) {
980988 return false ;
981989 }
982990 // Each CSurjectionCheck uses swap to keep pointers valid.
@@ -2079,7 +2087,8 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
20792087
20802088 // Verify signature
20812089 CCheck* check = new CScriptCheck (*coins, tx, i, prevValueIn, flags, cacheStore, &txdata);
2082- if (!QueueCheck (pvChecks, check)) {
2090+ ScriptError serror = QueueCheck (pvChecks, check);
2091+ if (serror != SCRIPT_ERR_OK) {
20832092 if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
20842093 // Check whether the failure was caused by a
20852094 // non-mandatory script verification check, such as
@@ -2090,7 +2099,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
20902099 CScriptCheck check2 (*coins, tx, i, prevValueIn,
20912100 flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore, &txdata);
20922101 if (check2 ())
2093- return state.Invalid (false , REJECT_NONSTANDARD, strprintf (" non-mandatory-script-verify-flag (%s)" , ScriptErrorString (check-> GetScriptError () )));
2102+ return state.Invalid (false , REJECT_NONSTANDARD, strprintf (" non-mandatory-script-verify-flag (%s)" , ScriptErrorString (serror )));
20942103 }
20952104 // Failures of other flags indicate a transaction that is
20962105 // invalid in new blocks, e.g. a invalid P2SH. We DoS ban
@@ -2099,14 +2108,6 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
20992108 // as to the correct behavior - we may want to continue
21002109 // peering with non-upgraded nodes even after soft-fork
21012110 // super-majority signaling has occurred.
2102-
2103- // If the check was deleted already, we have no idea what is
2104- // wrong with it. This should only happen during ConnectBlock
2105- // with a non-NULL queue. Since this code is only reached in
2106- // the one-shot mempool case it will never be deleted.
2107- assert (check);
2108- ScriptError serror = check->GetScriptError ();
2109- delete check;
21102111 if (serror == SCRIPT_ERR_WITHDRAW_VERIFY_BLOCKCONFIRMED)
21112112 return state.Invalid (false , REJECT_SCRIPT, strprintf (" mandatory-script-verify-flag-failed (%s)" , ScriptErrorString (serror)));
21122113 else
0 commit comments