Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backport: merge bitcoin#23106, #22067, #23303, #23403, #22513, #17034, #23718, partial bitcoin#21330, #21365, #22514 (psbt backports) #6503

Merged
merged 12 commits into from
Jan 8, 2025

Conversation

kwvg
Copy link
Collaborator

@kwvg kwvg commented Dec 21, 2024

Additional Information

  • Even though Dash Core does not implement Taproot, bitcoin#21365 has been partially backported due to changes related to transaction precomputation, required by later PSBT backports.

  • Some test vectors introduced in bitcoin#17034 and bitcoin#23718 have psbtx.tx->vin[i].scriptWitness populated and as Dash Core does not support SegWit, attempting to read the raw data results in serialization errors.

    The offending field was stripped out by forking Bitcoin Core v24 and modifying decodepsbt to strip out the field, reencode the modified data and return it. These changes were made in separate commits.

Breaking Changes

None expected.

Checklist

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas (note: N/A)
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation
  • I have assigned this pull request to a milestone (for repository code-owners and collaborators only)

@kwvg kwvg added this to the 22.1 milestone Dec 21, 2024
@kwvg kwvg marked this pull request as ready for review December 24, 2024 11:23
Copy link

coderabbitai bot commented Dec 24, 2024

Walkthrough

The pull request introduces comprehensive enhancements to Bitcoin Core's transaction handling, particularly focusing on Partially Signed Bitcoin Transactions (PSBTs) and multisig functionality. The changes span multiple components of the codebase, including script verification, signing mechanisms, wallet management, and testing infrastructure.

Key modifications include the introduction of a new MissingDataBehavior enumeration to control how missing transaction data is handled during script verification, updates to PSBT processing to support precomputed transaction data, and expanded capabilities for handling extended public keys and multisig wallets. The changes also introduce new methods for encoding and decoding versioned keys, improve error handling in various transaction-related operations, and add new test cases to validate these enhanced functionalities.

The modifications aim to provide more robust and flexible transaction handling, with a particular emphasis on improving the security and reliability of multisig and PSBT workflows across different wallet scenarios.

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request. We would love to hear your feedback on Discord.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (32)
test/functional/wallet_multisig_descriptor_psbt.py (1)

58-59: Remove unnecessary nested f-string prefixes:
The nested f-string syntax can safely drop the inner f prefixes, as no variable interpolation is occurring.

- external = multisig.getdescriptorinfo(f"sh(sortedmulti({self.M},{f'/0/*,'.join(xpubs)}/0/*))")
+ external = multisig.getdescriptorinfo(f"sh(sortedmulti({self.M},{'/0/*,'.join(xpubs)}/0/*))")

- internal = multisig.getdescriptorinfo(f"sh(sortedmulti({self.M},{f'/1/*,'.join(xpubs)}/1/*))")
+ internal = multisig.getdescriptorinfo(f"sh(sortedmulti({self.M},{'/1/*,'.join(xpubs)}/1/*))")
🧰 Tools
🪛 Ruff (0.8.2)

58-58: f-string without any placeholders

Remove extraneous f prefix

(F541)


59-59: f-string without any placeholders

Remove extraneous f prefix

(F541)

src/psbt.cpp (1)

219-234: PrecomputePSBTData function:
This function consolidates logic for collecting spent outputs and initializing PrecomputedTransactionData. Handling the condition where not all UTXOs are available (have_all_spent_outputs) is a practical touch, ensuring partial precomputation when necessary.

Might consider logging or returning info if partial precomputation occurs, helping diagnose incomplete UTXO data.

src/wallet/scriptpubkeyman.h (1)

217-217: Clarify the default return value.
This override always returns TransactionError::INVALID_PSBT, which may impede usability if there's a scenario where partially valid PSBT data should be processed differently. Consider providing a more contextual error or implementing partial handling.

src/psbt.h (10)

26-28: Global type constants.
Ensure the newly introduced constants (PSBT_GLOBAL_XPUB, PSBT_GLOBAL_VERSION, and PSBT_GLOBAL_PROPRIETARY) follow existing naming and usage conventions.


59-96: PSBTProprietary struct and serialization helpers.
This large block introduces custom proprietary data key storage. Ensure thorough testing for edge cases like empty identifiers or conflicting subtypes, and watch out for memory overhead if used extensively.


115-138: HD keypath deserialization.
Properly fails on invalid lengths with a thrown exception. Double-check that large or edge-case path lengths are handled (or blocked) as expected.

Need help writing test vectors for extremely long key paths?


139-162: HD keypath serialization.
The functions carefully handle pubkey array sizes. Confirm no off-by-one or multi-segment path misinterpretations in cross-library usage.


201-203: Sighash check and serialization.
The optional sighash type is recognized. Confirm it doesn't conflict with the top-level transaction's sighash or cause user confusion.


215-220: RIPEMD160 preimage serialization.
Writes each preimage pair with an explicit type. Good design to keep these enumerations. Possibly consider size checks to prevent DoS if large preimages are fed.


