@@ -33,14 +33,61 @@ 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.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.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+ auto i = sigdata.signatures .emplace (keyid, SigPair (pubkey, sig_out));
77+ assert (i.second );
78+ return true ;
79+ }
80+ return false ;
81+ }
82+
3683/* *
3784 * Sign scriptPubKey using signature made with creator.
3885 * Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
3986 * unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script.
4087 * Returns false if scriptPubKey could not be completely satisfied.
4188 */
4289static bool SignStep (const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey,
43- std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion)
90+ std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion, SignatureData& sigdata )
4491{
4592 CScript scriptRet;
4693 uint160 h160;
@@ -58,20 +105,20 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
58105 case TX_WITNESS_UNKNOWN:
59106 return false ;
60107 case TX_PUBKEY:
61- 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 ;
62109 ret.push_back (std::move (sig));
63110 return true ;
64111 case TX_PUBKEYHASH: {
65112 CKeyID keyID = CKeyID (uint160 (vSolutions[0 ]));
66- if (!creator. CreateSig (provider, sig, keyID, scriptPubKey, sigversion)) return false ;
113+ if (!CreateSig (creator, sigdata, provider, sig, keyID, scriptPubKey, sigversion)) return false ;
67114 ret.push_back (std::move (sig));
68115 CPubKey pubkey;
69- provider. GetPubKey (keyID, pubkey);
116+ GetPubKey (provider, sigdata, keyID, pubkey);
70117 ret.push_back (ToByteVector (pubkey));
71118 return true ;
72119 }
73120 case TX_SCRIPTHASH:
74- if (provider. GetCScript (uint160 (vSolutions[0 ]), scriptRet)) {
121+ if (GetCScript (provider, sigdata, uint160 (vSolutions[0 ]), scriptRet)) {
75122 ret.push_back (std::vector<unsigned char >(scriptRet.begin (), scriptRet.end ()));
76123 return true ;
77124 }
@@ -82,7 +129,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
82129 ret.push_back (valtype ()); // workaround CHECKMULTISIG bug
83130 for (size_t i = 1 ; i < vSolutions.size () - 1 ; ++i) {
84131 CPubKey pubkey = CPubKey (vSolutions[i]);
85- 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)) {
86133 ret.push_back (std::move (sig));
87134 }
88135 }
@@ -98,7 +145,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
98145
99146 case TX_WITNESS_V0_SCRIPTHASH:
100147 CRIPEMD160 ().Write (&vSolutions[0 ][0 ], vSolutions[0 ].size ()).Finalize (h160.begin ());
101- if (provider. GetCScript (h160, scriptRet)) {
148+ if (GetCScript (provider, sigdata, h160, scriptRet)) {
102149 ret.push_back (std::vector<unsigned char >(scriptRet.begin (), scriptRet.end ()));
103150 return true ;
104151 }
@@ -130,7 +177,7 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
130177
131178 std::vector<valtype> result;
132179 txnouttype whichType;
133- bool solved = SignStep (provider, creator, fromPubKey, result, whichType, SigVersion::BASE);
180+ bool solved = SignStep (provider, creator, fromPubKey, result, whichType, SigVersion::BASE, sigdata );
134181 bool P2SH = false ;
135182 CScript subscript;
136183 sigdata.scriptWitness .stack .clear ();
@@ -141,7 +188,8 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
141188 // the final scriptSig is the signatures from that
142189 // and then the serialized subscript:
143190 subscript = CScript (result[0 ].begin (), result[0 ].end ());
144- 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;
145193 P2SH = true ;
146194 }
147195
@@ -150,15 +198,16 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
150198 CScript witnessscript;
151199 witnessscript << OP_DUP << OP_HASH160 << ToByteVector (result[0 ]) << OP_EQUALVERIFY << OP_CHECKSIG;
152200 txnouttype subType;
153- solved = solved && SignStep (provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0);
201+ solved = solved && SignStep (provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0, sigdata );
154202 sigdata.scriptWitness .stack = result;
155203 result.clear ();
156204 }
157205 else if (solved && whichType == TX_WITNESS_V0_SCRIPTHASH)
158206 {
159207 CScript witnessscript (result[0 ].begin (), result[0 ].end ());
208+ sigdata.witness_script = witnessscript;
160209 txnouttype subType;
161- 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;
162211 result.push_back (std::vector<unsigned char >(witnessscript.begin (), witnessscript.end ()));
163212 sigdata.scriptWitness .stack = result;
164213 result.clear ();
@@ -290,6 +339,22 @@ void UpdateInput(CTxIn& input, const SignatureData& data)
290339 input.scriptWitness = data.scriptWitness ;
291340}
292341
342+ void SignatureData::MergeSignatureData (SignatureData sigdata)
343+ {
344+ if (complete) return ;
345+ if (sigdata.complete ) {
346+ *this = std::move (sigdata);
347+ return ;
348+ }
349+ if (redeem_script.empty () && !sigdata.redeem_script .empty ()) {
350+ redeem_script = sigdata.redeem_script ;
351+ }
352+ if (witness_script.empty () && !sigdata.witness_script .empty ()) {
353+ witness_script = sigdata.witness_script ;
354+ }
355+ signatures.insert (std::make_move_iterator (sigdata.signatures .begin ()), std::make_move_iterator (sigdata.signatures .end ()));
356+ }
357+
293358bool SignSignature (const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType)
294359{
295360 assert (nIn < txTo.vin .size ());
@@ -485,6 +550,7 @@ class DummySignatureCreator final : public BaseSignatureCreator {
485550}
486551
487552const BaseSignatureCreator& DUMMY_SIGNATURE_CREATOR = DummySignatureCreator();
553+ const SigningProvider& DUMMY_SIGNING_PROVIDER = SigningProvider();
488554
489555bool IsSolvable (const SigningProvider& provider, const CScript& script)
490556{
0 commit comments