Commit Graph

182 Commits

Author SHA1 Message Date
Ava Chow
c6c4edf324 Merge bitcoin/bitcoin#32983: rpc: refactor: use string_view in Arg/MaybeArg
b63428ac9c rpc: refactor: use more (Maybe)Arg<std::string_view> (stickies-v)
037830ca0d refactor: increase string_view usage (stickies-v)
b3bf18f0ba rpc: refactor: use string_view in Arg/MaybeArg (stickies-v)

Pull request description:

  The `RPCHelpMan::{Arg,MaybeArg}` helpers avoid copying (potentially) large strings by returning them as `const std::string*` (`MaybeArg`) or `const std::string&` (`Arg`). For `MaybeArg`, this has the not-so-nice effect that users need to deal with raw pointers, potentially also requiring new functions (e.g. [`EnsureUniqueWalletName` ](d127b25199 (diff-d8bfcfbdd5fa7d5c52d38c1fe5eeac9ce5c5a794cdfaf683585140fa70a32374R32))) with raw pointers being implemented.

  This PR aims to improve on this by returning a trivially copyable `std::string_view` (`Arg`) or `std::optional<std::string_view>` (`MaybeArg`), modernizing the interface without introducing any additional copying overhead. In doing so, it also generalizes whether we return by value or by pointer/reference using `std::is_trivially_copyable_v` instead of defining the types manually.

  In cases where functions currently take a `const std::string&` and it would be too much work / touching consensus logic to update them (`signmessage.cpp`), a `std::string` copy is made (which was already happening anyway).

  The last 2 commits increase usage of the `{Arg,MaybeArg}<std::string_view>` helpers, and could be dropped/pruned if anything turns out to be controversial - I just think it's a nice little cleanup.

ACKs for top commit:
  maflcko:
    re-ACK b63428ac9c 🎉
  achow101:
    ACK b63428ac9c
  pablomartin4btc:
    re-ACK [b63428a](b63428ac9c)
  w0xlt:
    reACK b63428ac9c

Tree-SHA512: b4942c353a1658c22a88d8c9b402c288ad35265a3b88aa2072b1f9b6d921cd073194ed4b00b807cb48ca440f47c87ef3d8e0dd1a5d814be58fc7743f26288277
2025-10-24 10:33:51 -07:00
stickies-v
b3bf18f0ba rpc: refactor: use string_view in Arg/MaybeArg
Modernizes interface by not forcing users to deal with raw pointers,
without adding copying overhead. Generalizes the logic of whether
we return by value or by optional/pointer.

In cases where functions take a `const std::string&` and it would
be too much work to update them, a string copy is made (which was
already happening anyway).
2025-10-02 12:53:25 +01:00
Ava Chow
f14876213a musig: Move synthetic xpub construction to its own function 2025-09-16 16:09:31 -07:00
Ava Chow
39a63bf2e7 descriptors: Add a doxygen comment for has_hardened output_parameter 2025-07-31 15:40:25 -07:00
Ava Chow
2320184d0e descriptors: Fix meaning of any_key_parsed
Invert any_key_parsed so that the name matches the behavior.
2025-07-31 15:40:25 -07:00
Ava Chow
a53924bee3 descriptor: Parse musig() key expressions 2025-06-24 13:40:12 -07:00
Ava Chow
9473e9606c descriptors: Move DeriveType parsing into its own function 2025-06-24 13:39:54 -07:00
Ava Chow
4af0dca096 descriptor: Add MuSigPubkeyProvider 2025-06-24 13:35:29 -07:00
Ava Chow
1894f97503 descriptors: Add PubkeyProvider::IsBIP32() 2025-06-11 11:11:48 -07:00
MarcoFalke
fa2125e7b8 Remove unused IsSingleKey 2025-05-09 15:06:51 +02:00
MarcoFalke
fa55dd01df descriptors: Reject + sign when parsing multi threshold 2025-04-28 17:05:37 +02:00
MarcoFalke
fa6f77ed3c descriptors: Reject + sign in ParseKeyPathNum 2025-04-28 17:05:36 +02:00
Ava Chow
acee5c59e6 descriptors: Have GetPrivKey fill keys directly
Instead of GetPrivKey returning a key and having the caller fill the
FlatSigningProvider, have GetPrivKey take the FlatSigningProvider and
fill it by itself. This will be necessary for descriptors such as
musig() where there are private keys that need to be added to the
FlatSigningProvider but do not directly appear in any resulting scripts.

