@ -481,11 +481,11 @@ class DescriptorImpl : public Descriptor
const std : : string m_name ;
protected :
//! The sub-descriptor argument (nullptr for everything but SH and WSH).
//! The sub-descriptor argument s (empty for everything but SH and WSH).
//! In doc/descriptors.m this is referred to as SCRIPT expressions sh(SCRIPT)
//! and wsh(SCRIPT), and distinct from KEY expressions and ADDR expressions.
//! Subdescriptors can only ever generate a single script.
const std : : unique_ptr< DescriptorImpl > m_subdescriptor_arg ;
const std : : vector< std : : unique_ptr< DescriptorImpl > > m_subdescriptor_arg s ;
//! Return a serialization of anything except pubkey and script arguments, to be prepended to those.
virtual std : : string ToStringExtra ( ) const { return " " ; }
@ -493,22 +493,23 @@ protected:
/** A helper function to construct the scripts for this descriptor.
*
* This function is invoked once by ExpandHelper .
*
* @ param pubkeys The evaluations of the m_pubkey_args field .
* @ param script The evaluation of m_subdescriptor_arg ( or nullptr when m_subdescriptor_arg is nullptr ) .
* @ param script The evaluation s of m_subdescriptor_args ( one for each m_subdescriptor_args element ) .
* @ param out A FlatSigningProvider to put scripts or public keys in that are necessary to the solver .
* The origin info of the provided pubkeys is automatically added .
* @ return A vector with scriptPubKeys for this descriptor .
*/
virtual std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & pubkeys , const CScript * script , FlatSigningProvider & out ) const = 0 ;
virtual std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & pubkeys , Span < const CScript > scripts , FlatSigningProvider & out ) const = 0 ;
public :
DescriptorImpl ( std : : vector < std : : unique_ptr < PubkeyProvider > > pubkeys , std : : unique_ptr < DescriptorImpl > script , const std : : string & name ) : m_pubkey_args ( std : : move ( pubkeys ) ) , m_name ( name ) , m_subdescriptor_arg ( std : : move ( script ) ) { }
DescriptorImpl ( std : : vector < std : : unique_ptr < PubkeyProvider > > pubkeys , const std : : string & name ) : m_pubkey_args ( std : : move ( pubkeys ) ) , m_name ( name ) , m_subdescriptor_args ( ) { }
DescriptorImpl ( std : : vector < std : : unique_ptr < PubkeyProvider > > pubkeys , std : : unique_ptr < DescriptorImpl > script , const std : : string & name ) : m_pubkey_args ( std : : move ( pubkeys ) ) , m_name ( name ) , m_subdescriptor_args ( Vector ( std : : move ( script ) ) ) { }
bool IsSolvable ( ) const override
{
i f ( m_subdescriptor_arg ) {
if ( ! m_subdescriptor_ arg- > IsSolvable ( ) ) return false ;
for ( const auto & arg : m_subdescriptor_arg s ) {
if ( ! arg- > IsSolvable ( ) ) return false ;
}
return true ;
}
@ -518,8 +519,8 @@ public:
for ( const auto & pubkey : m_pubkey_args ) {
if ( pubkey - > IsRange ( ) ) return true ;
}
i f ( m_subdescriptor_arg ) {
if ( m_subdescriptor_ arg- > IsRange ( ) ) return true ;
for ( const auto & arg : m_subdescriptor_arg s ) {
if ( arg- > IsRange ( ) ) return true ;
}
return false ;
}
@ -541,10 +542,10 @@ public:
}
ret + = std : : move ( tmp ) ;
}
i f ( m_subdescriptor_arg ) {
for ( const auto & scriptarg : m_subdescriptor_arg s ) {
if ( pos + + ) ret + = " , " ;
std : : string tmp ;
if ( ! m_subde scriptor_ arg- > ToStringHelper ( arg , tmp , priv , normalized ) ) return false ;
if ( ! scriptarg- > ToStringHelper ( arg , tmp , priv , normalized ) ) return false ;
ret + = std : : move ( tmp ) ;
}
out = std : : move ( ret ) + " ) " ;
@ -577,18 +578,20 @@ public:
std : : vector < std : : pair < CPubKey , KeyOriginInfo > > entries ;
entries . reserve ( m_pubkey_args . size ( ) ) ;
// Construct temporary data in `entries` and `subscripts`, to avoid producing output in case of failure.
// Construct temporary data in `entries` , `subscripts`, and `subprovider` to avoid producing output in case of failure.
for ( const auto & p : m_pubkey_args ) {
entries . emplace_back ( ) ;
if ( ! p - > GetPubKey ( pos , arg , entries . back ( ) . first , entries . back ( ) . second , read_cache , write_cache ) ) return false ;
}
std : : vector < CScript > subscripts ;
if ( m_subdescriptor_arg ) {
FlatSigningProvider subprovider ;
if ( ! m_subdescriptor_arg - > ExpandHelper ( pos , arg , read_cache , subscripts , subprovider , write_cache ) ) return false ;
assert ( subscripts . size ( ) = = 1 ) ;
out = Merge ( out , subprovider ) ;
FlatSigningProvider subprovider ;
for ( const auto & subarg : m_subdescriptor_args ) {
std : : vector < CScript > outscripts ;
if ( ! subarg - > ExpandHelper ( pos , arg , read_cache , outscripts , subprovider , write_cache ) ) return false ;
assert ( outscripts . size ( ) = = 1 ) ;
subscripts . emplace_back ( std : : move ( outscripts [ 0 ] ) ) ;
}
out = Merge ( std : : move ( out ) , std : : move ( subprovider ) ) ;
std : : vector < CPubKey > pubkeys ;
pubkeys . reserve ( entries . size ( ) ) ;
@ -596,11 +599,8 @@ public:
pubkeys . push_back ( entry . first ) ;
out . origins . emplace ( entry . first . GetID ( ) , std : : make_pair < CPubKey , KeyOriginInfo > ( CPubKey ( entry . first ) , std : : move ( entry . second ) ) ) ;
}
if ( m_subdescriptor_arg ) {
output_scripts = MakeScripts ( pubkeys , & subscripts [ 0 ] , out ) ;
} else {
output_scripts = MakeScripts ( pubkeys , nullptr , out ) ;
}
output_scripts = MakeScripts ( pubkeys , MakeSpan ( subscripts ) , out ) ;
return true ;
}
@ -621,10 +621,8 @@ public:
if ( ! p - > GetPrivKey ( pos , provider , key ) ) continue ;
out . keys . emplace ( key . GetPubKey ( ) . GetID ( ) , key ) ;
}
if ( m_subdescriptor_arg ) {
FlatSigningProvider subprovider ;
m_subdescriptor_arg - > ExpandPrivate ( pos , provider , subprovider ) ;
out = Merge ( out , subprovider ) ;
for ( const auto & arg : m_subdescriptor_args ) {
arg - > ExpandPrivate ( pos , provider , out ) ;
}
}
@ -637,9 +635,9 @@ class AddressDescriptor final : public DescriptorImpl
const CTxDestination m_destination ;
protected :
std : : string ToStringExtra ( ) const override { return EncodeDestination ( m_destination ) ; }
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & , const CScript * , FlatSigningProvider & ) const override { return Vector ( GetScriptForDestination ( m_destination ) ) ; }
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & , Span < const CScript > , FlatSigningProvider & ) const override { return Vector ( GetScriptForDestination ( m_destination ) ) ; }
public :
AddressDescriptor ( CTxDestination destination ) : DescriptorImpl ( { } , { } , " addr " ) , m_destination ( std : : move ( destination ) ) { }
AddressDescriptor ( CTxDestination destination ) : DescriptorImpl ( { } , " addr " ) , m_destination ( std : : move ( destination ) ) { }
bool IsSolvable ( ) const final { return false ; }
std : : optional < OutputType > GetOutputType ( ) const override
@ -663,9 +661,9 @@ class RawDescriptor final : public DescriptorImpl
const CScript m_script ;
protected :
std : : string ToStringExtra ( ) const override { return HexStr ( m_script ) ; }
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & , const CScript * , FlatSigningProvider & ) const override { return Vector ( m_script ) ; }
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & , Span < const CScript > , FlatSigningProvider & ) const override { return Vector ( m_script ) ; }
public :
RawDescriptor ( CScript script ) : DescriptorImpl ( { } , { } , " raw " ) , m_script ( std : : move ( script ) ) { }
RawDescriptor ( CScript script ) : DescriptorImpl ( { } , " raw " ) , m_script ( std : : move ( script ) ) { }
bool IsSolvable ( ) const final { return false ; }
std : : optional < OutputType > GetOutputType ( ) const override
@ -689,9 +687,9 @@ public:
class PKDescriptor final : public DescriptorImpl
{
protected :
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & keys , const CScript * , FlatSigningProvider & ) const override { return Vector ( GetScriptForRawPubKey ( keys [ 0 ] ) ) ; }
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & keys , Span < const CScript > , FlatSigningProvider & ) const override { return Vector ( GetScriptForRawPubKey ( keys [ 0 ] ) ) ; }
public :
PKDescriptor ( std : : unique_ptr < PubkeyProvider > prov ) : DescriptorImpl ( Vector ( std : : move ( prov ) ) , { } , " pk " ) { }
PKDescriptor ( std : : unique_ptr < PubkeyProvider > prov ) : DescriptorImpl ( Vector ( std : : move ( prov ) ) , " pk " ) { }
bool IsSingleType ( ) const final { return true ; }
} ;
@ -699,14 +697,14 @@ public:
class PKHDescriptor final : public DescriptorImpl
{
protected :
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & keys , const CScript * , FlatSigningProvider & out ) const override
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & keys , Span < const CScript > , FlatSigningProvider & out ) const override
{
CKeyID id = keys [ 0 ] . GetID ( ) ;
out . pubkeys . emplace ( id , keys [ 0 ] ) ;
return Vector ( GetScriptForDestination ( PKHash ( id ) ) ) ;
}
public :
PKHDescriptor ( std : : unique_ptr < PubkeyProvider > prov ) : DescriptorImpl ( Vector ( std : : move ( prov ) ) , { } , " pkh " ) { }
PKHDescriptor ( std : : unique_ptr < PubkeyProvider > prov ) : DescriptorImpl ( Vector ( std : : move ( prov ) ) , " pkh " ) { }
std : : optional < OutputType > GetOutputType ( ) const override { return OutputType : : LEGACY ; }
bool IsSingleType ( ) const final { return true ; }
} ;
@ -715,14 +713,14 @@ public:
class WPKHDescriptor final : public DescriptorImpl
{
protected :
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & keys , const CScript * , FlatSigningProvider & out ) const override
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & keys , Span < const CScript > , FlatSigningProvider & out ) const override
{
CKeyID id = keys [ 0 ] . GetID ( ) ;
out . pubkeys . emplace ( id , keys [ 0 ] ) ;
return Vector ( GetScriptForDestination ( WitnessV0KeyHash ( id ) ) ) ;
}
public :
WPKHDescriptor ( std : : unique_ptr < PubkeyProvider > prov ) : DescriptorImpl ( Vector ( std : : move ( prov ) ) , { } , " wpkh " ) { }
WPKHDescriptor ( std : : unique_ptr < PubkeyProvider > prov ) : DescriptorImpl ( Vector ( std : : move ( prov ) ) , " wpkh " ) { }
std : : optional < OutputType > GetOutputType ( ) const override { return OutputType : : BECH32 ; }
bool IsSingleType ( ) const final { return true ; }
} ;
@ -731,7 +729,7 @@ public:
class ComboDescriptor final : public DescriptorImpl
{
protected :
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & keys , const CScript * , FlatSigningProvider & out ) const override
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & keys , Span < const CScript > , FlatSigningProvider & out ) const override
{
std : : vector < CScript > ret ;
CKeyID id = keys [ 0 ] . GetID ( ) ;
@ -747,7 +745,7 @@ protected:
return ret ;
}
public :
ComboDescriptor ( std : : unique_ptr < PubkeyProvider > prov ) : DescriptorImpl ( Vector ( std : : move ( prov ) ) , { } , " combo " ) { }
ComboDescriptor ( std : : unique_ptr < PubkeyProvider > prov ) : DescriptorImpl ( Vector ( std : : move ( prov ) ) , " combo " ) { }
bool IsSingleType ( ) const final { return false ; }
} ;
@ -758,7 +756,7 @@ class MultisigDescriptor final : public DescriptorImpl
const bool m_sorted ;
protected :
std : : string ToStringExtra ( ) const override { return strprintf ( " %i " , m_threshold ) ; }
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & keys , const CScript * , FlatSigningProvider & ) const override {
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & keys , Span < const CScript > , FlatSigningProvider & ) const override {
if ( m_sorted ) {
std : : vector < CPubKey > sorted_keys ( keys ) ;
std : : sort ( sorted_keys . begin ( ) , sorted_keys . end ( ) ) ;
@ -767,7 +765,7 @@ protected:
return Vector ( GetScriptForMultisig ( m_threshold , keys ) ) ;
}
public :
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 ) { }
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 ) { }
bool IsSingleType ( ) const final { return true ; }
} ;
@ -775,10 +773,10 @@ public:
class SHDescriptor final : public DescriptorImpl
{
protected :
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & , const CScript * script , FlatSigningProvider & out ) const override
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & , Span < const CScript > scripts , FlatSigningProvider & out ) const override
{
auto ret = Vector ( GetScriptForDestination ( ScriptHash ( * script ) ) ) ;
if ( ret . size ( ) ) out . scripts . emplace ( CScriptID ( * script ) , * script ) ;
auto ret = Vector ( GetScriptForDestination ( ScriptHash ( script s[ 0 ] ) ) ) ;
if ( ret . size ( ) ) out . scripts . emplace ( CScriptID ( script s[ 0 ] ) , script s[ 0 ] ) ;
return ret ;
}
public :
@ -786,8 +784,8 @@ public:
std : : optional < OutputType > GetOutputType ( ) const override
{
assert ( m_subdescriptor_arg ) ;
if ( m_subdescriptor_arg - > GetOutputType ( ) = = OutputType : : BECH32 ) return OutputType : : P2SH_SEGWIT ;
assert ( m_subdescriptor_arg s. size ( ) = = 1 ) ;
if ( m_subdescriptor_arg s[ 0 ] - > GetOutputType ( ) = = OutputType : : BECH32 ) return OutputType : : P2SH_SEGWIT ;
return OutputType : : LEGACY ;
}
bool IsSingleType ( ) const final { return true ; }
@ -797,10 +795,10 @@ public:
class WSHDescriptor final : public DescriptorImpl
{
protected :
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & , const CScript * script , FlatSigningProvider & out ) const override
std : : vector < CScript > MakeScripts ( const std : : vector < CPubKey > & , Span < const CScript > scripts , FlatSigningProvider & out ) const override
{
auto ret = Vector ( GetScriptForDestination ( WitnessV0ScriptHash ( * script ) ) ) ;
if ( ret . size ( ) ) out . scripts . emplace ( CScriptID ( * script ) , * script ) ;
auto ret = Vector ( GetScriptForDestination ( WitnessV0ScriptHash ( script s[ 0 ] ) ) ) ;
if ( ret . size ( ) ) out . scripts . emplace ( CScriptID ( script s[ 0 ] ) , script s[ 0 ] ) ;
return ret ;
}
public :