246-251: Proprietary input serialization.
Serializes m_proprietary. Confirm no unbounded memory growth as these sets can accumulate.


324-326: int sighash read.
Unserialized into an int. Watch for negative or out-of-range values. Possibly consider a narrower type if future expansions occur.


416-436: HASH256 preimage read block.
Same pattern. Carefully watch potential memory usage for large preimages.


872-877: SignPSBTInput signature changes.
Now takes const PrecomputedTransactionData* txdata. This is more efficient. Validate that txdata is not null if the user expects a real signature.

src/wallet/scriptpubkeyman.cpp (2)

750-750: Sighash mismatch check.
This block ensures consistent usage of the requested sighash across all inputs. Might need better error messages if mismatches happen in multi-signer scenarios.


765-765: SignPSBTInput usage.
Signs or partially updates each input. Confirm it gracefully handles unspendable inputs or hardware signer interactions.

src/rpc/rawtransaction.cpp (2)

1557-1558: Sighash extraction.
Conditional check for input.sighash_type. Properly uses SighashToStr(). Straightforward.


1679-1692: Output field expansions for proprietary data.
Collects the same metadata for outputs. Carefully handle any conflicts if multiple signers add the same proprietary fields.

src/wallet/rpcwallet.cpp (1)

4474-4474: Consider type-checking other parameters.

Currently, only the first parameter is strictly type-checked as a string (RPCTypeCheck(request.params, {UniValue::VSTR});). The subsequent parameters (sign, sighashtype, bip32derivs, finalize) are handled without explicit type checks. This can lead to less friendly error messages or subtle type mismatches if the user supplies invalid parameter types.

src/script/sign.h (1)

42-42: Introduce a comment clarifying the purpose of m_txdata.
The addition of m_txdata to store precomputed transaction data is beneficial. To maintain clarity for future contributors, consider adding a short comment on why it’s needed and how it’s used.

src/node/psbt.cpp (1)

124-124: Clarify usage of nullptr for txdata.
Here, SignPSBTInput is called with nullptr instead of &txdata. This may be intentional to skip precomputation for certain test paths or advanced usage scenarios. Verify that this difference (passing real precomputed data in one call vs. nullptr in another) won’t cause inconsistent results in the fee/size estimation logic.

src/pubkey.h (3)

19-19: Introduce a comment or docstring for maintainability.
Currently, BIP32_EXTKEY_WITH_VERSION_SIZE is declared without any direct mention of its purpose or typical usage context, which might cause confusion for new contributors.

+// Includes 4 bytes for the version, in addition to the standard BIP32 ext key size (74).
 const unsigned int BIP32_EXTKEY_WITH_VERSION_SIZE = 78;

249-249: Explicitly clarify endianness for version array.
While storing raw version bytes is fine, consider documenting any endianness assumptions here (big-endian vs. little-endian), especially if external components interpret these bytes in a specific order.


282-283: Consider version validation.
EncodeWithVersion & DecodeWithVersion copy 4 bytes of version without checks. If future expansions require validating or restricting certain versions, consider adding a validation step.

src/rpc/client.cpp (1)

141-141: Add documentation about the 'finalize' parameter.
When introducing a new parameter to walletprocesspsbt, consider adding comment or help text describing the role of finalize—particularly crucial for scripting or automation.

src/script/interpreter.cpp (2)

1503-1503: Consider documenting or removing the unused force parameter.
Currently, force is neither referenced nor documented. If it's intended for future use, consider adding a brief comment clarifying its purpose. Otherwise, removing it could simplify the code.


1524-1534: Improve error handling in HandleMissingData.
This function’s use of assert(!"Missing data") and assert(!"Unknown MissingDataBehavior value") is correct for debug builds, but consider logging or throwing exceptions in release builds to prevent abrupt termination and facilitate error reporting.

src/wallet/wallet.h (2)

1165-1166: Clarify the output parameter in the docstring.
The parameter n_signed is returned by reference, indicating how many inputs got signed by this wallet. Ensure that callers use this to handle partial signings properly, especially in multi-signer workflows.


1174-1175: Document the behavior of finalize = true.
While adding a parameter for finalizing the scriptSig is useful, consider expanding the documentation to describe scenarios where disabling finalization is advantageous (e.g., for partially signed PSBTs that require more signatures downstream).

doc/psbt.md (2)

95-95: Add a comma for clarity.
"For a quick start see Basic M-of-N multisig example..." would be clearer with a comma after "For a quick start." Example:

For a quick start, see [Basic M-of-N multisig example…]

🧰 Tools
🪛 LanguageTool

[uncategorized] ~95-~95: Possible missing comma found.
Context: ...ple Bitcoin Core instances For a quick start see [Basic M-of-N multisig example usin...

(AI_HYDRA_LEO_MISSING_COMMA)


96-96: Minor grammar nitpick.
"If you are using legacy wallets feel free..." would be clearer with a comma after "If you are using legacy wallets." Example:

If you are using legacy wallets, feel free to continue…

🧰 Tools
🪛 LanguageTool

[uncategorized] ~96-~96: Possible missing comma found.
Context: ...tisig-example). If you are using legacy wallets feel free to continue with the example ...

