@@ -33,14 +33,60 @@ bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provid
3333 return true ;
3434}
3535
36+ static bool GetCScript (const SigningProvider* provider, const SignatureData* sigdata, const CScriptID &scriptid, CScript& script)
37+ {
38+ if (provider != nullptr && provider->GetCScript (scriptid, script)) {
39+ return true ;
40+ }
41+ // Look for scripts in SignatureData
42+ if (CScriptID (sigdata->redeem_script ) == scriptid) {
43+ script = sigdata->redeem_script ;
44+ return true ;
45+ } else if (CScriptID (sigdata->witness_script ) == scriptid) {
46+ script = sigdata->witness_script ;
47+ return true ;
48+ }
49+ return false ;
50+ }
51+
52+ static bool GetPubKey (const SigningProvider* provider, const SignatureData* sigdata, const CKeyID &address, CPubKey& pubkey)
53+ {
54+ if (provider != nullptr && provider->GetPubKey (address, pubkey)) {
55+ return true ;
56+ }
57+ // Look for pubkey in all partial sigs
58+ const auto & it = sigdata->signatures .find (address);
59+ if (it != sigdata->signatures .end ()) {
60+ pubkey = it->second .first ;
61+ return true ;
62+ }
63+ return false ;
64+ }
65+
66+ static bool CreateSig (const BaseSignatureCreator& creator, SignatureData& sigdata, const SigningProvider& provider, std::vector<unsigned char >& sig_out, const CKeyID& keyid, const CScript& scriptcode, SigVersion sigversion)
67+ {
68+ const auto & it = sigdata.signatures .find (keyid);
69+ if (it != sigdata.signatures .end ()) {
70+ sig_out = it->second .second ;
71+ return true ;
72+ }
73+ if (creator.CreateSig (provider, sig_out, keyid, scriptcode, sigversion)) {
74+ CPubKey pubkey;
75+ GetPubKey (&provider, &sigdata, keyid, pubkey);
76+ sigdata.signatures .emplace (keyid, SigPair (pubkey, sig_out));
77+ return true ;
78+ }
79+ return false ;
80+ }
81+
3682/* *
3783 * Sign scriptPubKey using signature made with creator.
3884 * Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
3985 * unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script.
4086 * Returns false if scriptPubKey could not be completely satisfied.
4187 */
4288static bool SignStep (const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey,
43- std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion)
89+ std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion, SignatureData& sigdata )
4490{
4591 CScript scriptRet;
4692 uint160 h160;
@@ -59,20 +105,20 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
59105 case TX_WITNESS_UNKNOWN:
60106 return false ;
61107 case TX_PUBKEY:
62- if (!creator. CreateSig (provider, sig, CPubKey (vSolutions[0 ]).GetID (), scriptPubKey, sigversion)) return false ;
108+ if (!CreateSig (creator, sigdata, provider, sig, CPubKey (vSolutions[0 ]).GetID (), scriptPubKey, sigversion)) return false ;
63109 ret.push_back (std::move (sig));
64110 return true ;
65111 case TX_PUBKEYHASH: {
66112 keyID = CKeyID (uint160 (vSolutions[0 ]));
67- if (!creator. CreateSig (provider, sig, keyID, scriptPubKey, sigversion)) return false ;
113+ if (!CreateSig (creator, sigdata, provider, sig, keyID, scriptPubKey, sigversion)) return false ;
68114 ret.push_back (std::move (sig));
69115 CPubKey pubkey;
70- provider. GetPubKey (keyID, pubkey);
116+ GetPubKey (&provider, &sigdata, keyID, pubkey);
71117 ret.push_back (ToByteVector (pubkey));
72118 return true ;
73119 }
74120 case TX_SCRIPTHASH:
75- if (provider. GetCScript (uint160 (vSolutions[0 ]), scriptRet)) {
121+ if (GetCScript (&provider, &sigdata, uint160 (vSolutions[0 ]), scriptRet)) {
76122 ret.push_back (std::vector<unsigned char >(scriptRet.begin (), scriptRet.end ()));
77123 return true ;
78124 }
@@ -83,7 +129,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
83129 ret.push_back (valtype ()); // workaround CHECKMULTISIG bug
84130 for (size_t i = 1 ; i < vSolutions.size () - 1 ; ++i) {
85131 CPubKey pubkey = CPubKey (vSolutions[i]);
86- if (ret.size () < required + 1 && creator. CreateSig (provider, sig, pubkey.GetID (), scriptPubKey, sigversion)) {
132+ if (ret.size () < required + 1 && CreateSig (creator, sigdata, provider, sig, pubkey.GetID (), scriptPubKey, sigversion)) {
87133 ret.push_back (std::move (sig));
88134 }
89135 }
@@ -99,7 +145,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
99145
100146 case TX_WITNESS_V0_SCRIPTHASH:
101147 CRIPEMD160 ().Write (&vSolutions[0 ][0 ], vSolutions[0 ].size ()).Finalize (h160.begin ());
102- if (provider. GetCScript (h160, scriptRet)) {
148+ if (GetCScript (&provider, &sigdata, h160, scriptRet)) {
103149 ret.push_back (std::vector<unsigned char >(scriptRet.begin (), scriptRet.end ()));
104150 return true ;
105151 }
@@ -131,7 +177,7 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
131177
132178 std::vector<valtype> result;
133179 txnouttype whichType;
134- bool solved = SignStep (provider, creator, fromPubKey, result, whichType, SigVersion::BASE);
180+ bool solved = SignStep (provider, creator, fromPubKey, result, whichType, SigVersion::BASE, sigdata );
135181 bool P2SH = false ;
136182 CScript subscript;
137183 sigdata.scriptWitness .stack .clear ();
@@ -142,7 +188,8 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
142188 // the final scriptSig is the signatures from that
143189 // and then the serialized subscript:
144190 subscript = CScript (result[0 ].begin (), result[0 ].end ());
145- solved = solved && SignStep (provider, creator, subscript, result, whichType, SigVersion::BASE) && whichType != TX_SCRIPTHASH;
191+ sigdata.redeem_script = subscript;
192+ solved = solved && SignStep (provider, creator, subscript, result, whichType, SigVersion::BASE, sigdata) && whichType != TX_SCRIPTHASH;
146193 P2SH = true ;
147194 }
148195
@@ -151,15 +198,16 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
151198 CScript witnessscript;
152199 witnessscript << OP_DUP << OP_HASH160 << ToByteVector (result[0 ]) << OP_EQUALVERIFY << OP_CHECKSIG;
153200 txnouttype subType;
154- solved = solved && SignStep (provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0);
201+ solved = solved && SignStep (provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0, sigdata );
155202 sigdata.scriptWitness .stack = result;
156203 result.clear ();
157204 }
158205 else if (solved && whichType == TX_WITNESS_V0_SCRIPTHASH)
159206 {
160207 CScript witnessscript (result[0 ].begin (), result[0 ].end ());
208+ sigdata.witness_script = witnessscript;
161209 txnouttype subType;
162- solved = solved && SignStep (provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0) && subType != TX_SCRIPTHASH && subType != TX_WITNESS_V0_SCRIPTHASH && subType != TX_WITNESS_V0_KEYHASH;
210+ solved = solved && SignStep (provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0, sigdata ) && subType != TX_SCRIPTHASH && subType != TX_WITNESS_V0_SCRIPTHASH && subType != TX_WITNESS_V0_KEYHASH;
163211 result.push_back (std::vector<unsigned char >(witnessscript.begin (), witnessscript.end ()));
164212 sigdata.scriptWitness .stack = result;
165213 result.clear ();
@@ -491,6 +539,7 @@ class DummySignatureCreator final : public BaseSignatureCreator {
491539}
492540
493541const BaseSignatureCreator& DUMMY_SIGNATURE_CREATOR = DummySignatureCreator();
542+ const SigningProvider& DUMMY_SIGNING_PROVIDER = SigningProvider();
494543
495544bool IsSolvable (const SigningProvider& provider, const CScript& script)
496545{
0 commit comments