GetPrivKey is now changed to void as the caller no longer cares whether
it succeeds or fails.
2025-04-14 16:32:01 -07:00
Ava Chow
4b0303197e descriptors: Move FlatSigningProvider pubkey filling to GetPubKey
Instead of MakeScripts inconsistently filling the output
FlatSigningProvider with the pubkeys involved, just do it in GetPubKey.
2025-04-14 16:32:01 -07:00
Ava Chow
25a3b9b0f5 descriptors: Have GetPubKey fill origins directly
Instead of having ExpandHelper fill in the origins in the
FlatSigningProvider output, have GetPubKey do it by itself. This reduces
the extra variables needed in order to track and set origins in
ExpandHelper.

Also changes GetPubKey to return a std::optional<CPubKey> rather than
using a bool and output parameters.
2025-04-14 16:32:01 -07:00
Ava Chow
6268bde0af descriptor: Remove unused parent_info from BIP32PUbKeyProvider::GetPubKey 2025-04-14 16:32:01 -07:00
Ava Chow
0ff072caa1 wallet, rpc: Only allow keypool import from single key descriptors
Legacy wallets should only import keys to the keypool if they came in a
single key descriptor. Instead of relying on assumptions about the
descriptor based on how many pubkeys show up after expanding the
descriptor, explicitly mark descriptors as being single key type and use
that for the check.
2025-04-14 16:32:01 -07:00
Hodlinator
56f271e9b9 descriptors refactor: Clarify multipath data relationships through local struct 2025-03-29 20:46:54 +01:00
Hodlinator
7e974f474e descriptors refactor: Use range-for and limit scope of seen_multipath
* Range-for avoids ++i/i++ debate and decreases linecount.
* seen_multipath is only used if multipath_segment_index hasn't already been set. Rename it to seen_substitutes to better describe what it does, now that the context implies its involved in multipath.
2025-03-29 20:43:48 +01:00
Hodlinator
99a92efdd9 descriptors doc: Correct Markdown format + wording 2025-03-25 21:13:35 +01:00
merge-script
aa87e0b446 Merge bitcoin/bitcoin#31519: refactor: Use std::span over Span
ffff4a293a bench: Update span-serialize comment (MarcoFalke)
fa4d6ec97b refactor: Avoid false-positive gcc warning (MarcoFalke)
fa942332b4 scripted-diff: Bump copyright headers after std::span changes (MarcoFalke)
fa0c6b7179 refactor: Remove unused Span alias (MarcoFalke)
fade0b5e5e scripted-diff: Use std::span over Span (MarcoFalke)
fadccc26c0 refactor: Make Span an alias of std::span (MarcoFalke)
fa27e36717 test: Fix broken span_tests (MarcoFalke)
fadf02ef8b refactor: Return std::span from MakeUCharSpan (MarcoFalke)
fa720b94be refactor: Return std::span from MakeByteSpan (MarcoFalke)

Pull request description:

  `Span` has some issues:

  * It does not support fixed-size spans, which are available through `std::span`.
  * It is confusing to have it available and in use at the same time with `std::span`.
  * It does not obey the standard library iterator build hardening flags. See https://github.com/bitcoin/bitcoin/issues/31272 for a discussion. For example, this allows to catch issues like the one fixed in commit fabeca3458.

  Both types are type-safe and can even implicitly convert into each other in most contexts.

  However, exclusively using `std::span` seems less confusing, so do it here with a scripted-diff.

ACKs for top commit:
  l0rinc:
    reACK ffff4a293a
  theuni:
    ACK ffff4a293a.

Tree-SHA512: 9cc2f1f43551e2c07cc09f38b1f27d11e57e9e9bc0c6138c8fddd0cef54b91acd8b14711205ff949be874294a121910d0aceffe0e8914c4cff07f1e0e87ad5b8
2025-03-20 13:41:54 +08:00
Ryan Ofsky
223fc24c4e Merge bitcoin/bitcoin#31603: descriptor: check whitespace in keys within fragments
21e9d39a37 docs: add release notes for 31603 (brunoerg)
a8b548d75d test: `getdescriptorinfo`/`importdescriptors` with whitespace in pubkeys (brunoerg)
c7afca3d62 test: descriptor: check whitespace into keys (brunoerg)
cb722a3cea descriptor: check whitespace in ParsePubkeyInner (brunoerg)
50856695ef test: fix descriptors in `ismine_tests` (brunoerg)