(AI_HYDRA_LEO_MISSING_COMMA)

doc/descriptors.md (2)

134-138: Fix grammar and improve clarity.

Minor grammar and clarity improvements needed:

  • Line 134: Replace "an xpub" with "a xpub" (as suggested by static analysis)
  • Line 150: Add periods to "eg" to make it "e.g."
  • Line 153: Add hyphen to "daisy chained" to make it "daisy-chained"
-  1. Every participant generates an xpub. The most straightforward way is to create a new descriptor wallet which we will refer to as
+  1. Every participant generates a xpub. The most straightforward way is to create a new descriptor wallet which we will refer to as
   the participant's signer wallet. Avoid reusing this wallet for any purpose other than signing transactions from the
   corresponding multisig we are about to create. Hint: extract the wallet's xpubs using `listdescriptors` and pick the one from the
   `pkh` descriptor since it's least likely to be accidentally reused (legacy addresses)
🧰 Tools
🪛 LanguageTool

[misspelling] ~134-~134: Use “a” instead of ‘an’ if the following word doesn’t start with a vowel sound, e.g. ‘a sentence’, ‘a university’.
Context: ... are: 1. Every participant generates an xpub. The most straightforward way is t...

(EN_A_VS_AN)


125-130: Consider adding links to security best practices.

The disclaimers about wallet management and security considerations are important. Consider adding links to relevant documentation about:

  • Wallet backup best practices
  • Privacy best practices for multisig transactions
  • Security considerations when using non-Bitcoin Core wallets
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad7a373 and aba9370.

📒 Files selected for processing (39)
  • doc/descriptors.md (1 hunks)
  • doc/psbt.md (1 hunks)
  • src/coinjoin/server.cpp (1 hunks)
  • src/node/psbt.cpp (3 hunks)
  • src/psbt.cpp (7 hunks)
  • src/psbt.h (19 hunks)
  • src/pubkey.cpp (1 hunks)
  • src/pubkey.h (4 hunks)
  • src/qt/psbtoperationsdialog.cpp (2 hunks)
  • src/rpc/client.cpp (1 hunks)
  • src/rpc/rawtransaction.cpp (11 hunks)
  • src/script/bitcoinconsensus.cpp (1 hunks)
  • src/script/interpreter.cpp (2 hunks)
  • src/script/interpreter.h (3 hunks)
  • src/script/keyorigin.h (1 hunks)
  • src/script/sigcache.h (1 hunks)
  • src/script/sign.cpp (4 hunks)
  • src/script/sign.h (1 hunks)
  • src/script/signingprovider.h (1 hunks)
  • src/serialize.h (1 hunks)
  • src/test/evo_deterministicmns_tests.cpp (1 hunks)
  • src/test/fuzz/script_flags.cpp (1 hunks)
  • src/test/fuzz/script_sign.cpp (3 hunks)
  • src/test/multisig_tests.cpp (3 hunks)
  • src/test/script_p2sh_tests.cpp (1 hunks)
  • src/test/script_tests.cpp (4 hunks)
  • src/test/transaction_tests.cpp (1 hunks)
  • src/wallet/rpcwallet.cpp (4 hunks)
  • src/wallet/scriptpubkeyman.cpp (6 hunks)
  • src/wallet/scriptpubkeyman.h (3 hunks)
  • src/wallet/test/psbt_wallet_tests.cpp (1 hunks)
  • src/wallet/test/wallet_test_fixture.cpp (2 hunks)
  • src/wallet/test/wallet_test_fixture.h (1 hunks)
  • src/wallet/wallet.cpp (2 hunks)
  • src/wallet/wallet.h (1 hunks)
  • test/functional/data/rpc_psbt.json (3 hunks)
  • test/functional/rpc_psbt.py (1 hunks)
  • test/functional/test_runner.py (1 hunks)
  • test/functional/wallet_multisig_descriptor_psbt.py (1 hunks)
🧰 Additional context used
🪛 LanguageTool
doc/psbt.md

[uncategorized] ~95-~95: Possible missing comma found.
Context: ...ple Bitcoin Core instances For a quick start see [Basic M-of-N multisig example usin...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~96-~96: Possible missing comma found.
Context: ...tisig-example). If you are using legacy wallets feel free to continue with the example ...

(AI_HYDRA_LEO_MISSING_COMMA)

doc/descriptors.md

[misspelling] ~134-~134: Use “a” instead of ‘an’ if the following word doesn’t start with a vowel sound, e.g. ‘a sentence’, ‘a university’.
Context: ... are: 1. Every participant generates an xpub. The most straightforward way is t...

(EN_A_VS_AN)


