Skip to content

Commit

Permalink
[Refactor] Move stack check inside CheckColdStake
Browse files Browse the repository at this point in the history
>>> adapted from df11631 (PIVX-Project#2275)

without introducing the new opcode
  • Loading branch information
random-zebra committed Jun 18, 2021
1 parent 2729c11 commit cff3325
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 29 deletions.
52 changes: 27 additions & 25 deletions src/script/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -962,26 +962,7 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&

case OP_CHECKCOLDSTAKEVERIFY:
{
// the stack can contain only <sig> <pk> <pkh> at this point
if ((int)stack.size() != 3) {
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
}
// check pubkey/signature encoding
valtype& vchSig = stacktop(-3);
valtype& vchPubKey = stacktop(-2);
if (!CheckSignatureEncoding(vchSig, flags, serror) ||
!CheckPubKeyEncoding(vchPubKey, flags, serror)) {
// serror is set
return false;
}
// check hash size
valtype& vchPubKeyHash = stacktop(-1);
if ((int)vchPubKeyHash.size() != 20) {
return set_error(serror, SCRIPT_ERR_SCRIPT_SIZE);
}
if(!checker.CheckColdStake(script)) {
return set_error(serror, SCRIPT_ERR_CHECKCOLDSTAKEVERIFY);
}
return checker.CheckColdStake(script, stack, flags, serror);
}
break;

Expand Down Expand Up @@ -1355,15 +1336,33 @@ bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) con
return true;
}

bool TransactionSignatureChecker::CheckColdStake(const CScript& prevoutScript) const
bool TransactionSignatureChecker::CheckColdStake(const CScript& prevoutScript, std::vector<valtype>& stack, unsigned int flags, ScriptError* serror) const
{
// the stack can contain only <sig> <pk> <pkh> at this point
if ((int)stack.size() != 3) {
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
}
// check pubkey/signature encoding
valtype& vchSig = stacktop(-3);
valtype& vchPubKey = stacktop(-2);
if (!CheckSignatureEncoding(vchSig, flags, serror) ||
!CheckPubKeyEncoding(vchPubKey, flags, serror)) {
// serror is set
return false;
}
// check hash size
valtype& vchPubKeyHash = stacktop(-1);
if ((int)vchPubKeyHash.size() != 20) {
return set_error(serror, SCRIPT_ERR_SCRIPT_SIZE);
}

// Transaction must be a coinstake tx
if (!txTo->IsCoinStake()) {
return false;
return set_error(serror, SCRIPT_ERR_CHECKCOLDSTAKEVERIFY);
}
// There must be one single input
if (txTo->vin.size() != 1) {
return false;
return set_error(serror, SCRIPT_ERR_CHECKCOLDSTAKEVERIFY);
}
// Since this is a coinstake, it has at least 2 outputs
const unsigned int outs = txTo->vout.size();
Expand All @@ -1378,13 +1377,16 @@ bool TransactionSignatureChecker::CheckColdStake(const CScript& prevoutScript) c
if (txTo->vout[i].scriptPubKey != prevoutScript) {
// Only the last one can be different (and only when outs >=3)
if (i != outs-1 || outs < 3) {
return false;
return set_error(serror, SCRIPT_ERR_CHECKCOLDSTAKEVERIFY);
}
} else {
outValue += txTo->vout[i].nValue;
}
}
return outValue > amount;
if (outValue < amount) {
return set_error(serror, SCRIPT_ERR_CHECKCOLDSTAKEVERIFY);
}
return true;
}


Expand Down
4 changes: 2 additions & 2 deletions src/script/interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class BaseSignatureChecker
return false;
}

virtual bool CheckColdStake(const CScript& script) const
virtual bool CheckColdStake(const CScript& prevoutScript, std::vector<valtype>& stack, unsigned int flags, ScriptError* error) const
{
return false;
}
Expand All @@ -132,7 +132,7 @@ class TransactionSignatureChecker : public BaseSignatureChecker

bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override ;
bool CheckLockTime(const CScriptNum& nLockTime) const override;
bool CheckColdStake(const CScript& prevoutScript) const override;
bool CheckColdStake(const CScript& prevoutScript, std::vector<valtype>& stack, unsigned int flags, ScriptError* error) const override;
};

class MutableTransactionSignatureChecker : public TransactionSignatureChecker
Expand Down
4 changes: 2 additions & 2 deletions src/test/script_P2CS_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ BOOST_AUTO_TEST_CASE(coldstake_script)
BOOST_CHECK(CheckP2CSScript(tx.vin[0].scriptSig, scriptP2CS, tx, err));

// Transfer more coins to the masternode
tx.vout[2].nValue -= 2 * COIN;
tx.vout[3].nValue += 2 * COIN;
tx.vout[2].nValue -= 3 * COIN;
tx.vout[3].nValue += 3 * COIN;
SignColdStake(tx, 0, scriptP2CS, stakerKey, true);
BOOST_CHECK(!CheckP2CSScript(tx.vin[0].scriptSig, scriptP2CS, tx, err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_CHECKCOLDSTAKEVERIFY, ScriptErrorString(err));
Expand Down

0 comments on commit cff3325

Please sign in to comment.