Pull request description:

  Currently, we successfully parse descriptors which contains spaces in the beginning or end of the public/private key within a fragment (e.g. `pk( KEY)`, `pk(KEY )` or `pk( KEY )`). I have noticed that one of the reasons is that the `DecodeBase58` function simply ignore these whitespaces.

  This PR changes the `ParsePubkeyInner ` to reject pubkeys that contain a whitespace at the beginning and/or at the end. We will only check the whitespace in some RPCs (e.g. `importdescriptors`), but an already imported descriptor won't be affected by this check, especially because we store descriptors from `ToString`.

  For context: https://github.com/brunoerg/bitcoinfuzz/issues/72

ACKs for top commit:
  rkrux:
    tACK 21e9d39a37
  darosior:
    re-ACK 21e9d39a37
  sipa:
    utACK 21e9d39a37

Tree-SHA512: 54f48a89a235517e5cdc29a46dceeb7dabbee93c7616a166288ff3f90131808eb0ece43b0797a11fe827a5f7bd51d65e3e75c16789b0a42020934cabb684cc8f
2025-03-18 08:36:41 -04:00
MarcoFalke
fa942332b4 scripted-diff: Bump copyright headers after std::span changes
Historically, the headers have been bumped some time after a file has
been touched. Do it now to avoid having to touch them again in the
future for that reason.

-BEGIN VERIFY SCRIPT-
 sed -i --regexp-extended 's;( 20[0-2][0-9])(-20[0-2][0-9])? The Bitcoin Core developers;\1-present The Bitcoin Core developers;g' $( git show --pretty="" --name-only HEAD~1 )
-END VERIFY SCRIPT-
2025-03-12 19:46:54 +01:00
MarcoFalke
fade0b5e5e scripted-diff: Use std::span over Span
-BEGIN VERIFY SCRIPT-

 ren() { sed -i "s!\<$1\>!$2!g" $( git grep -l "$1" -- "./src" ":(exclude)src/span.h" ":(exclude)src/leveldb/db/log_test.cc" ) ; }

 ren Span            std::span
 ren AsBytes         std::as_bytes
 ren AsWritableBytes std::as_writable_bytes

 sed -i 's!SpanPopBack(Span!SpanPopBack(std::span!g' ./src/span.h

-END VERIFY SCRIPT-
2025-03-12 19:45:37 +01:00
brunoerg
cb722a3cea descriptor: check whitespace in ParsePubkeyInner
Due to Base58, keys with whitespace at the beginning or
at the end are successfully parsed. This commit adds a
check into `ParsePubkeyInner` to verify whether if the
first or last char of the key is a space.
2025-02-24 09:55:40 -03:00
Ava Chow
6d11c9c60b descriptor: Add proper Clone function to miniscript::Node
Multipath descriptors requires performing a deep copy, so a Clone
function that does that is added to miniscript::Node instead of the
current shallow copy.