[uncategorized] ~150-~150: The abbreviation “e.g.” (= for example) requires two periods.
Context: ... to the network. Note that any wallet (eg one of the signers or multisig) is capa...

(E_G)


[grammar] ~153-~153: The verb “daisy-chained” is spelled with a hyphen.
Context: ...n included in a block You may prefer a daisy chained signing flow where each participant sig...

(DAISY_CHAIN_HYPHEN)

🪛 Ruff (0.8.2)
test/functional/wallet_multisig_descriptor_psbt.py

58-58: f-string without any placeholders

Remove extraneous f prefix

(F541)


59-59: f-string without any placeholders

Remove extraneous f prefix

(F541)

🔇 Additional comments (109)
src/script/interpreter.h (4)

124-124: Add optional parameter to Init:
Introducing the bool force = false parameter adds flexibility to the initialization of PrecomputedTransactionData. Ensure that all call sites correctly handle the new parameter, especially if force = true can override normal safety checks.


159-167: New MissingDataBehavior enum:
Defining a strongly typed enum for missing data behavior clarifies intent and promotes safer handling of missing data. However, be cautious when using ASSERT_FAIL in non-consensus code, as it can lead to abrupt terminations if triggered unexpectedly.


173-173: Store MissingDataBehavior as a member:
Adding m_mdb to capture the desired missing data behavior helps ensure consistent usage throughout the checker’s lifecycle.


182-183: Updated constructor signatures:
These constructors now accept MissingDataBehavior, aligning the transaction checker’s behavior with other code paths that handle incomplete data. This change makes it explicit how missing data is treated.

src/psbt.cpp (6)

40-46: Merging extended public keys:
This block merges xpub sets from another PSBT. The insert operations look correct, albeit potentially O(N) for large sets. If large-scale merges are frequent, consider more efficient containers or merging strategies.


73-81: UTXO hash consistency check:
Ensuring non_witness_utxo->GetHash() matches prevout.hash is a vital safeguard against mismatched or tampered UTXOs. This prevents subtle transaction malleability or security flaws.


140-143: Merge cryptographic preimages:
Adding ripemd160_preimages, sha256_preimages, hash160_preimages, and hash256_preimages merges additional fields safely. This helps finalize signature operations that rely on these modified preimages.


Line range hint 236-276: Enhanced SignPSBTInput:
Now accepts a PrecomputedTransactionData* txdata pointer, which optimizes signature creation by bypassing repeated hashing. The fallback to DUMMY_SIGNATURE_CREATOR ensures partial signing if data is missing. Make sure any unexpected missing data triggers the correct behavior (FAIL vs. ASSERT_FAIL).


296-298: FinalizePSBT uses precomputation:
By calling PrecomputePSBTData and passing the results to SignPSBTInput, finalization can reuse hashed data. This should improve performance on bigger transactions.


370-377: GetVersion() fallback to 0:
Returning 0 when m_version is unset prevents accidental use of uninitialized data. Consider documenting what version 0 implies in the PSBT specification continuum.

src/script/sign.cpp (7)

12-12: Include script/keyorigin.h:
This import is appropriate since the file references key origins in KeyOriginInfo.


20-24: Constructor with MissingDataBehavior::FAIL:
This constructor ensures incomplete data triggers a verifiable error. It helps maintain correctness in consensus-sensitive logic.


26-32: Second constructor honors precomputed data:
Allowing a PrecomputedTransactionData* txdata optimizes repeated hashing. This design is flexible for signers that do or do not supply precomputed data.


40-40: Use m_txdata in SignatureHash:
This line ensures the signature creation reuses precomputed results when available, improving efficiency for multi-input transactions.


265-265: MutableTransactionSignatureChecker uses MissingDataBehavior::FAIL:
Makes it clear that incomplete data leads to a failed signature check instead of an uncontrolled assertion. This is safer for typical wallet usage.


410-429: Precompute transaction data in SignTransaction:
The addition of txdata.Init(...) with all spent outputs (or none if missing) centralizes hashing logic. This is a good approach to reduce duplication and improve signing performance.


444-444: ProduceSignature usage note:
Explicitly calling ProduceSignature with the newly introduced txdata ensures robust signing. No further issues spotted here.

test/functional/rpc_psbt.py (4)

50-53: Test locked wallet scenario:
This block confirms that walletprocesspsbt disallows signing when locked. It is a solid test ensuring correct error handling:


54-57: Test processing without signing:
Ensures that walletprocesspsbt can still process the transaction and return an incomplete PSBT. This is valuable for external signing flows.


58-59: Unlock wallet with walletpassphrase:
Needed to proceed with signing tests. Straightforward usage, no issues identified.


61-63: Separate partial signature from finalization:
Testing both partial and final PSBT flows is a great demonstration of the newly added finalize parameter. The test ensures distinct output for each.

src/wallet/scriptpubkeyman.h (2)

361-361: Re-check parameter usage.
The updated signature with finalize is good for flexibility. Ensure downstream callers handle the new parameter consistently, especially for hardware wallet flows.


