2222#include < util/vector.h>
2323
2424#include < memory>
25+ #include < numeric>
2526#include < optional>
2627#include < string>
2728#include < vector>
@@ -706,6 +707,19 @@ class DescriptorImpl : public Descriptor
706707 }
707708
708709 std::optional<OutputType> GetOutputType () const override { return std::nullopt ; }
710+
711+ std::optional<int64_t > ScriptSize () const override { return {}; }
712+
713+ /* * A helper for MaxSatisfactionWeight.
714+ *
715+ * @param use_max_sig Whether to assume ECDSA signatures will have a high-r.
716+ * @return The maximum size of the satisfaction in raw bytes (with no witness meaning).
717+ */
718+ virtual std::optional<int64_t > MaxSatSize (bool use_max_sig) const { return {}; }
719+
720+ std::optional<int64_t > MaxSatisfactionWeight (bool ) const override { return {}; }
721+
722+ std::optional<int64_t > MaxSatisfactionElems () const override { return {}; }
709723};
710724
711725/* * A parsed addr(A) descriptor. */
@@ -725,6 +739,8 @@ class AddressDescriptor final : public DescriptorImpl
725739 }
726740 bool IsSingleType () const final { return true ; }
727741 bool ToPrivateString (const SigningProvider& arg, std::string& out) const final { return false ; }
742+
743+ std::optional<int64_t > ScriptSize () const override { return GetScriptForDestination (m_destination).size (); }
728744};
729745
730746/* * A parsed raw(H) descriptor. */
@@ -746,6 +762,8 @@ class RawDescriptor final : public DescriptorImpl
746762 }
747763 bool IsSingleType () const final { return true ; }
748764 bool ToPrivateString (const SigningProvider& arg, std::string& out) const final { return false ; }
765+
766+ std::optional<int64_t > ScriptSize () const override { return m_script.size (); }
749767};
750768
751769/* * A parsed pk(P) descriptor. */
@@ -766,6 +784,21 @@ class PKDescriptor final : public DescriptorImpl
766784public:
767785 PKDescriptor (std::unique_ptr<PubkeyProvider> prov, bool xonly = false ) : DescriptorImpl(Vector(std::move(prov)), " pk" ), m_xonly(xonly) {}
768786 bool IsSingleType () const final { return true ; }
787+
788+ std::optional<int64_t > ScriptSize () const override {
789+ return 1 + (m_xonly ? 32 : m_pubkey_args[0 ]->GetSize ()) + 1 ;
790+ }
791+
792+ std::optional<int64_t > MaxSatSize (bool use_max_sig) const override {
793+ const auto ecdsa_sig_size = use_max_sig ? 72 : 71 ;
794+ return 1 + (m_xonly ? 65 : ecdsa_sig_size);
795+ }
796+
797+ std::optional<int64_t > MaxSatisfactionWeight (bool use_max_sig) const override {
798+ return *MaxSatSize (use_max_sig) * WITNESS_SCALE_FACTOR;
799+ }
800+
801+ std::optional<int64_t > MaxSatisfactionElems () const override { return 1 ; }
769802};
770803
771804/* * A parsed pkh(P) descriptor. */
@@ -782,6 +815,19 @@ class PKHDescriptor final : public DescriptorImpl
782815 PKHDescriptor (std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), " pkh" ) {}
783816 std::optional<OutputType> GetOutputType () const override { return OutputType::LEGACY; }
784817 bool IsSingleType () const final { return true ; }
818+
819+ std::optional<int64_t > ScriptSize () const override { return 1 + 1 + 1 + 20 + 1 + 1 ; }
820+
821+ std::optional<int64_t > MaxSatSize (bool use_max_sig) const override {
822+ const auto sig_size = use_max_sig ? 72 : 71 ;
823+ return 1 + sig_size + 1 + m_pubkey_args[0 ]->GetSize ();
824+ }
825+
826+ std::optional<int64_t > MaxSatisfactionWeight (bool use_max_sig) const override {
827+ return *MaxSatSize (use_max_sig) * WITNESS_SCALE_FACTOR;
828+ }
829+
830+ std::optional<int64_t > MaxSatisfactionElems () const override { return 2 ; }
785831};
786832
787833/* * A parsed wpkh(P) descriptor. */
@@ -798,6 +844,19 @@ class WPKHDescriptor final : public DescriptorImpl
798844 WPKHDescriptor (std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), " wpkh" ) {}
799845 std::optional<OutputType> GetOutputType () const override { return OutputType::BECH32; }
800846 bool IsSingleType () const final { return true ; }
847+
848+ std::optional<int64_t > ScriptSize () const override { return 1 + 1 + 20 ; }
849+
850+ std::optional<int64_t > MaxSatSize (bool use_max_sig) const override {
851+ const auto sig_size = use_max_sig ? 72 : 71 ;
852+ return (1 + sig_size + 1 + 33 );
853+ }
854+
855+ std::optional<int64_t > MaxSatisfactionWeight (bool use_max_sig) const override {
856+ return MaxSatSize (use_max_sig);
857+ }
858+
859+ std::optional<int64_t > MaxSatisfactionElems () const override { return 2 ; }
801860};
802861
803862/* * A parsed combo(P) descriptor. */
@@ -842,6 +901,24 @@ class MultisigDescriptor final : public DescriptorImpl
842901public:
843902 MultisigDescriptor (int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers, bool sorted = false ) : DescriptorImpl(std::move(providers), sorted ? " sortedmulti" : " multi" ), m_threshold(threshold), m_sorted(sorted) {}
844903 bool IsSingleType () const final { return true ; }
904+
905+ std::optional<int64_t > ScriptSize () const override {
906+ const auto n_keys = m_pubkey_args.size ();
907+ auto op = [](int64_t acc, const std::unique_ptr<PubkeyProvider>& pk) { return acc + 1 + pk->GetSize ();};
908+ const auto pubkeys_size{std::accumulate (m_pubkey_args.begin (), m_pubkey_args.end (), int64_t {0 }, op)};
909+ return 1 + BuildScript (n_keys).size () + BuildScript (m_threshold).size () + pubkeys_size;
910+ }
911+
912+ std::optional<int64_t > MaxSatSize (bool use_max_sig) const override {
913+ const auto sig_size = use_max_sig ? 72 : 71 ;
914+ return (1 + (1 + sig_size) * m_threshold);
915+ }
916+
917+ std::optional<int64_t > MaxSatisfactionWeight (bool use_max_sig) const override {
918+ return *MaxSatSize (use_max_sig) * WITNESS_SCALE_FACTOR;
919+ }
920+
921+ std::optional<int64_t > MaxSatisfactionElems () const override { return 1 + m_threshold; }
845922};
846923
847924/* * A parsed (sorted)multi_a(...) descriptor. Always uses x-only pubkeys. */
@@ -867,6 +944,17 @@ class MultiADescriptor final : public DescriptorImpl
867944public:
868945 MultiADescriptor (int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers, bool sorted = false ) : DescriptorImpl(std::move(providers), sorted ? " sortedmulti_a" : " multi_a" ), m_threshold(threshold), m_sorted(sorted) {}
869946 bool IsSingleType () const final { return true ; }
947+
948+ std::optional<int64_t > ScriptSize () const override {
949+ const auto n_keys = m_pubkey_args.size ();
950+ return (1 + 32 + 1 ) * n_keys + BuildScript (m_threshold).size () + 1 ;
951+ }
952+
953+ std::optional<int64_t > MaxSatSize (bool use_max_sig) const override {
954+ return (1 + 65 ) * m_threshold + (m_pubkey_args.size () - m_threshold);
955+ }
956+
957+ std::optional<int64_t > MaxSatisfactionElems () const override { return m_pubkey_args.size (); }
870958};
871959
872960/* * A parsed sh(...) descriptor. */
@@ -879,16 +967,39 @@ class SHDescriptor final : public DescriptorImpl
879967 if (ret.size ()) out.scripts .emplace (CScriptID (scripts[0 ]), scripts[0 ]);
880968 return ret;
881969 }
970+
971+ bool IsSegwit () const { return m_subdescriptor_args[0 ]->GetOutputType () == OutputType::BECH32; }
972+
882973public:
883974 SHDescriptor (std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), " sh" ) {}
884975
885976 std::optional<OutputType> GetOutputType () const override
886977 {
887978 assert (m_subdescriptor_args.size () == 1 );
888- if (m_subdescriptor_args[ 0 ]-> GetOutputType () == OutputType::BECH32 ) return OutputType::P2SH_SEGWIT;
979+ if (IsSegwit () ) return OutputType::P2SH_SEGWIT;
889980 return OutputType::LEGACY;
890981 }
891982 bool IsSingleType () const final { return true ; }
983+
984+ std::optional<int64_t > ScriptSize () const override { return 1 + 1 + 20 + 1 ; }
985+
986+ std::optional<int64_t > MaxSatisfactionWeight (bool use_max_sig) const override {
987+ if (const auto sat_size = m_subdescriptor_args[0 ]->MaxSatSize (use_max_sig)) {
988+ if (const auto subscript_size = m_subdescriptor_args[0 ]->ScriptSize ()) {
989+ // The subscript is never witness data.
990+ const auto subscript_weight = (1 + *subscript_size) * WITNESS_SCALE_FACTOR;
991+ // The weight depends on whether the inner descriptor is satisfied using the witness stack.
992+ if (IsSegwit ()) return subscript_weight + *sat_size;
993+ return subscript_weight + *sat_size * WITNESS_SCALE_FACTOR;
994+ }
995+ }
996+ return {};
997+ }
998+
999+ std::optional<int64_t > MaxSatisfactionElems () const override {
1000+ if (const auto sub_elems = m_subdescriptor_args[0 ]->MaxSatisfactionElems ()) return 1 + *sub_elems;
1001+ return {};
1002+ }
8921003};
8931004
8941005/* * A parsed wsh(...) descriptor. */
@@ -905,6 +1016,26 @@ class WSHDescriptor final : public DescriptorImpl
9051016 WSHDescriptor (std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), " wsh" ) {}
9061017 std::optional<OutputType> GetOutputType () const override { return OutputType::BECH32; }
9071018 bool IsSingleType () const final { return true ; }
1019+
1020+ std::optional<int64_t > ScriptSize () const override { return 1 + 1 + 32 ; }
1021+
1022+ std::optional<int64_t > MaxSatSize (bool use_max_sig) const override {
1023+ if (const auto sat_size = m_subdescriptor_args[0 ]->MaxSatSize (use_max_sig)) {
1024+ if (const auto subscript_size = m_subdescriptor_args[0 ]->ScriptSize ()) {
1025+ return GetSizeOfCompactSize (*subscript_size) + *subscript_size + *sat_size;
1026+ }
1027+ }
1028+ return {};
1029+ }
1030+
1031+ std::optional<int64_t > MaxSatisfactionWeight (bool use_max_sig) const override {
1032+ return MaxSatSize (use_max_sig);
1033+ }
1034+
1035+ std::optional<int64_t > MaxSatisfactionElems () const override {
1036+ if (const auto sub_elems = m_subdescriptor_args[0 ]->MaxSatisfactionElems ()) return 1 + *sub_elems;
1037+ return {};
1038+ }
9081039};
9091040
9101041/* * A parsed tr(...) descriptor. */
@@ -958,6 +1089,18 @@ class TRDescriptor final : public DescriptorImpl
9581089 }
9591090 std::optional<OutputType> GetOutputType () const override { return OutputType::BECH32M; }
9601091 bool IsSingleType () const final { return true ; }
1092+
1093+ std::optional<int64_t > ScriptSize () const override { return 1 + 1 + 32 ; }
1094+
1095+ std::optional<int64_t > MaxSatisfactionWeight (bool ) const override {
1096+ // FIXME: We assume keypath spend, which can lead to very large underestimations.
1097+ return 1 + 65 ;
1098+ }
1099+
1100+ std::optional<int64_t > MaxSatisfactionElems () const override {
1101+ // FIXME: See above, we assume keypath spend.
1102+ return 1 ;
1103+ }
9611104};
9621105
9631106/* We instantiate Miniscript here with a simple integer as key type.
@@ -1041,6 +1184,17 @@ class MiniscriptDescriptor final : public DescriptorImpl
10411184
10421185 bool IsSolvable () const override { return true ; }
10431186 bool IsSingleType () const final { return true ; }
1187+
1188+ std::optional<int64_t > ScriptSize () const override { return m_node->ScriptSize (); }
1189+
1190+ std::optional<int64_t > MaxSatSize (bool ) const override {
1191+ // For Miniscript we always assume high-R ECDSA signatures.
1192+ return m_node->GetWitnessSize ();
1193+ }
1194+
1195+ std::optional<int64_t > MaxSatisfactionElems () const override {
1196+ return m_node->GetStackSize ();
1197+ }
10441198};
10451199
10461200/* * A parsed rawtr(...) descriptor. */
@@ -1059,6 +1213,18 @@ class RawTRDescriptor final : public DescriptorImpl
10591213 RawTRDescriptor (std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(Vector(std::move(output_key)), " rawtr" ) {}
10601214 std::optional<OutputType> GetOutputType () const override { return OutputType::BECH32M; }
10611215 bool IsSingleType () const final { return true ; }
1216+
1217+ std::optional<int64_t > ScriptSize () const override { return 1 + 1 + 32 ; }
1218+
1219+ std::optional<int64_t > MaxSatisfactionWeight (bool ) const override {
1220+ // We can't know whether there is a script path, so assume key path spend.
1221+ return 1 + 65 ;
1222+ }
1223+
1224+ std::optional<int64_t > MaxSatisfactionElems () const override {
1225+ // See above, we assume keypath spend.
1226+ return 1 ;
1227+ }
10621228};
10631229
10641230// //////////////////////////////////////////////////////////////////////////
0 commit comments