Co-Authored-By: Antoine Poinsot <darosior@protonmail.com>
2025-01-21 13:17:18 -05:00
Ava Chow
b4ac48090f descriptor: Use InferXOnlyPubkey for miniscript XOnly pubkey from script 2025-01-06 19:10:54 -05:00
Ava Chow
092569e858 descriptor: Try the other parity in ConstPubkeyProvider::GetPrivKey()
GetPrivKey() needs the same handling of all keyids for xonly keys that
ToPrivateString() does. Refactor that into GetPrivKey() and reuse it in
ToPrivateString() to resolve this.
2025-01-06 14:52:01 -05:00
brunoerg
366ae00b77 descriptor: Assume ParseScript is not being called with a P2WPKH context 2024-12-24 11:01:47 -03:00
brunoerg
e366408590 descriptor: remove unreachable verification for pkh 2024-12-23 08:41:35 -03:00
glozow
f93d5553d1 Merge bitcoin/bitcoin#22838: descriptors: Be able to specify change and receiving in a single descriptor string
a0abcbd382 doc: Mention multipath specifier (Ava Chow)
0019f61fc5 tests: Test importing of multipath descriptors (Ava Chow)
f97d5c137d wallet, rpc: Allow importdescriptors to import multipath descriptors (Ava Chow)
32dcbca3fb rpc: Allow importmulti to import multipath descriptors correctly (Ava Chow)
64dfe3ce4b wallet: Move internal to be per key when importing (Ava Chow)
1692245525 tests: Multipath descriptors for scantxoutset and deriveaddresses (Ava Chow)
cddc0ba9a9 rpc: Have deriveaddresses derive receiving and change (Ava Chow)
360456cd22 tests: Multipath descriptors for getdescriptorinfo (Ava Chow)
a90eee444c tests: Add unit tests for multipath descriptors (Ava Chow)
1bbf46e2da descriptors: Change Parse to return vector of descriptors (Ava Chow)
0d640c6f02 descriptors: Have ParseKeypath handle multipath specifiers (Ava Chow)
a5f39b1034 descriptors: Change ParseScript to return vector of descriptors (Ava Chow)
0d55deae15 descriptors: Add DescriptorImpl::Clone (Ava Chow)
7e86541f72 descriptors: Add PubkeyProvider::Clone (Ava Chow)

Pull request description:

  It is convenient to have a descriptor which specifies both receiving and change addresses in a single string. However, as discussed in https://github.com/bitcoin/bitcoin/issues/17190#issuecomment-895515768, it is not feasible to use a generic multipath specification like BIP 88 due to combinatorial blow up and that it would result in unexpected descriptors.

  To resolve that problem, this PR proposes a targeted solution which allows only a single pair of 2 derivation indexes to be inserted in the place of a single derivation index. So instead of two descriptor `wpkh(xpub.../0/0/*)` and `wpkh(xpub.../0/1/*)` to represent receive and change addresses, this could be written as `wpkh(xpub.../0/<0;1>/*)`. The multipath specifier is of the form `<NUM;NUM>`. Each `NUM` can have its own hardened specifier, e.g. `<0;1h>` is valid. The multipath specifier can also only appear in one path index in the derivation path.

  This results in the parser returning two descriptors. The first descriptor uses the first `NUM` in all pairs present, and the second uses the second `NUM`. In our implementation, if a multipath descriptor is not provided, a pair is still returned, but the second element is just `nullptr`.

  The wallet will not output the multipath descriptors (yet). Furthermore, when a multipath descriptor is imported, it is expanded to the two descriptors and each imported on its own, with the second descriptor being implicitly for internal (change) addresses. There is no change to how the wallet stores or outputs descriptors (yet).

  Note that the path specifier is different from what was proposed. It uses angle brackets and the semicolon because these are unused characters available in the character set and I wanted to avoid conflicts with characters already in use in descriptors.

  Closes #17190

ACKs for top commit:
  darosior:
    re-ACK a0abcbd382
  mjdietzx:
    reACK a0abcbd382
  pythcoiner:
    reACK a0abcbd
  furszy:
    Code review ACK a0abcbd
  glozow:
    light code review ACK a0abcbd382

Tree-SHA512: 84ea40b3fd1b762194acd021cae018c2f09b98e595f5e87de5c832c265cfe8a6d0bc4dae25785392fa90db0f6301ddf9aea787980a29c74f81d04b711ac446c2
2024-08-28 15:56:15 +01:00
MarcoFalke
fadf0a7e15 refactor: Remove Span operator==, Use std::ranges::equal 2024-08-13 07:44:31 +02:00
Ava Chow
1bbf46e2da descriptors: Change Parse to return vector of descriptors
When given a descriptor which contins a multipath derivation specifier,
a vector of descriptors will be returned.
2024-08-08 12:47:22 -04:00
Ava Chow
0d640c6f02 descriptors: Have ParseKeypath handle multipath specifiers
Multipath specifiers are derivation path indexes of the form `<i;j;k;...>`
used for specifying multiple derivation paths for a descriptor.
Only one multipath specifier is allowed per PubkeyProvider.
This is syntactic sugar which is parsed into multiple distinct descriptors.
One descriptor will have all of the `i` paths, the second all of the `j` paths,
the third all of the `k` paths, and so on.