585-585: Enforce consistent usage of txdata.
This signature includes txdata for better signing efficiency. Verify that all call sites (e.g., walletprocesspsbt) are passing a properly precomputed transaction data object to avoid performance regressions.

src/psbt.h (20)

13-13: Check header includes consistency.
These additional includes (<script/keyorigin.h>, <span.h>, <streams.h>) should remain well-scoped and not introduce circular dependencies.

Also applies to: 16-17


37-41: Input type constants expansion.
Adding PSBT_IN_RIPEMD160, PSBT_IN_SHA256, PSBT_IN_HASH160, PSBT_IN_HASH256, and PSBT_IN_PROPRIETARY aligns with multi-hash preimage support. Confirm all relevant code paths respect these new vars, especially in edge cases.


46-46: Additional output type constant.
PSBT_OUT_PROPRIETARY extends custom data usage on outputs. Double-check that serialization handles unknown custom keys gracefully.


56-58: PSBT version sanity.
PSBT_HIGHEST_VERSION and the new version parameters help. Make sure to handle future expansions gracefully and maintain backward-compatibility for older versions.


97-114: Vector serialization macros.
The utility functions (SerializeToVector, UnserializeFromVector) are crucial. Confirm they handle malformed or partial data robustly, especially in multi-field scenarios.


171-174: Additional preimage maps.
The new maps for storing hash preimages (ripemd160_preimages, sha256_preimages, etc.) expand usage significantly. Validate there's no duplication or excessive memory usage for large sets of preimages.


189-189: Condition for writing nonWitnessUTXO.
SerializeToVector(...) for the non-witness UTXO is gated by if (non_witness_utxo). Ensure that placeholders or partial states do not break.


196-196: Partial signatures iteration.
Iterates over partial_sigs. Make sure no concurrency issues appear if background signers operate. Typically safe if single-threaded.


208-208: RedeemScript gating.
Explicit if (!redeem_script.empty()) is a good clarity approach. No action needed, but ensure to handle nested scripts if relevant.


213-214: HD keypath serialization invocation.
Collects BIP32 derivations in a single pass. This is consistent. Confirm no repeated pubkey collisions.


221-226: SHA256 preimage storage.
Same approach as RIPEMD160. Mirror the same validations.


227-232: HASH160 preimage handling.
Hash approach is consistent. Keep an eye on collisions or repeated preimage data.


233-237: HASH256 preimage block.
Similar structure as preceding. Good uniform code.


242-242: Final scriptSig gating.
Clear check on final scriptSig presence. Straightforward approach.


281-283: Key extraction from the beginning of the buffer.
Using SpanReader skey(...). Confirm no out-of-bounds reads if the key array is empty or truncated.


353-373: RIPEMD160 preimage read block.
Throws on duplicates. This is good for preventing collisions. Confirm exceptions are caught at higher layers.
[approve]


374-394: SHA256 preimage read block.
Symmetrical to RIPEMD160 approach. Looks consistent.


395-415: HASH160 preimage read block.
Again symmetrical, no immediate issues.


437-450: Proprietary input read block.
Throws on duplicates. This is consistent with the design for m_proprietary.
[approve]


868-868: PrecomputePSBTData function addition.
New function PrecomputePSBTData(psbt). Confirm that it does not re-hash data excessively if large or repeated.

src/wallet/scriptpubkeyman.cpp (1)

736-736: Comprehensive FillPSBT override.
Ensures that each input is processed for partial signing. Verify there's no concurrency risk or partial updates if exceptions occur.

src/rpc/rawtransaction.cpp (14)

7-7: Expanded includes in rawtransaction.
The additional #include <node/psbt.h> ensures PSBT support. Verify no duplication or cyclical references in Node modules.


1331-1350: Global Xpubs decoding display.
The array of global_xpubs is appended to the decode result. This is quite helpful, but ensure flows that do not use xpubs skip gracefully.


1407-1416: Proprietary input block.
Extracts identifier, subtype, key, and value. Ensure forging such data doesn't cause excessive data usage or memory issues.


1442-1451: Output proprietary map decode.
Same pattern as inputs. The uniform approach is good for maintainability.


1478-1494: Global xpub array in decodepsbt.
Pushes the new xpub data into JSON. The code is consistent with existing fields.


1495-1509: Proprietary global data in decodepsbt.
Parallel to xpub approach, ensures any new global proprietary data is included in the resulting JSON.


1590-1598: Ripemd160 preimages block in decode.
Mirrors the serialization. Keep the same caution about large data.


1599-1607: Sha256 preimages block.
The structure is consistent. No immediate issues.


1608-1616: Hash160 preimages block.
Same pattern. The uniform design is beneficial.


1617-1625: Hash256 preimages block.
Replicates the same logic, consistent.


1626-1639: Proprietary input fields block.
Again symmetrical. Watch for collisions in key usage.


