@@ -1151,6 +1151,107 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
11511151 BOOST_CHECK_MESSAGE (err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString (err));
11521152}
11531153
1154+ /* * Return the TxoutType of a script without exposing Solver details. */
1155+ static TxoutType GetTxoutType (const CScript& output_script)
1156+ {
1157+ std::vector<std::vector<uint8_t >> unused;
1158+ return Solver (output_script, unused);
1159+ }
1160+
1161+ #define CHECK_SCRIPT_STATIC_SIZE (script, expected_size ) \
1162+ do { \
1163+ BOOST_CHECK_EQUAL ((script).size (), (expected_size)); \
1164+ BOOST_CHECK_EQUAL ((script).capacity (), CScriptBase::STATIC_SIZE); \
1165+ BOOST_CHECK_EQUAL ((script).allocated_memory (), 0 ); \
1166+ } while (0 )
1167+
1168+ #define CHECK_SCRIPT_DYNAMIC_SIZE (script, expected_size, expected_extra ) \
1169+ do { \
1170+ BOOST_CHECK_EQUAL ((script).size (), (expected_size)); \
1171+ BOOST_CHECK_EQUAL ((script).capacity (), (expected_extra)); \
1172+ BOOST_CHECK_EQUAL ((script).allocated_memory (), (expected_extra)); \
1173+ } while (0 )
1174+
1175+ BOOST_AUTO_TEST_CASE (script_size_and_capacity_test)
1176+ {
1177+ BOOST_CHECK_EQUAL (sizeof (CompressedScript), 40 );
1178+ BOOST_CHECK_EQUAL (sizeof (CScriptBase), 32 );
1179+ BOOST_CHECK_NE (sizeof (CScriptBase), sizeof (prevector<CScriptBase::STATIC_SIZE + 1 , uint8_t >)); // CScriptBase size should be set to avoid wasting space in padding
1180+ BOOST_CHECK_EQUAL (sizeof (CScript), 32 );
1181+ BOOST_CHECK_EQUAL (sizeof (CTxOut), 40 );
1182+
1183+ CKey dummy_key;
1184+ dummy_key.MakeNewKey (/* fCompressed=*/ true );
1185+ const CPubKey dummy_pubkey{dummy_key.GetPubKey ()};
1186+
1187+ // Small OP_RETURN has direct allocation
1188+ {
1189+ const auto script{CScript () << OP_RETURN << std::vector<uint8_t >(10 , 0xaa )};
1190+ BOOST_CHECK_EQUAL (GetTxoutType (script), TxoutType::NULL_DATA);
1191+ CHECK_SCRIPT_STATIC_SIZE (script, 12 );
1192+ }
1193+
1194+ // P2WPKH has direct allocation
1195+ {
1196+ const auto script{GetScriptForDestination (WitnessV0KeyHash{PKHash{dummy_pubkey}})};
1197+ BOOST_CHECK_EQUAL (GetTxoutType (script), TxoutType::WITNESS_V0_KEYHASH);
1198+ CHECK_SCRIPT_STATIC_SIZE (script, 22 );
1199+ }
1200+
1201+ // P2SH has direct allocation
1202+ {
1203+ const auto script{GetScriptForDestination (ScriptHash{CScript{} << OP_TRUE})};
1204+ BOOST_CHECK (script.IsPayToScriptHash ());
1205+ CHECK_SCRIPT_STATIC_SIZE (script, 23 );
1206+ }
1207+
1208+ // P2PKH has direct allocation
1209+ {
1210+ const auto script{GetScriptForDestination (PKHash{dummy_pubkey})};
1211+ BOOST_CHECK_EQUAL (GetTxoutType (script), TxoutType::PUBKEYHASH);
1212+ CHECK_SCRIPT_STATIC_SIZE (script, 25 );
1213+ }
1214+
1215+ // P2WSH needs extra allocation
1216+ {
1217+ const auto script{GetScriptForDestination (WitnessV0ScriptHash{CScript{} << OP_TRUE})};
1218+ BOOST_CHECK (script.IsPayToWitnessScriptHash ());
1219+ CHECK_SCRIPT_DYNAMIC_SIZE (script, 34 , 34 );
1220+ }
1221+
1222+ // P2TR needs extra allocation
1223+ {
1224+ const auto script{GetScriptForDestination (WitnessV1Taproot{XOnlyPubKey{dummy_pubkey}})};
1225+ BOOST_CHECK_EQUAL (GetTxoutType (script), TxoutType::WITNESS_V1_TAPROOT);
1226+ CHECK_SCRIPT_DYNAMIC_SIZE (script, 34 , 34 );
1227+ }
1228+
1229+ // Compressed P2PK needs extra allocation
1230+ {
1231+ const auto script{GetScriptForRawPubKey (dummy_pubkey)};
1232+ BOOST_CHECK_EQUAL (GetTxoutType (script), TxoutType::PUBKEY);
1233+ CHECK_SCRIPT_DYNAMIC_SIZE (script, 35 , 35 );
1234+ }
1235+
1236+ // Uncompressed P2PK needs extra allocation
1237+ {
1238+ CKey uncompressed_key;
1239+ uncompressed_key.MakeNewKey (/* fCompressed=*/ false );
1240+ const CPubKey uncompressed_pubkey{uncompressed_key.GetPubKey ()};
1241+
1242+ const auto script{GetScriptForRawPubKey (uncompressed_pubkey)};
1243+ BOOST_CHECK_EQUAL (GetTxoutType (script), TxoutType::PUBKEY);
1244+ CHECK_SCRIPT_DYNAMIC_SIZE (script, 67 , 67 );
1245+ }
1246+
1247+ // Bare multisig needs extra allocation
1248+ {
1249+ const auto script{GetScriptForMultisig (1 , std::vector{2 , dummy_pubkey})};
1250+ BOOST_CHECK_EQUAL (GetTxoutType (script), TxoutType::MULTISIG);
1251+ CHECK_SCRIPT_DYNAMIC_SIZE (script, 71 , 103 );
1252+ }
1253+ }
1254+
11541255/* Wrapper around ProduceSignature to combine two scriptsigs */
11551256SignatureData CombineSignatures (const CTxOut& txout, const CMutableTransaction& tx, const SignatureData& scriptSig1, const SignatureData& scriptSig2)
11561257{
0 commit comments