ParseKeypath will always return a vector of keypaths with the same size
as the multipath specifier. The callers of this function are updated to deal
with this case and return multiple PubkeyProviders. Their callers have
also been updated to handle vectors of PubkeyProviders.

Co-Authored-By: furszy <matiasfurszyfer@protonmail.com>
2024-08-08 12:46:34 -04:00
Ava Chow
a5f39b1034 descriptors: Change ParseScript to return vector of descriptors
To prepare for returning multipath descriptors which will be a shorthand
for specifying multiple descriptors, change ParseScript's signature to return a
vector.
2024-08-08 12:46:32 -04:00
Ava Chow
0d55deae15 descriptors: Add DescriptorImpl::Clone 2024-08-07 16:28:59 -04:00
Ava Chow
7e86541f72 descriptors: Add PubkeyProvider::Clone 2024-08-07 16:28:57 -04:00
TheCharlatan
51fa26239a refactor: Mark some static global vars as const
These were found while looking for static mutable state in the kernel
library.
2024-07-08 21:19:23 +02:00
Ryan Ofsky
4f74c59334 util: Move util/string.h functions to util namespace
There are no changes to behavior. Changes in this commit are all additions, and
are easiest to review using "git diff -U0 --word-diff-regex=." options.

Motivation for this change is to keep util functions with really generic names
like "Split" and "Join" out of the global namespace so it is easier to see
where these functions are defined, and so they don't interfere with function
overloading, especially since the util library is a dependency of the kernel
library and intended to be used with external code.
2024-05-16 10:16:08 -05:00
Ryan Ofsky
9bcce2608d util: move spanparsing.h to script/parsing.h
Move miniscript / descriptor script parsing functions out of util library so
they are not a dependency of the kernel.

There are no changes to code or behavior.
2024-05-16 10:16:08 -05:00
dergoegge
78407b99ed [clang-tidy] Enable the misc-no-recursion check
Co-authored-by: stickies-v <stickies-v@protonmail.com>
Co-authored-by: Gloria Zhao <gloriajzhao@gmail.com>
2024-04-07 14:04:45 +01:00
Ava Chow
fe67841464 descriptor: Be able to get the pubkeys involved in a descriptor 2024-02-20 11:20:58 -05:00
brunoerg
e1281f1bbd wallet: fix key parsing check for miniscript expressions in ParseScript 2023-12-08 06:54:00 -03:00
Andrew Chow
37b9b73477 descriptors: Move InferScript's pubkey validity checks to InferPubkey 2023-10-09 14:07:37 -04:00
Andrew Chow
b7485f11ab descriptors: Check result of InferPubkey
InferPubkey can return a nullptr, so check it's result before continuing
with creating the inferred descriptor.
2023-10-09 14:07:37 -04:00
Antoine Poinsot
8571b89a7f descriptor: parse Miniscript expressions within Taproot descriptors 2023-10-08 02:43:22 +02:00
Antoine Poinsot
8ff9489422 descriptor: Tapscript-specific Miniscript key serialization / parsing
64-hex-characters public keys are valid in Miniscript key expressions
within a Tapscript context.

Keys under a Tapscript context always serialize as 32-bytes x-only
public keys (and that's what get hashed by OP_HASH160 on the stack too).
2023-10-08 02:43:22 +02:00
Antoine Poinsot
fcb6f13f44 pubkey: introduce a GetEvenCorrespondingCPubKey helper
We'll need to get a compressed key out of an x-only one in other places.
Avoid duplicating the code.
2023-10-08 02:43:19 +02:00
Antoine Poinsot
c3738d0344 miniscript: introduce a MsContext() helper to contexts
We are going to introduce Tapscript support in Miniscript, for which
some of Miniscript rules and properties change (new or modified
fragments, different typing rules, different resources consumption, ..).
2023-10-08 02:43:14 +02:00
Pieter Wuille
c1e6c542af descriptors: disallow hybrid public keys
The descriptor documentation (doc/descriptors.md) and BIP380 explicitly
require that hex-encoded public keys start with 02 or 03 (compressed) or
04 (uncompressed). However, the current parsing/inference code permit 06
and 07 (hybrid) encoding as well. Fix this.
2023-10-04 11:28:13 -04:00