2023-2023: PrecomputePSBTData usage in utxoupdatepsbt.
This line ensures the transaction data is precomputed only once for multiple sign calls. Good for performance. Double-check that partial updates are recognized.


2034-2034: SignPSBTInput called with public_provider.
Helps fill script/keypath info without private keys. Clean separation of roles.


2113-2119: Joining Xpub sets in joinpsbts.
Confirms that each xpub set is inserted or merged. Ensure no conflicts if duplicates have different properties.

src/wallet/rpcwallet.cpp (7)

4451-4451: Introduced "sign" parameter looks good.

This boolean parameter aligns with the documentation to optionally sign the PSBT.


4460-4460: Introduced "finalize" parameter is consistent.

This boolean parameter to optionally finalize the PSBT is well-documented and cleanly implemented.


4501-4501: Defaulting "finalize" to true is correct.

The logic cleanly ensures a fallback to true when user input is absent, aligning with the updated method signature.


4503-4503: Blank line change only.


4504-4504: Ensuring wallet is unlocked if signing is requested.

This condition is correct: users are prompted to unlock the wallet when needed, preventing accidental failures.


4505-4505: Blank line change only.


4506-4506: Pass "finalize" correctly to FillPSBT.

Including the new parameter in the call to FillPSBT completes the feature set for the finalize step.

src/wallet/wallet.cpp (2)

3103-3108: Enhance PSBT filling with 'finalize' parameter
This newly introduced parameter provides additional flexibility when filling the PSBT, enabling optional finalization after signing. The usage of PrecomputedTransactionData txdata improves efficiency by avoiding repeated signature hashing.


3135-3135: Delegate finalize control to ScriptPubKeyMans
Passing the finalize flag to each ScriptPubKeyMan ensures consistent behavior across all managers, preventing incomplete PSBTs due to missing finalization steps.

src/wallet/test/wallet_test_fixture.cpp (2)

7-7: Include scheduler for resource management
Adding <scheduler.h> allows the test fixture to properly stop the scheduler in its destructor, avoiding potential thread or scheduler resource leaks.


19-22: Clean up node scheduler in destructor
Explicitly stopping the scheduler prevents spurious threads from continuing after the fixture is destroyed, improving test stability and preventing memory leaks.

src/wallet/test/wallet_test_fixture.h (1)

22-22: Add custom destructor to WalletTestingSetup
Declaring the destructor here corresponds with the implementation that stops the scheduler, ensuring consistent resource cleanup across test lifecycles.

src/script/sigcache.h (1)

29-29: Use ASSERT_FAIL to handle missing data
Incorporating MissingDataBehavior::ASSERT_FAIL in the constructor ensures that signature verification immediately fails if any required data is missing, leading to stricter checks and earlier detection of errors.

src/script/keyorigin.h (1)

22-39: Implement a robust lexicographical comparison operator
This operator compares key fingerprints first, then path size, then path elements, ensuring deterministic ordering of KeyOriginInfo objects. The usage of memcmp for fingerprints is straightforward and the fallback to lexicographical compare for paths is correct for multi-account setups.

src/test/fuzz/script_flags.cpp (1)

45-45: Ensure the chosen missing-data policy is appropriate for fuzzing.
Using MissingDataBehavior::ASSERT_FAIL here means the fuzz target will trigger an assertion whenever data is missing. While this may be intentional to catch bugs early, ensure it doesn't prevent exploring other fuzzing scenarios (e.g., gracefully skipping incomplete inputs).

src/script/bitcoinconsensus.cpp (1)

93-93: Consistent handling of missing data.
The TransactionSignatureChecker call here now includes MissingDataBehavior::FAIL. Verify that callers of dashconsensus_verify_script gracefully handle a failure path when data is incomplete or missing. This approach helps avoid processing partially valid transactions.

src/script/sign.h (1)

46-47: Validate consistent usage of the new constructor.
The new constructor taking PrecomputedTransactionData* txdata ensures signatures can use precomputed data for improved efficiency. Verify all callers properly initialize the txdata pointer to avoid null dereferences.

src/node/psbt.cpp (2)

25-26: Efficiently precomputing PSBT data.
Initializing txdata with PrecomputePSBTData here is a clean approach that standardizes the usage of precomputed transaction data. Confirm that PrecomputePSBTData(psbtx) behaves correctly even if inputs are partially signed or incomplete.


65-65: Leverage precomputed data in SignPSBTInput.
Passing &txdata optimizes signing. Ensure all code paths (finalizers, signers, updaters) properly handle the existence of txdata and verify that no mismatch occurs if the PSBT has been modified after precomputation.

src/test/fuzz/script_sign.cpp (3)

8-8: Include for PSBT functionality.

This addition correctly references the PSBT definitions. No issues noted.


46-46: Validate the new compact size approach.

Using CompactSizeWriter(fuzzed_data_provider.ConsumeIntegral<uint8_t>()) is fine for ensuring a compact size format. However, verify that the consumed integer value is always within the expected range for your fuzz tests.


