|
|
|
@ -73,7 +73,7 @@ ScriptError VerifyWithFlag(const CTransaction& output, const CMutableTransaction
@@ -73,7 +73,7 @@ ScriptError VerifyWithFlag(const CTransaction& output, const CMutableTransaction
|
|
|
|
|
{ |
|
|
|
|
ScriptError error; |
|
|
|
|
CTransaction inputi(input); |
|
|
|
|
bool ret = VerifyScript(inputi.vin[0].scriptSig, output.vout[0].scriptPubKey, inputi.wit.vtxinwit.size() > 0 ? &inputi.wit.vtxinwit[0].scriptWitness : NULL, flags, TransactionSignatureChecker(&inputi, 0, output.vout[0].nValue), &error); |
|
|
|
|
bool ret = VerifyScript(inputi.vin[0].scriptSig, output.vout[0].scriptPubKey, &inputi.vin[0].scriptWitness, flags, TransactionSignatureChecker(&inputi, 0, output.vout[0].nValue), &error); |
|
|
|
|
BOOST_CHECK((ret == true) == (error == SCRIPT_ERR_OK)); |
|
|
|
|
|
|
|
|
|
return error; |
|
|
|
@ -84,13 +84,12 @@ ScriptError VerifyWithFlag(const CTransaction& output, const CMutableTransaction
@@ -84,13 +84,12 @@ ScriptError VerifyWithFlag(const CTransaction& output, const CMutableTransaction
|
|
|
|
|
* and witness such that spendingTx spends output zero of creationTx. |
|
|
|
|
* Also inserts creationTx's output into the coins view. |
|
|
|
|
*/ |
|
|
|
|
void BuildTxs(CMutableTransaction& spendingTx, CCoinsViewCache& coins, CMutableTransaction& creationTx, const CScript& scriptPubKey, const CScript& scriptSig, const CTxInWitness& witness) |
|
|
|
|
void BuildTxs(CMutableTransaction& spendingTx, CCoinsViewCache& coins, CMutableTransaction& creationTx, const CScript& scriptPubKey, const CScript& scriptSig, const CScriptWitness& witness) |
|
|
|
|
{ |
|
|
|
|
creationTx.nVersion = 1; |
|
|
|
|
creationTx.vin.resize(1); |
|
|
|
|
creationTx.vin[0].prevout.SetNull(); |
|
|
|
|
creationTx.vin[0].scriptSig = CScript(); |
|
|
|
|
creationTx.wit.vtxinwit.resize(1); |
|
|
|
|
creationTx.vout.resize(1); |
|
|
|
|
creationTx.vout[0].nValue = 1; |
|
|
|
|
creationTx.vout[0].scriptPubKey = scriptPubKey; |
|
|
|
@ -100,8 +99,7 @@ void BuildTxs(CMutableTransaction& spendingTx, CCoinsViewCache& coins, CMutableT
@@ -100,8 +99,7 @@ void BuildTxs(CMutableTransaction& spendingTx, CCoinsViewCache& coins, CMutableT
|
|
|
|
|
spendingTx.vin[0].prevout.hash = creationTx.GetHash(); |
|
|
|
|
spendingTx.vin[0].prevout.n = 0; |
|
|
|
|
spendingTx.vin[0].scriptSig = scriptSig; |
|
|
|
|
spendingTx.wit.vtxinwit.resize(1); |
|
|
|
|
spendingTx.wit.vtxinwit[0] = witness; |
|
|
|
|
spendingTx.vin[0].scriptWitness = witness; |
|
|
|
|
spendingTx.vout.resize(1); |
|
|
|
|
spendingTx.vout[0].nValue = 1; |
|
|
|
|
spendingTx.vout[0].scriptPubKey = CScript(); |
|
|
|
@ -133,7 +131,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
@@ -133,7 +131,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
|
|
|
|
|
// Do not use a valid signature to avoid using wallet operations.
|
|
|
|
|
CScript scriptSig = CScript() << OP_0 << OP_0; |
|
|
|
|
|
|
|
|
|
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, CTxInWitness()); |
|
|
|
|
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, CScriptWitness()); |
|
|
|
|
// Legacy counting only includes signature operations in scriptSigs and scriptPubKeys
|
|
|
|
|
// of a transaction and does not take the actual executed sig operations into account.
|
|
|
|
|
// spendingTx in itself does not contain a signature operation.
|
|
|
|
@ -151,7 +149,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
@@ -151,7 +149,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
|
|
|
|
|
CScript scriptPubKey = GetScriptForDestination(CScriptID(redeemScript)); |
|
|
|
|
CScript scriptSig = CScript() << OP_0 << OP_0 << ToByteVector(redeemScript); |
|
|
|
|
|
|
|
|
|
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, CTxInWitness()); |
|
|
|
|
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, CScriptWitness()); |
|
|
|
|
assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 2 * WITNESS_SCALE_FACTOR); |
|
|
|
|
assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY); |
|
|
|
|
} |
|
|
|
@ -161,14 +159,12 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
@@ -161,14 +159,12 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
|
|
|
|
|
CScript p2pk = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; |
|
|
|
|
CScript scriptPubKey = GetScriptForWitness(p2pk); |
|
|
|
|
CScript scriptSig = CScript(); |
|
|
|
|
CTxInWitness witness; |
|
|
|
|
CScriptWitness scriptWitness; |
|
|
|
|
scriptWitness.stack.push_back(vector<unsigned char>(0)); |
|
|
|
|
scriptWitness.stack.push_back(vector<unsigned char>(0)); |
|
|
|
|
witness.scriptWitness = scriptWitness; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); |
|
|
|
|
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, scriptWitness); |
|
|
|
|
assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 1); |
|
|
|
|
// No signature operations if we don't verify the witness.
|
|
|
|
|
assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags & ~SCRIPT_VERIFY_WITNESS) == 0); |
|
|
|
@ -177,10 +173,10 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
@@ -177,10 +173,10 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
|
|
|
|
|
// The sig op cost for witness version != 0 is zero.
|
|
|
|
|
assert(scriptPubKey[0] == 0x00); |
|
|
|
|
scriptPubKey[0] = 0x51; |
|
|
|
|
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); |
|
|
|
|
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, scriptWitness); |
|
|
|
|
assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 0); |
|
|
|
|
scriptPubKey[0] = 0x00; |
|
|
|
|
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); |
|
|
|
|
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, scriptWitness); |
|
|
|
|
|
|
|
|
|
// The witness of a coinbase transaction is not taken into account.
|
|
|
|
|
spendingTx.vin[0].prevout.SetNull(); |
|
|
|
@ -193,13 +189,11 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
@@ -193,13 +189,11 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
|
|
|
|
|
CScript scriptSig = GetScriptForWitness(p2pk); |
|
|
|
|
CScript scriptPubKey = GetScriptForDestination(CScriptID(scriptSig)); |
|
|
|
|
scriptSig = CScript() << ToByteVector(scriptSig); |
|
|
|
|
CTxInWitness witness; |
|
|
|
|
CScriptWitness scriptWitness; |
|
|
|
|
scriptWitness.stack.push_back(vector<unsigned char>(0)); |
|
|
|
|
scriptWitness.stack.push_back(vector<unsigned char>(0)); |
|
|
|
|
witness.scriptWitness = scriptWitness; |
|
|
|
|
|
|
|
|
|
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); |
|
|
|
|
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, scriptWitness); |
|
|
|
|
assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 1); |
|
|
|
|
assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_EQUALVERIFY); |
|
|
|
|
} |
|
|
|
@ -209,14 +203,12 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
@@ -209,14 +203,12 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
|
|
|
|
|
CScript witnessScript = CScript() << 1 << ToByteVector(pubkey) << ToByteVector(pubkey) << 2 << OP_CHECKMULTISIGVERIFY; |
|
|
|
|
CScript scriptPubKey = GetScriptForWitness(witnessScript); |
|
|
|
|
CScript scriptSig = CScript(); |
|
|
|
|
CTxInWitness witness; |
|
|
|
|
CScriptWitness scriptWitness; |
|
|
|
|
scriptWitness.stack.push_back(vector<unsigned char>(0)); |
|
|
|
|
scriptWitness.stack.push_back(vector<unsigned char>(0)); |
|
|
|
|
scriptWitness.stack.push_back(vector<unsigned char>(witnessScript.begin(), witnessScript.end())); |
|
|
|
|
witness.scriptWitness = scriptWitness; |
|
|
|
|
|
|
|
|
|
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); |
|
|
|
|
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, scriptWitness); |
|
|
|
|
assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 2); |
|
|
|
|
assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags & ~SCRIPT_VERIFY_WITNESS) == 0); |
|
|
|
|
assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY); |
|
|
|
@ -228,14 +220,12 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
@@ -228,14 +220,12 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
|
|
|
|
|
CScript redeemScript = GetScriptForWitness(witnessScript); |
|
|
|
|
CScript scriptPubKey = GetScriptForDestination(CScriptID(redeemScript)); |
|
|
|
|
CScript scriptSig = CScript() << ToByteVector(redeemScript); |
|
|
|
|
CTxInWitness witness; |
|
|
|
|
CScriptWitness scriptWitness; |
|
|
|
|
scriptWitness.stack.push_back(vector<unsigned char>(0)); |
|
|
|
|
scriptWitness.stack.push_back(vector<unsigned char>(0)); |
|
|
|
|
scriptWitness.stack.push_back(vector<unsigned char>(witnessScript.begin(), witnessScript.end())); |
|
|
|
|
witness.scriptWitness = scriptWitness; |
|
|
|
|
|
|
|
|
|
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); |
|
|
|
|
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, scriptWitness); |
|
|
|
|
assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 2); |
|
|
|
|
assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY); |
|
|
|
|
} |
|
|
|
|