Skip to content

Commit cf9efd8

Browse files
authored
Merge pull request #220 from instagibbs/revertcheck
Revert ownership of CCheck to QueueCheck, return ScriptError
2 parents cc3a368 + f3a4e5b commit cf9efd8

File tree

2 files changed

+26
-22
lines changed

2 files changed

+26
-22
lines changed

src/script/script_error.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,10 @@ typedef enum ScriptError_t
7777
SCRIPT_ERR_WITHDRAW_VERIFY_BLOCKCONFIRMED,
7878
SCRIPT_ERR_WITHDRAW_VERIFY_BLINDED_AMOUNTS,
7979

80-
SCRIPT_ERR_ERROR_COUNT
80+
SCRIPT_ERR_ERROR_COUNT,
81+
82+
SCRIPT_ERR_RANGEPROOF,
83+
SCRIPT_ERR_PEDERSEN_TALLY
8184
} ScriptError;
8285

8386
#define SCRIPT_ERR_LAST SCRIPT_ERR_ERROR_COUNT

src/validation.cpp

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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

642649
bool 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

Comments
 (0)