Skip to content

Commit e7df1ec

Browse files
committed
Merge #14934: Descriptor expansion cache clarifications
2e68ffa [doc] descriptor: explain GetPubKey() usage with cached public key (Sjors Provoost) 2290269 scripted-diff: rename DescriptorImpl m_script_arg to m_subdescriptor_arg (Sjors Provoost) Pull request description: I found the name `m_script_arg` to be confusing while reviewing bitcoin/bitcoin#14646 (comment). @sipa let me know if `m_subdescriptor_arg` is completely wrong. I also added an explanation of why we call `GetPubKey` when we don't ask it for a public key. ACKs for top commit: laanwj: ACK 2e68ffa Tree-SHA512: 06698e9a91cdda93c043a82732793f0ad3cd91daa2513565953e9fa048d5573322fb534e9d0ea9ab736e6366be5921e2b8699c4f4b3693edab48039aaae06f78
2 parents 2863324 + 2e68ffa commit e7df1ec

File tree

2 files changed

+21
-17
lines changed

2 files changed

+21
-17
lines changed

src/script/descriptor.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -335,10 +335,12 @@ class BIP32PubkeyProvider final : public PubkeyProvider
335335
/** Base class for all Descriptor implementations. */
336336
class DescriptorImpl : public Descriptor
337337
{
338-
//! Public key arguments for this descriptor (size 1 for PK, PKH, WPKH; any size of Multisig).
338+
//! Public key arguments for this descriptor (size 1 for PK, PKH, WPKH; any size for Multisig).
339339
const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
340340
//! The sub-descriptor argument (nullptr for everything but SH and WSH).
341-
const std::unique_ptr<DescriptorImpl> m_script_arg;
341+
//! In doc/descriptors.m this is referred to as SCRIPT expressions sh(SCRIPT)
342+
//! and wsh(SCRIPT), and distinct from KEY expressions and ADDR expressions.
343+
const std::unique_ptr<DescriptorImpl> m_subdescriptor_arg;
342344
//! The string name of the descriptor function.
343345
const std::string m_name;
344346

@@ -349,23 +351,23 @@ class DescriptorImpl : public Descriptor
349351
/** A helper function to construct the scripts for this descriptor.
350352
*
351353
* This function is invoked once for every CScript produced by evaluating
352-
* m_script_arg, or just once in case m_script_arg is nullptr.
354+
* m_subdescriptor_arg, or just once in case m_subdescriptor_arg is nullptr.
353355
354356
* @param pubkeys The evaluations of the m_pubkey_args field.
355-
* @param script The evaluation of m_script_arg (or nullptr when m_script_arg is nullptr).
357+
* @param script The evaluation of m_subdescriptor_arg (or nullptr when m_subdescriptor_arg is nullptr).
356358
* @param out A FlatSigningProvider to put scripts or public keys in that are necessary to the solver.
357359
* The script arguments to this function are automatically added, as is the origin info of the provided pubkeys.
358360
* @return A vector with scriptPubKeys for this descriptor.
359361
*/
360362
virtual std::vector<CScript> MakeScripts(const std::vector<CPubKey>& pubkeys, const CScript* script, FlatSigningProvider& out) const = 0;
361363

362364
public:
363-
DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::unique_ptr<DescriptorImpl> script, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_script_arg(std::move(script)), m_name(name) {}
365+
DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::unique_ptr<DescriptorImpl> script, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_subdescriptor_arg(std::move(script)), m_name(name) {}
364366

365367
bool IsSolvable() const override
366368
{
367-
if (m_script_arg) {
368-
if (!m_script_arg->IsSolvable()) return false;
369+
if (m_subdescriptor_arg) {
370+
if (!m_subdescriptor_arg->IsSolvable()) return false;
369371
}
370372
return true;
371373
}
@@ -375,8 +377,8 @@ class DescriptorImpl : public Descriptor
375377
for (const auto& pubkey : m_pubkey_args) {
376378
if (pubkey->IsRange()) return true;
377379
}
378-
if (m_script_arg) {
379-
if (m_script_arg->IsRange()) return true;
380+
if (m_subdescriptor_arg) {
381+
if (m_subdescriptor_arg->IsRange()) return true;
380382
}
381383
return false;
382384
}
@@ -396,10 +398,10 @@ class DescriptorImpl : public Descriptor
396398
}
397399
ret += std::move(tmp);
398400
}
399-
if (m_script_arg) {
401+
if (m_subdescriptor_arg) {
400402
if (pos++) ret += ",";
401403
std::string tmp;
402-
if (!m_script_arg->ToStringHelper(arg, tmp, priv)) return false;
404+
if (!m_subdescriptor_arg->ToStringHelper(arg, tmp, priv)) return false;
403405
ret += std::move(tmp);
404406
}
405407
out = std::move(ret) + ")";
@@ -428,6 +430,8 @@ class DescriptorImpl : public Descriptor
428430
// Construct temporary data in `entries` and `subscripts`, to avoid producing output in case of failure.
429431
for (const auto& p : m_pubkey_args) {
430432
entries.emplace_back();
433+
// If we have a cache, we don't need GetPubKey to compute the public key.
434+
// Pass in nullptr to signify only origin info is desired.
431435
if (!p->GetPubKey(pos, arg, cache_read ? nullptr : &entries.back().first, entries.back().second)) return false;
432436
if (cache_read) {
433437
// Cached expanded public key exists, use it.
@@ -444,9 +448,9 @@ class DescriptorImpl : public Descriptor
444448
}
445449
}
446450
std::vector<CScript> subscripts;
447-
if (m_script_arg) {
451+
if (m_subdescriptor_arg) {
448452
FlatSigningProvider subprovider;
449-
if (!m_script_arg->ExpandHelper(pos, arg, cache_read, subscripts, subprovider, cache_write)) return false;
453+
if (!m_subdescriptor_arg->ExpandHelper(pos, arg, cache_read, subscripts, subprovider, cache_write)) return false;
450454
out = Merge(out, subprovider);
451455
}
452456

@@ -456,7 +460,7 @@ class DescriptorImpl : public Descriptor
456460
pubkeys.push_back(entry.first);
457461
out.origins.emplace(entry.first.GetID(), std::make_pair<CPubKey, KeyOriginInfo>(CPubKey(entry.first), std::move(entry.second)));
458462
}
459-
if (m_script_arg) {
463+
if (m_subdescriptor_arg) {
460464
for (const auto& subscript : subscripts) {
461465
out.scripts.emplace(CScriptID(subscript), subscript);
462466
std::vector<CScript> addscripts = MakeScripts(pubkeys, &subscript, out);

src/script/descriptor.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,17 @@ struct Descriptor {
4747
*
4848
* pos: the position at which to expand the descriptor. If IsRange() is false, this is ignored.
4949
* provider: the provider to query for private keys in case of hardened derivation.
50-
* output_script: the expanded scriptPubKeys will be put here.
50+
* output_scripts: the expanded scriptPubKeys will be put here.
5151
* out: scripts and public keys necessary for solving the expanded scriptPubKeys will be put here (may be equal to provider).
52-
* cache: vector which will be overwritten with cache data necessary to-evaluate the descriptor at this point without access to private keys.
52+
* cache: vector which will be overwritten with cache data necessary to evaluate the descriptor at this point without access to private keys.
5353
*/
5454
virtual bool Expand(int pos, const SigningProvider& provider, std::vector<CScript>& output_scripts, FlatSigningProvider& out, std::vector<unsigned char>* cache = nullptr) const = 0;
5555

5656
/** Expand a descriptor at a specified position using cached expansion data.
5757
*
5858
* pos: the position at which to expand the descriptor. If IsRange() is false, this is ignored.
5959
* cache: vector from which cached expansion data will be read.
60-
* output_script: the expanded scriptPubKeys will be put here.
60+
* output_scripts: the expanded scriptPubKeys will be put here.
6161
* out: scripts and public keys necessary for solving the expanded scriptPubKeys will be put here (may be equal to provider).
6262
*/
6363
virtual bool ExpandFromCache(int pos, const std::vector<unsigned char>& cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out) const = 0;

0 commit comments

Comments
 (0)