1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
crate::ix!();
pub type FillableSigningProviderKeyMap = HashMap<KeyID,Key>;
pub type FillableSigningProviderScriptMap = HashMap<ScriptID,Script>;
/**
| Fillable signing provider that keeps
| keys in an address->secret map
|
*/
pub struct FillableSigningProvider<T> {
base: SigningProvider,
cs_key_store: Arc<Mutex<FillableSigningProviderInner<T>>>,
}
pub struct FillableSigningProviderInner<T> {
/**
| Map of key id to unencrypted private
| keys known by the signing provider.
|
| Map may be empty if the provider has another
| source of keys, like an encrypted store.
|
*/
map_keys: FillableSigningProviderKeyMap,
/**
| Map of script id to scripts known by the
| signing provider.
|
| This map originally just held P2SH
| redeemScripts, and was used by wallet
| code to look up script ids referenced in
| "OP_HASH160 <script id> OP_EQUAL" P2SH
| outputs.
|
| Later in 605e8473a7d it was extended to
| hold P2WSH witnessScripts as well, and
| used to look up nested scripts
| referenced in "OP_0 <script hash>" P2WSH
| outputs.
|
| Later in commits f4691ab3a9d and
| 248f3a76a82, it was extended once again
| to hold segwit "OP_0 <key or script
| hash>" scriptPubKeys, in order to give
| the wallet a way to distinguish between
| segwit outputs that it generated
| addresses for and wanted to receive
| payments from, and segwit outputs that
| it never generated addresses for, but it
| could spend just because of having keys.
|
| (Before segwit activation it was also
| important to not treat segwit outputs to
| arbitrary wallet keys as payments,
| because these could be spent by anyone
| without even needing to sign with the
| keys.)
|
| Some of the scripts stored in mapScripts
| are memory-only and intentionally not
| saved to disk.
|
| Specifically, scripts added by
| ImplicitlyLearnRelatedKeyScripts(pubkey)
| calls are not written to disk so future
| wallet code can have flexibility to be
| more selective about what transaction
| outputs it recognizes as payments,
| instead of having to treat all outputs
| spending to keys it knows as payments.
|
| By contrast, mapScripts entries added by
| AddCScript(script),
|
| LearnRelatedScripts(pubkey, type), and
| LearnAllRelatedScripts(pubkey) calls are
| saved because they are all intentionally
| used to receive payments.
|
| The FillableSigningProvider::mapScripts
| script map should not be confused with
| LegacyScriptPubKeyMan::setWatchOnly
| script set.
|
| The two collections can hold the same
| scripts, but they serve different
| purposes.
|
| The setWatchOnly script set is intended
| to expand the set of outputs the wallet
| considers payments.
|
| Every output with a script it contains
| is considered to belong to the wallet,
| regardless of whether the script is
| solvable or signable.
|
| By contrast, the scripts in mapScripts
| are only used for solving, and to
| restrict which outputs are considered
| payments by the wallet.
|
| An output with a script in mapScripts,
| unlike setWatchOnly, is not
| automatically considered to belong
| to the wallet if it can't be solved
| and signed for.
|
*/
map_scripts: FillableSigningProviderScriptMap,
item: T,
}
impl<T> AddKey for FillableSigningProvider<T> {
fn add_key(&mut self, key: &Key) -> bool {
todo!();
/*
return AddKeyPubKey(key, key.GetPubKey());
*/
}
}
impl<T> FillableSigningProvider<T> {
#[EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)]
pub fn implicitly_learn_related_key_scripts(&mut self, pubkey: &PubKey) {
todo!();
/*
AssertLockHeld(cs_KeyStore);
CKeyID key_id = pubkey.GetID();
// This adds the redeemscripts necessary to detect P2WPKH and P2SH-P2WPKH
// outputs. Technically P2WPKH outputs don't have a redeemscript to be
// spent. However, our current IsMine logic requires the corresponding
// P2SH-P2WPKH redeemscript to be present in the wallet in order to accept
// payment even to P2WPKH outputs.
// Also note that having superfluous scripts in the keystore never hurts.
// They're only used to guide recursion in signing and IsMine logic - if
// a script is present but we can't do anything with it, it has no effect.
// "Implicitly" refers to fact that scripts are derived automatically from
// existing keys, and are present in memory, even without being explicitly
// loaded (e.g. from a file).
if (pubkey.IsCompressed()) {
CScript script = GetScriptForDestination(WitnessV0KeyHash(key_id));
// This does not use AddCScript, as it may be overridden.
CScriptID id(script);
mapScripts[id] = std::move(script);
}
*/
}
pub fn get_pub_key(&self,
address: &KeyID,
vch_pub_key_out: &mut PubKey) -> bool {
todo!();
/*
CKey key;
if (!GetKey(address, key)) {
return false;
}
vchPubKeyOut = key.GetPubKey();
return true;
*/
}
pub fn add_key_pub_key(&mut self,
key: &Key,
pubkey: &PubKey) -> bool {
todo!();
/*
LOCK(cs_KeyStore);
mapKeys[pubkey.GetID()] = key;
ImplicitlyLearnRelatedKeyScripts(pubkey);
return true;
*/
}
pub fn have_key(&self, address: &KeyID) -> bool {
todo!();
/*
LOCK(cs_KeyStore);
return mapKeys.count(address) > 0;
*/
}
pub fn get_keys(&self) -> HashSet<KeyID> {
todo!();
/*
LOCK(cs_KeyStore);
std::set<CKeyID> set_address;
for (const auto& mi : mapKeys) {
set_address.insert(mi.first);
}
return set_address;
*/
}
pub fn get_key(&self,
address: &KeyID,
key_out: &mut Key) -> bool {
todo!();
/*
LOCK(cs_KeyStore);
KeyMap::const_iterator mi = mapKeys.find(address);
if (mi != mapKeys.end()) {
keyOut = mi->second;
return true;
}
return false;
*/
}
pub fn add_script(&mut self, redeem_script: &Script) -> bool {
todo!();
/*
if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
return error("FillableSigningProvider::AddCScript(): redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE);
LOCK(cs_KeyStore);
mapScripts[CScriptID(redeemScript)] = redeemScript;
return true;
*/
}
pub fn have_script(&self, hash: &ScriptID) -> bool {
todo!();
/*
LOCK(cs_KeyStore);
return mapScripts.count(hash) > 0;
*/
}
pub fn get_scripts(&self) -> HashSet<ScriptID> {
todo!();
/*
LOCK(cs_KeyStore);
std::set<CScriptID> set_script;
for (const auto& mi : mapScripts) {
set_script.insert(mi.first);
}
return set_script;
*/
}
pub fn get_script(&self,
hash: &ScriptID,
redeem_script_out: &mut Script) -> bool {
todo!();
/*
LOCK(cs_KeyStore);
ScriptMap::const_iterator mi = mapScripts.find(hash);
if (mi != mapScripts.end())
{
redeemScriptOut = (*mi).second;
return true;
}
return false;
*/
}
}