Merge #13655: bitcoinconsensus: invalid flags error should be set to bitcoinconsensus_err

417b6c1d29 bitcoinconsensus: invalid flags should be set to bitcoinconsensus_error type, add test cases covering bitcoinconsensus error codes (Thomas Kerin)

Pull request description:

  A check was added to the bitcoinconsensus verify_script codepath to ensure that callers only used _exposed_ interpreter flags. I think this error should be written to `bitcoinconsensus_err* err` and not returned by verify_script?

  I modified the check so it indicates the error using *err like the others, and added tests covering the error codes.

Tree-SHA512: 8ab370e56956a7d4740f83475e6078774affd663ac92383a02b85295da550f1b4f7a7a68f32ed5c5bcb39d98e2f15ec0b76de8399887e7763eb7c1e21d131093
This commit is contained in:
Wladimir J. van der Laan 2018-07-18 16:57:11 +02:00
commit 585db54dd1
No known key found for this signature in database
GPG key ID: 1E4AED62986CD25D
2 changed files with 143 additions and 1 deletions

View file

@ -81,7 +81,7 @@ static int verify_script(const unsigned char *scriptPubKey, unsigned int scriptP
unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err)
{
if (!verify_flags(flags)) {
return bitcoinconsensus_ERR_INVALID_FLAGS;
return set_error(err, bitcoinconsensus_ERR_INVALID_FLAGS);
}
try {
TxInputStream stream(SER_NETWORK, PROTOCOL_VERSION, txTo, txToLen);

View file

@ -1495,4 +1495,146 @@ BOOST_AUTO_TEST_CASE(script_can_append_self)
BOOST_CHECK(s == d);
}
#if defined(HAVE_CONSENSUS_LIB)
/* Test simple (successful) usage of bitcoinconsensus_verify_script */
BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_returns_true)
{
unsigned int libconsensus_flags = 0;
int nIn = 0;
CScript scriptPubKey;
CScript scriptSig;
CScriptWitness wit;
scriptPubKey << OP_1;
CTransaction creditTx = BuildCreditingTransaction(scriptPubKey, 1);
CTransaction spendTx = BuildSpendingTransaction(scriptSig, wit, creditTx);
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
stream << spendTx;
bitcoinconsensus_error err;
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 1);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_OK);
}
/* Test bitcoinconsensus_verify_script returns invalid tx index err*/
BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_index_err)
{
unsigned int libconsensus_flags = 0;
int nIn = 3;
CScript scriptPubKey;
CScript scriptSig;
CScriptWitness wit;
scriptPubKey << OP_EQUAL;
CTransaction creditTx = BuildCreditingTransaction(scriptPubKey, 1);
CTransaction spendTx = BuildSpendingTransaction(scriptSig, wit, creditTx);
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
stream << spendTx;
bitcoinconsensus_error err;
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_INDEX);
}
/* Test bitcoinconsensus_verify_script returns tx size mismatch err*/
BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_size)
{
unsigned int libconsensus_flags = 0;
int nIn = 0;
CScript scriptPubKey;
CScript scriptSig;
CScriptWitness wit;
scriptPubKey << OP_EQUAL;
CTransaction creditTx = BuildCreditingTransaction(scriptPubKey, 1);
CTransaction spendTx = BuildSpendingTransaction(scriptSig, wit, creditTx);
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
stream << spendTx;
bitcoinconsensus_error err;
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size() * 2, nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH);
}
/* Test bitcoinconsensus_verify_script returns invalid tx serialization error */
BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_serialization)
{
unsigned int libconsensus_flags = 0;
int nIn = 0;
CScript scriptPubKey;
CScript scriptSig;
CScriptWitness wit;
scriptPubKey << OP_EQUAL;
CTransaction creditTx = BuildCreditingTransaction(scriptPubKey, 1);
CTransaction spendTx = BuildSpendingTransaction(scriptSig, wit, creditTx);
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
stream << 0xffffffff;
bitcoinconsensus_error err;
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_DESERIALIZE);
}
/* Test bitcoinconsensus_verify_script returns amount required error */
BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_amount_required_err)
{
unsigned int libconsensus_flags = bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS;
int nIn = 0;
CScript scriptPubKey;
CScript scriptSig;
CScriptWitness wit;
scriptPubKey << OP_EQUAL;
CTransaction creditTx = BuildCreditingTransaction(scriptPubKey, 1);
CTransaction spendTx = BuildSpendingTransaction(scriptSig, wit, creditTx);
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
stream << spendTx;
bitcoinconsensus_error err;
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_AMOUNT_REQUIRED);
}
/* Test bitcoinconsensus_verify_script returns invalid flags err */
BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_invalid_flags)
{
unsigned int libconsensus_flags = 1 << 3;
int nIn = 0;
CScript scriptPubKey;
CScript scriptSig;
CScriptWitness wit;
scriptPubKey << OP_EQUAL;
CTransaction creditTx = BuildCreditingTransaction(scriptPubKey, 1);
CTransaction spendTx = BuildSpendingTransaction(scriptSig, wit, creditTx);
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
stream << spendTx;
bitcoinconsensus_error err;
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_INVALID_FLAGS);
}
#endif
BOOST_AUTO_TEST_SUITE_END()