64-64: Consistent serialization format.

Again, switching to CompactSizeWriter seems correct. Ensure that both serialization and deserialization handle the full range of values returned by the fuzzer.

src/script/signingprovider.h (1)

11-11: Explicit inclusion of keyorigin.

Removing forward declarations for KeyOriginInfo and adding #include <script/keyorigin.h> clarifies dependencies.

src/wallet/test/psbt_wallet_tests.cpp (1)

74-74: Integration of precomputed data.

The call to FillPSBT with PrecomputePSBTData(psbtx) ensures that precomputed transaction data is leveraged. This is generally a good practice for improved signing performance and correctness, particularly when used repeatedly.

src/test/multisig_tests.cpp (8)

80-80: Assert missing data behaviors.

Specifying MissingDataBehavior::ASSERT_FAIL ensures validation fails if required data is missing. This provides more robust testing of multisig scenarios.


87-87: Enhanced error handling.

Including MissingDataBehavior::ASSERT_FAIL clarifies that missing script data in multisig checks triggers a failure, aligning with stricter testing.


93-93: Ensuring strict evaluation.

This parameter ensures no silent passing of incomplete data, improving test reliability for partial signatures.


104-104: Behavior clarity for single key checks.

Including the explicit missing-data behavior helps catch incomplete signature data. This encourages more transparent debugging when a single key is tested.


109-109: Consistent error handling.

Ensuring the script fails clearly when data is missing prevents false positives in negative test cases.


115-115: Strengthening the negative scenario.

Applying MissingDataBehavior::ASSERT_FAIL affirms that an invalid or missing signature element triggers SCRIPT_ERR_SIG_DER, consistent with the test's intent.


127-127: Robust escrow condition checks.

Mandating ASSERT_FAIL ensures that any missing signature data in this escrow test scenario leads to an immediate test failure, thus verifying accurate multi-key handling.


132-132: Final confirmation of escrow failure modes.

This approach conclusively enforces that incomplete data for escrow-based multisig scripts fails predictably.

src/pubkey.h (2)

132-136: Confirm consistent ordering with existing comparison operators.
The new operator> parallels operator< logic and appears correct. Ensure all usages rely on consistent key size assumptions and memory comparisons.


270-278: Validate chaincode ordering after key comparison.
The operator< implementation is logically sound, comparing pubkey first, then chaincode. Confirm this matches intended lexicographical ordering in all use cases.

src/pubkey.cpp (2)

299-303: No error handling for invalid version bytes.
The method simply stores version bytes and calls Encode(). Confirm if undesired versions can cause issues downstream and consider adding basic safety checks or logging.


305-309: Decode flow matches Encode logic.
DecodeWithVersion directly mirrors EncodeWithVersion, which is consistent and straightforward. Verify that outside code properly checks the decoded version when necessary.

src/qt/psbtoperationsdialog.cpp (2)

78-78: Handle unlock failures more robustly.
Initialization of WalletModel::UnlockContext ctx can fail if the user cancels unlock. Confirm upstream logic handles partial user interaction (e.g., passphrases, hardware prompts).


90-92: Clarity improved by locking check.
This conditional now clearly distinguishes a locked wallet scenario from a partially signed transaction scenario. The warning message is user-friendly and informative.

src/test/script_p2sh_tests.cpp (1)

44-44: Ensure consistent behavior handling missing data.
Including MissingDataBehavior::ASSERT_FAIL ensures that this call fails explicitly if any data is missing. Verify all callers are prepared to handle this behavior, and confirm corresponding test coverage.

src/coinjoin/server.cpp (1)

559-559: Confirm no silent failures.
By passing MissingDataBehavior::ASSERT_FAIL, any unexpected missing data will force a failure. Ensure this is desired for all potential code paths, preventing silent failures in production.

test/functional/test_runner.py (1)

254-254: New test script added to BASE_SCRIPTS.
The wallet_multisig_descriptor_psbt.py script is now part of the default suite. Confirm it runs successfully in CI and does not introduce unintended side effects or extend runtime excessively.

src/test/evo_deterministicmns_tests.cpp (1)

232-232: Stricter verification on signature checks.
Using MissingDataBehavior::ASSERT_FAIL ensures the test will halt on incomplete data. Verify that any missing amount data triggers a clear failure message, aiding in debugging potential input issues.

src/script/interpreter.cpp (1)

1519-1520: Ensure consistency with the new parameter signature.
The explicit template instantiations for PrecomputedTransactionData::Init now include the bool force parameter. Verify that all call sites match the updated signature to avoid linking errors or inconsistent usage.

src/test/script_tests.cpp (2)

Line range hint 129-138: Consistent use of MissingDataBehavior::ASSERT_FAIL.
Passing ASSERT_FAIL ensures that tests fail fast when transaction data is missing. Validate whether these checks match the intended behavior for test coverage, as they will trigger a hard assert rather than a soft failure.


