@@ -33,14 +33,61 @@ bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provid
33
33
return true ;
34
34
}
35
35
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
+
36
83
/* *
37
84
* Sign scriptPubKey using signature made with creator.
38
85
* Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
39
86
* unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script.
40
87
* Returns false if scriptPubKey could not be completely satisfied.
41
88
*/
42
89
static 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 )
44
91
{
45
92
CScript scriptRet;
46
93
uint160 h160;
@@ -58,20 +105,20 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
58
105
case TX_WITNESS_UNKNOWN:
59
106
return false ;
60
107
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 ;
62
109
ret.push_back (std::move (sig));
63
110
return true ;
64
111
case TX_PUBKEYHASH: {
65
112
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 ;
67
114
ret.push_back (std::move (sig));
68
115
CPubKey pubkey;
69
- provider. GetPubKey (keyID, pubkey);
116
+ GetPubKey (provider, sigdata, keyID, pubkey);
70
117
ret.push_back (ToByteVector (pubkey));
71
118
return true ;
72
119
}
73
120
case TX_SCRIPTHASH:
74
- if (provider. GetCScript (uint160 (vSolutions[0 ]), scriptRet)) {
121
+ if (GetCScript (provider, sigdata, uint160 (vSolutions[0 ]), scriptRet)) {
75
122
ret.push_back (std::vector<unsigned char >(scriptRet.begin (), scriptRet.end ()));
76
123
return true ;
77
124
}
@@ -82,7 +129,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
82
129
ret.push_back (valtype ()); // workaround CHECKMULTISIG bug
83
130
for (size_t i = 1 ; i < vSolutions.size () - 1 ; ++i) {
84
131
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)) {
86
133
ret.push_back (std::move (sig));
87
134
}
88
135
}
@@ -98,7 +145,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
98
145
99
146
case TX_WITNESS_V0_SCRIPTHASH:
100
147
CRIPEMD160 ().Write (&vSolutions[0 ][0 ], vSolutions[0 ].size ()).Finalize (h160.begin ());
101
- if (provider. GetCScript (h160, scriptRet)) {
148
+ if (GetCScript (provider, sigdata, h160, scriptRet)) {
102
149
ret.push_back (std::vector<unsigned char >(scriptRet.begin (), scriptRet.end ()));
103
150
return true ;
104
151
}
@@ -130,7 +177,7 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
130
177
131
178
std::vector<valtype> result;
132
179
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 );
134
181
bool P2SH = false ;
135
182
CScript subscript;
136
183
sigdata.scriptWitness .stack .clear ();
@@ -141,7 +188,8 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
141
188
// the final scriptSig is the signatures from that
142
189
// and then the serialized subscript:
143
190
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;
145
193
P2SH = true ;
146
194
}
147
195
@@ -150,15 +198,16 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
150
198
CScript witnessscript;
151
199
witnessscript << OP_DUP << OP_HASH160 << ToByteVector (result[0 ]) << OP_EQUALVERIFY << OP_CHECKSIG;
152
200
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 );
154
202
sigdata.scriptWitness .stack = result;
155
203
result.clear ();
156
204
}
157
205
else if (solved && whichType == TX_WITNESS_V0_SCRIPTHASH)
158
206
{
159
207
CScript witnessscript (result[0 ].begin (), result[0 ].end ());
208
+ sigdata.witness_script = witnessscript;
160
209
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;
162
211
result.push_back (std::vector<unsigned char >(witnessscript.begin (), witnessscript.end ()));
163
212
sigdata.scriptWitness .stack = result;
164
213
result.clear ();
@@ -290,6 +339,22 @@ void UpdateInput(CTxIn& input, const SignatureData& data)
290
339
input.scriptWitness = data.scriptWitness ;
291
340
}
292
341
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
+
293
358
bool SignSignature (const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType)
294
359
{
295
360
assert (nIn < txTo.vin .size ());
@@ -485,6 +550,7 @@ class DummySignatureCreator final : public BaseSignatureCreator {
485
550
}
486
551
487
552
const BaseSignatureCreator& DUMMY_SIGNATURE_CREATOR = DummySignatureCreator();
553
+ const SigningProvider& DUMMY_SIGNING_PROVIDER = SigningProvider();
488
554
489
555
bool IsSolvable (const SigningProvider& provider, const CScript& script)
490
556
{
0 commit comments