diff options
-rw-r--r-- | src/test/orphanage_tests.cpp | 20 | ||||
-rw-r--r-- | src/test/util/transaction_utils.cpp | 21 | ||||
-rw-r--r-- | src/test/util/transaction_utils.h | 4 |
3 files changed, 45 insertions, 0 deletions
diff --git a/src/test/orphanage_tests.cpp b/src/test/orphanage_tests.cpp index d4c52d7fe1..799f2c0fec 100644 --- a/src/test/orphanage_tests.cpp +++ b/src/test/orphanage_tests.cpp @@ -3,12 +3,15 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <arith_uint256.h> +#include <consensus/validation.h> +#include <policy/policy.h> #include <primitives/transaction.h> #include <pubkey.h> #include <script/sign.h> #include <script/signingprovider.h> #include <test/util/random.h> #include <test/util/setup_common.h> +#include <test/util/transaction_utils.h> #include <txorphanage.h> #include <array> @@ -370,4 +373,21 @@ BOOST_AUTO_TEST_CASE(get_children) } } +BOOST_AUTO_TEST_CASE(too_large_orphan_tx) +{ + TxOrphanage orphanage; + CMutableTransaction tx; + tx.vin.resize(1); + + // check that txs larger than MAX_STANDARD_TX_WEIGHT are not added to the orphanage + BulkTransaction(tx, MAX_STANDARD_TX_WEIGHT + 4); + BOOST_CHECK_EQUAL(GetTransactionWeight(CTransaction(tx)), MAX_STANDARD_TX_WEIGHT + 4); + BOOST_CHECK(!orphanage.AddTx(MakeTransactionRef(tx), 0)); + + tx.vout.clear(); + BulkTransaction(tx, MAX_STANDARD_TX_WEIGHT); + BOOST_CHECK_EQUAL(GetTransactionWeight(CTransaction(tx)), MAX_STANDARD_TX_WEIGHT); + BOOST_CHECK(orphanage.AddTx(MakeTransactionRef(tx), 0)); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util/transaction_utils.cpp b/src/test/util/transaction_utils.cpp index 300caa577c..5727da4444 100644 --- a/src/test/util/transaction_utils.cpp +++ b/src/test/util/transaction_utils.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <coins.h> +#include <consensus/validation.h> #include <script/signingprovider.h> #include <test/util/transaction_utils.h> @@ -69,3 +70,23 @@ std::vector<CMutableTransaction> SetupDummyInputs(FillableSigningProvider& keyst return dummyTransactions; } + +void BulkTransaction(CMutableTransaction& tx, int32_t target_weight) +{ + tx.vout.emplace_back(0, CScript() << OP_RETURN); + auto unpadded_weight{GetTransactionWeight(CTransaction(tx))}; + assert(target_weight >= unpadded_weight); + + // determine number of needed padding bytes by converting weight difference to vbytes + auto dummy_vbytes = (target_weight - unpadded_weight + (WITNESS_SCALE_FACTOR - 1)) / WITNESS_SCALE_FACTOR; + // compensate for the increase of the compact-size encoded script length + // (note that the length encoding of the unpadded output script needs one byte) + dummy_vbytes -= GetSizeOfCompactSize(dummy_vbytes) - 1; + + // pad transaction by repeatedly appending a dummy opcode to the output script + tx.vout[0].scriptPubKey.insert(tx.vout[0].scriptPubKey.end(), dummy_vbytes, OP_1); + + // actual weight should be at most 3 higher than target weight + assert(GetTransactionWeight(CTransaction(tx)) >= target_weight); + assert(GetTransactionWeight(CTransaction(tx)) <= target_weight + 3); +} diff --git a/src/test/util/transaction_utils.h b/src/test/util/transaction_utils.h index 6f2faeec6c..80f2d1acbf 100644 --- a/src/test/util/transaction_utils.h +++ b/src/test/util/transaction_utils.h @@ -26,4 +26,8 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CSc // the second nValues[2] and nValues[3] outputs paid to a TxoutType::PUBKEYHASH. std::vector<CMutableTransaction> SetupDummyInputs(FillableSigningProvider& keystoreRet, CCoinsViewCache& coinsRet, const std::array<CAmount,4>& nValues); +// bulk transaction to reach a certain target weight, +// by appending a single output with padded output script +void BulkTransaction(CMutableTransaction& tx, int32_t target_weight); + #endif // BITCOIN_TEST_UTIL_TRANSACTION_UTILS_H |