Line range hint 1014-1094: Uniform approach to missing data checks.
All newly-updated lines use MissingDataBehavior::ASSERT_FAIL in MutableTransactionSignatureChecker. This is consistent, but double-check that none of these tests expect a graceful fallback. If correct, this direct approach is suitable for debugging missing data during test runs.

doc/descriptors.md (1)

120-160: LGTM! Well-structured multisig documentation.

The new section provides clear, step-by-step instructions for creating and using M-of-N multisig wallets. The inclusion of disclaimers and references to functional tests as documentation is particularly valuable.

🧰 Tools
🪛 LanguageTool

[misspelling] ~134-~134: Use “a” instead of ‘an’ if the following word doesn’t start with a vowel sound, e.g. ‘a sentence’, ‘a university’.
Context: ... are: 1. Every participant generates an xpub. The most straightforward way is t...

(EN_A_VS_AN)


[uncategorized] ~150-~150: The abbreviation “e.g.” (= for example) requires two periods.
Context: ... to the network. Note that any wallet (eg one of the signers or multisig) is capa...

(E_G)


[grammar] ~153-~153: The verb “daisy-chained” is spelled with a hyphen.
Context: ...n included in a block You may prefer a daisy chained signing flow where each participant sig...

(DAISY_CHAIN_HYPHEN)

src/test/transaction_tests.cpp (1)

99-99: LGTM! Enhanced error handling for script verification.

The addition of MissingDataBehavior::ASSERT_FAIL parameter improves the robustness of transaction script verification by enforcing strict error handling for missing data.

Let's verify the consistent usage of this parameter across the codebase:

✅ Verification successful

Consistent usage of MissingDataBehavior parameter verified

The search results confirm that the MissingDataBehavior parameter is consistently used across the codebase:

  • In test files (transaction_tests.cpp, script_tests.cpp, multisig_tests.cpp, etc.), ASSERT_FAIL is used for strict verification
  • In production code (sign.cpp, bitcoinconsensus.cpp), FAIL is used for actual transaction processing
  • The parameter is properly passed through the inheritance chain via constructors in sigcache.h and interpreter.h
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistent usage of MissingDataBehavior::ASSERT_FAIL
# across transaction verification code

# Search for TransactionSignatureChecker constructor calls
rg -A 2 "TransactionSignatureChecker.*\(" 

# Search for MissingDataBehavior enum usage
rg "MissingDataBehavior::"

Length of output: 21304

src/serialize.h (1)

730-741: LGTM! Clean implementation of CompactSizeWriter.

The new class follows good design principles:

  • Encapsulates compact size serialization logic
  • Uses composition over inheritance
  • Follows single responsibility principle
  • Consistent with existing serialization patterns
test/functional/data/rpc_psbt.json (3)

21-21: LGTM: Invalid test vector added for negative testing.

The added base64-encoded PSBT test vector will help ensure that invalid PSBTs are properly rejected.


38-46: LGTM: Valid test vectors added for positive testing.

The added base64-encoded PSBT test vectors will help ensure that valid PSBTs are properly accepted. These test cases appear to cover:

  • Basic PSBT operations
  • Different transaction structures
  • Various signing scenarios

148-148: LGTM: Proper JSON structure maintained.

The closing brace maintains the proper JSON structure.

Comment on lines +176 to +177
std::set<PSBTProprietary> m_proprietary;
std::optional<int> sighash_type;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

m_proprietary set usage.
std::set<PSBTProprietary> ensures no duplicates, but custom ordering is defined. Confirm PSBTProprietary::operator< matches all uniqueness criteria to avoid collisions.

Comment on lines +1387 to +1403
{RPCResult::Type::OBJ_DYN, "ripemd160_preimages", /*optional=*/ true, "",
{
{RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
}},
{RPCResult::Type::OBJ_DYN, "sha256_preimages", /*optional=*/ true, "",
{
{RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
}},
{RPCResult::Type::OBJ_DYN, "hash160_preimages", /*optional=*/ true, "",
{
{RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
}},
{RPCResult::Type::OBJ_DYN, "hash256_preimages", /*optional=*/ true, "",
{
{RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
}},
{RPCResult::Type::OBJ_DYN, "unknown", /*optional=*/ true, "The unknown input fields",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Ripemd160 preimage decoding.
Thus far consistent with earlier code. Potential risk if large preimage data is inserted in a spam scenario – consider length checks.

@UdjinM6 UdjinM6 added the RPC Some notable changes to RPC params/behaviour/descriptions label Dec 26, 2024
Copy link

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK aba9370

@kwvg kwvg requested review from knst and PastaPastaPasta and removed request for knst and PastaPastaPasta January 7, 2025 07:09
Copy link
Member

@PastaPastaPasta PastaPastaPasta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK aba9370

@PastaPastaPasta PastaPastaPasta merged commit 3edc738 into dashpay:develop Jan 8, 2025
24 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RPC Some notable changes to RPC params/behaviour/descriptions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants