Skip to content

Commit 75b8861

Browse files
committed
[Script] Unify OP_CHECKCOLDSTAKEVERIFY checks
Pass the script that we are spending to CTransaction::CheckColdStake(), directly from the interpreter. This way, there's no need for additional verifications in CheckTransaction (except for enforcement/activation).
1 parent 2a5bae7 commit 75b8861

File tree

6 files changed

+15
-43
lines changed

6 files changed

+15
-43
lines changed

src/main.cpp

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,25 +1174,6 @@ bool CheckZerocoinSpend(const CTransaction& tx, bool fVerifySignature, CValidati
11741174
return fValidated;
11751175
}
11761176

1177-
bool CheckColdStake(const CTransaction& tx, CValidationState& state, bool fColdStakingActive)
1178-
{
1179-
CTxOut prevOut;
1180-
if(!GetOutput(tx.vin[0].prevout.hash, tx.vin[0].prevout.n, state, prevOut))
1181-
return state.DoS(100, error("%s : invalid input", __func__), REJECT_INVALID, "bad-txns-inputs");
1182-
1183-
if (!prevOut.scriptPubKey.IsPayToColdStaking())
1184-
return true;
1185-
1186-
if (!fColdStakingActive)
1187-
return state.DoS(100, error("%s : invalid input", __func__), REJECT_INVALID, "coldstake-not-active");
1188-
1189-
// spending to the same contract
1190-
if (prevOut.scriptPubKey != tx.vout[1].scriptPubKey)
1191-
return state.DoS(100, error("%s : invalid scripts", __func__), REJECT_INVALID, "bad-txns-cold-stake");
1192-
1193-
return true;
1194-
}
1195-
11961177
bool CheckTransaction(const CTransaction& tx, bool fZerocoinActive, bool fRejectBadUTXO, CValidationState& state, bool fFakeSerialAttack, bool fColdStakingActive)
11971178
{
11981179
// Basic checks that don't depend on any context
@@ -1241,10 +1222,6 @@ bool CheckTransaction(const CTransaction& tx, bool fZerocoinActive, bool fReject
12411222
}
12421223
}
12431224

1244-
// Additional check for cold staking
1245-
if (tx.IsCoinStake() && !tx.HasZerocoinSpendInputs() && !CheckColdStake(tx, state, fColdStakingActive))
1246-
return state.DoS(100, error("%s: invalid cold stake", __func__), REJECT_INVALID, "bad-txns-cold-stake");
1247-
12481225
std::set<COutPoint> vInOutPoints;
12491226
std::set<CBigNum> vZerocoinSpendSerials;
12501227
int nZCSpendCount = 0;
@@ -4474,8 +4451,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
44744451
if (!IsInitialBlockDownload() && block.vtx[1].HasP2CSOutputs() && !sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)) {
44754452
const int outputs = block.vtx[1].vout.size();
44764453
if (outputs >=3 && block.vtx[1].vout[outputs-1].scriptPubKey != block.vtx[1].vout[outputs-2].scriptPubKey)
4477-
return state.DoS(100, error("%s: Wrong cold staking outputs when masternode payment enforcement is disabled on tx %s",
4478-
__func__, block.vtx[1].ToString().c_str()));
4454+
return state.DoS(100, error("%s: Wrong cold staking outputs when masternode payment enforcement is disabled: "
4455+
"script[-1] (%s) != script[-2] (%s)", __func__,
4456+
HexStr(block.vtx[1].vout[outputs-1].scriptPubKey), HexStr(block.vtx[1].vout[outputs-2].scriptPubKey)));
44794457
}
44804458
}
44814459

src/main.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -351,11 +351,6 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& ma
351351
*/
352352
bool CheckInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& view, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector<CScriptCheck>* pvChecks = NULL);
353353

354-
/*
355-
* Check cold stakes P2CS script rules and enforcement activation
356-
*/
357-
bool CheckColdStake(const CTransaction& tx, CValidationState& state, bool fColdStakingActive);
358-
359354
/** Apply the effects of this transaction on the UTXO set represented by view */
360355
void UpdateCoins(const CTransaction& tx, CValidationState& state, CCoinsViewCache& inputs, CTxUndo& txundo, int nHeight);
361356

src/primitives/transaction.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -209,28 +209,28 @@ bool CTransaction::IsCoinStake() const
209209
return (vout.size() >= 2 && vout[0].IsEmpty());
210210
}
211211

212-
bool CTransaction::CheckColdStake() const
212+
bool CTransaction::CheckColdStake(const CScript& script) const
213213
{
214+
214215
// tx is a coinstake tx
215216
if (!IsCoinStake())
216217
return false;
217218

218-
// all inputs have the same pubKeyScript
219+
// all inputs have the same scriptSig
219220
CScript firstScript = vin[0].scriptSig;
220221
if (vin.size() > 1) {
221222
for (unsigned int i=1; i<vin.size(); i++)
222223
if (vin[i].scriptSig != firstScript) return false;
223224
}
224225

225226
// all outputs except first (coinstake marker) and last (masternode payout)
226-
// have the same pubKeyScript
227-
firstScript = vout[1].scriptPubKey;
228-
if (vout.size() > 3) {
227+
// have the same pubKeyScript and it matches the script we are spending
228+
if (vout[1].scriptPubKey != script) return false;
229+
if (vin.size() > 3) {
229230
for (unsigned int i=2; i<vout.size()-1; i++)
230-
if (vout[i].scriptPubKey != firstScript) return false;
231+
if (vout[i].scriptPubKey != script) return false;
231232
}
232233

233-
// additional checks in CheckTransaction
234234
return true;
235235
}
236236

src/primitives/transaction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ class CTransaction
283283
}
284284

285285
bool IsCoinStake() const;
286-
bool CheckColdStake() const;
286+
bool CheckColdStake(const CScript& script) const;
287287
bool HasP2CSOutputs() const;
288288

289289
friend bool operator==(const CTransaction& a, const CTransaction& b)

src/script/interpreter.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -962,10 +962,9 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
962962
case OP_CHECKCOLDSTAKEVERIFY:
963963
{
964964
// check it is used in a valid cold stake transaction.
965-
if(!checker.CheckColdStake()) {
965+
if(!checker.CheckColdStake(script)) {
966966
return set_error(serror, SCRIPT_ERR_CHECKCOLDSTAKEVERIFY);
967967
}
968-
// CheckTransaction verifies that prevout scripts match with out scripts
969968
}
970969
break;
971970

src/script/interpreter.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class BaseSignatureChecker
9898
return false;
9999
}
100100

101-
virtual bool CheckColdStake() const
101+
virtual bool CheckColdStake(const CScript& script) const
102102
{
103103
return false;
104104
}
@@ -119,8 +119,8 @@ class TransactionSignatureChecker : public BaseSignatureChecker
119119
TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {}
120120
bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const;
121121
bool CheckLockTime(const CScriptNum& nLockTime) const;
122-
bool CheckColdStake() const override {
123-
return txTo->CheckColdStake();
122+
bool CheckColdStake(const CScript& script) const override {
123+
return txTo->CheckColdStake(script);
124124
}
125125
};
126126

0 commit comments

Comments
 (0)