Silent Payments: sending #28201

pull josibake wants to merge 26 commits into bitcoin:master from josibake:implement-bip352-sending changing 72 files +12865 −10021
  1. josibake commented at 4:37 pm on August 2, 2023: member

    This PR is part of integrating silent payments into Bitcoin Core. Status and tracking for the project is managed in #28536

    This PR depends on #28122 and is marked as a draft until it is merged. If interested in those commits, please review on #28122

    Pre-work / Refactors

    The first three commits are pre-work / refactors needed for this PR. They are broken out into the following PRS:

    Sending

    Silent Payments logic

    The main focus of this PR is:

    • Applying the Taptweak to a taproot internal private key (this is a copy-paste of the code for applying the taptweak in the signing process)
    • Getting a private key from a given scriptPubKey
    • Creating silent payment outputs
    • Applying the created scriptPubKeys back to the vector of CRecipients

    The functions are then used together to create silent payment outputs during CreateTransactionInternal.

    Final steps

    The last commits ensure that:

    • Coin selection is silent payments aware and knows to exclude taproot script path spends and inputs with unknown witness when funding a transaction which pays to a silent payment address
    • The change output type is correctly chosen when paying to a silent payment address
    • Functional tests
  2. DrahtBot commented at 4:37 pm on August 2, 2023: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage

    For detailed information about the code coverage, see the test coverage report.

    Reviews

    See the guideline for information on the review process. A summary of reviews will appear here.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #30050 (refactor, wallet: get serialized size of CRecipients directly by josibake)
    • #30048 (crypto: add NUMS_H const by josibake)
    • #30047 (refactor: Model the bech32 charlimit as an Enum by josibake)
    • #29325 (consensus: Store transaction nVersion as uint32_t by achow101)
    • #28333 (wallet: Construct ScriptPubKeyMans with all data rather than loaded progressively by achow101)
    • #27865 (wallet: Track no-longer-spendable TXOs separately by achow101)
    • #27286 (wallet: Keep track of the wallet’s own transaction outputs in memory by achow101)
    • #27260 (Enhanced error messages for invalid network prefix during address parsing. by russeree)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  3. DrahtBot added the label CI failed on Aug 2, 2023
  4. josibake renamed this:
    Silent Payments: implement sending
    Silent Payments: sending
    on Aug 3, 2023
  5. josibake force-pushed on Aug 3, 2023
  6. josibake force-pushed on Aug 3, 2023
  7. josibake force-pushed on Aug 3, 2023
  8. DrahtBot removed the label CI failed on Aug 3, 2023
  9. josibake commented at 9:50 am on August 3, 2023: member

    Maybe add a quick summary in the description with the main implementation differences relative to #24897. It seems a big one is that this doesn’t require an index!

    updated! I added the summary in #27827 and added links back to the parent PR in each of the child PRs.

  10. in src/wallet/spend.cpp:942 in 181e329a1d outdated
    899+    assert(tx_outpoints.size() > 0);
    900+    CKey scalar_ecdh_input = PrepareScalarECDHInput(input_private_keys, tx_outpoints);
    901+    std::vector<SilentPaymentRecipient> silent_payment_recipients = GroupSilentPaymentAddresses(silent_payment_destinations);
    902+    std::vector<CRecipient> outputs;
    903+    for (const auto& recipient : silent_payment_recipients) {
    904+        Sender sender{scalar_ecdh_input, recipient};
    


    josibake commented at 10:29 am on August 8, 2023:
    This does not need to be a struct, it can just be a function.
  11. in test/functional/wallet_silentpayments_sending.py:91 in e6f7458324 outdated
    86+            address=SILENT_PAYMENT_ADDRESS,
    87+            amount=21,
    88+        )
    89+        assert txid
    90+
    91+    def test_deterministic_send(self):
    


    BrandonOdiwuor commented at 5:32 pm on August 9, 2023:
    Incorporating logs within the test is crucial for offering transparent insight into the test’s progression, simplifying the identification of problems, and enhancing comprehension of the test’s overall behavior.
  12. in test/functional/wallet_silentpayments_sending.py:127 in e6f7458324 outdated
    122+                assert output["scriptPubKey"]["address"] == "bcrt1p5num3dvry0ffusg3s7v2j5fy025p95jtn6js65jlruwc69r9je2s6qfsj7"
    123+                break
    124+        else:
    125+            assert False
    126+
    127+    def test_address_reuse(self):
    


    BrandonOdiwuor commented at 5:34 pm on August 9, 2023:
    Also consider adding logs to this test as the ones above
  13. josibake force-pushed on Aug 30, 2023
  14. josibake force-pushed on Aug 30, 2023
  15. josibake force-pushed on Aug 31, 2023
  16. josibake force-pushed on Aug 31, 2023
  17. josibake force-pushed on Sep 8, 2023
  18. josibake force-pushed on Sep 11, 2023
  19. josibake force-pushed on Sep 11, 2023
  20. DrahtBot added the label CI failed on Sep 11, 2023
  21. josibake force-pushed on Sep 11, 2023
  22. josibake force-pushed on Sep 11, 2023
  23. josibake force-pushed on Sep 12, 2023
  24. josibake force-pushed on Sep 12, 2023
  25. josibake force-pushed on Sep 14, 2023
  26. DrahtBot removed the label CI failed on Sep 14, 2023
  27. DrahtBot added the label Needs rebase on Sep 19, 2023
  28. josibake force-pushed on Sep 21, 2023
  29. josibake force-pushed on Sep 21, 2023
  30. DrahtBot added the label CI failed on Sep 21, 2023
  31. DrahtBot removed the label Needs rebase on Sep 21, 2023
  32. DrahtBot removed the label CI failed on Sep 21, 2023
  33. josibake commented at 4:30 pm on September 26, 2023: member
    Note: send does not work, but sendall, sendtoaddress does
  34. josibake force-pushed on Oct 2, 2023
  35. josibake force-pushed on Oct 2, 2023
  36. DrahtBot added the label CI failed on Oct 2, 2023
  37. josibake force-pushed on Oct 3, 2023
  38. josibake force-pushed on Oct 3, 2023
  39. DrahtBot removed the label CI failed on Oct 4, 2023
  40. DrahtBot added the label Needs rebase on Oct 16, 2023
  41. josibake force-pushed on Jan 15, 2024
  42. DrahtBot removed the label Needs rebase on Jan 15, 2024
  43. DrahtBot commented at 9:36 pm on January 17, 2024: contributor

    🚧 At least one of the CI tasks failed. Make sure to run all tests locally, according to the documentation.

    Possibly this is due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    Leave a comment here, if you need help tracking down a confusing failure.

    Debug: https://github.com/bitcoin/bitcoin/runs/20505330863

  44. DrahtBot added the label CI failed on Jan 17, 2024
  45. josibake force-pushed on Jan 19, 2024
  46. DrahtBot removed the label CI failed on Jan 19, 2024
  47. willcl-ark added the label Wallet on Jan 24, 2024
  48. willcl-ark added the label Privacy on Jan 24, 2024
  49. DrahtBot added the label Needs rebase on Jan 26, 2024
  50. josibake force-pushed on Jan 26, 2024
  51. DrahtBot removed the label Needs rebase on Jan 26, 2024
  52. DrahtBot added the label CI failed on Feb 2, 2024
  53. DrahtBot removed the label CI failed on Feb 7, 2024
  54. DrahtBot added the label Needs rebase on Feb 20, 2024
  55. Squashed 'src/secp256k1/' changes from d8311688bd..3d08027789
    3d08027789 ci: enable silentpayments module
    85946762a5 tests: add BIP-352 test vectors
    bf349c2a08 silentpayments: add examples/silentpayments.c
    9a7106e19c silentpayments: add recipient light client support
    f113564298 silentpayments: add recipient scanning routine
    4fb8716f4f silentpayments: add opaque data type `public_data`
    987d829e8f silentpayments: add recipient label support
    14ca754578 silentpayments: add sender routine
    9b965927da silentpayments: implement output pubkey creation
    a0fcc2c780 silentpayments: implement shared secret creation
    13f203dacd silentpayments: add sortable recipient struct
    a9326bdd7a doc: add module description for silentpayments
    15d3e71cc1 build: add skeleton for new silentpayments (BIP352) module
    cc7d18a8a8 extrakeys: add secp256k1_pubkey_sort
    
    git-subtree-dir: src/secp256k1
    git-subtree-split: 3d080277895655e8274ee73aacd154c4ead143e3
    785ef3d558
  56. Merge commit '785ef3d5588dd6975bd4e8e067e6a62697867fe8' into refresh-secp256k1 bfe9876348
  57. Squashed 'src/secp256k1/' changes from 3d08027789..0270b14309
    0270b14309 labels: actually set the label
    
    git-subtree-dir: src/secp256k1
    git-subtree-split: 0270b1430981584582645161a04a4df67cd187bb
    7607d3cfbe
  58. Merge commit '7607d3cfbe3c86ad9d01f56437dd0a38fbb13045' into refresh-secp256k1 03a2a2d78a
  59. josibake force-pushed on Apr 22, 2024
  60. DrahtBot removed the label Needs rebase on Apr 22, 2024
  61. DrahtBot added the label CI failed on Apr 22, 2024
  62. DrahtBot commented at 9:52 pm on April 22, 2024: contributor

    🚧 At least one of the CI tasks failed. Make sure to run all tests locally, according to the documentation.

    Possibly this is due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    Leave a comment here, if you need help tracking down a confusing failure.

    Debug: https://github.com/bitcoin/bitcoin/runs/24114299414

  63. josibake force-pushed on Apr 27, 2024
  64. Squashed 'src/secp256k1/' changes from 0270b14309..92f592023f
    92f592023f ci: enable silentpayments module
    8ddc4574c9 tests: add BIP-352 test vectors
    8315abd830 silentpayments: add benchmark for `scan_outputs`
    f3a9516ec8 silentpayments: add examples/silentpayments.c
    7e11e7613b silentpayments: add recipient light client support
    3321771b0e silentpayments: add recipient scanning routine
    766567f099 silentpayments: add opaque data type `public_data`
    8d0bb06ce7 silentpayments: add recipient label support
    9c9bd057bc silentpayments: add sender routine
    036e688fd0 silentpayments: implement output pubkey creation
    1ffee123d6 silentpayments: implement shared secret creation
    7a5683260c silentpayments: add sortable recipient struct
    a8d6f4b8e1 doc: add module description for silentpayments
    1121a4d376 build: add skeleton for new silentpayments (BIP352) module
    7d2591ce12 Add secp256k1_pubkey_sort
    da515074e3 Merge bitcoin-core/secp256k1#1058: Signed-digit multi-comb ecmult_gen algorithm
    4c341f89ab Add changelog entry for SDMC
    a043940253 Permit COMB_BITS < 256 for exhaustive tests
    39b2f2a321 Add test case for ecmult_gen recoded = {-1,0,1}
    644e86de9a Reintroduce projective blinding
    07810d9abb Reduce side channels from single-bit reads
    a0d32b597d Optimization: use Nx32 representation for recoded bits
    e03dcc44b5 Make secp256k1_scalar_get_bits support 32-bit reads
    5005abee60 Rename scalar_get_bits -> scalar_get_bits_limb32; return uint32_t
    6247f485b6 Optimization: avoid unnecessary doublings in precomputation
    15d0cca2a6 Optimization: first table lookup needs no point addition
    7a33db35cd Optimization: move (2^COMB_BITS-1)/2 term into ctx->scalar_offset
    ed2a056f3d Provide 3 configurations accessible through ./configure
    5f7be9f6a5 Always generate tables for current (blocks,teeth) config
    fde1dfcd8d Signed-digit multi-comb ecmult_gen algorithm
    486518b350 Make exhaustive tests's scalar_inverse(&x,&x) work
    ab45c3e089 Initial gej blinding -> final ge blinding
    aa00a6b892 Introduce CEIL_DIV macro and use it
    REVERT: 0270b14309 labels: actually set the label
    REVERT: 3d08027789 ci: enable silentpayments module
    REVERT: 85946762a5 tests: add BIP-352 test vectors
    REVERT: bf349c2a08 silentpayments: add examples/silentpayments.c
    REVERT: 9a7106e19c silentpayments: add recipient light client support
    REVERT: f113564298 silentpayments: add recipient scanning routine
    REVERT: 4fb8716f4f silentpayments: add opaque data type `public_data`
    REVERT: 987d829e8f silentpayments: add recipient label support
    REVERT: 14ca754578 silentpayments: add sender routine
    REVERT: 9b965927da silentpayments: implement output pubkey creation
    REVERT: a0fcc2c780 silentpayments: implement shared secret creation
    REVERT: 13f203dacd silentpayments: add sortable recipient struct
    REVERT: a9326bdd7a doc: add module description for silentpayments
    REVERT: 15d3e71cc1 build: add skeleton for new silentpayments (BIP352) module
    REVERT: cc7d18a8a8 extrakeys: add secp256k1_pubkey_sort
    
    git-subtree-dir: src/secp256k1
    git-subtree-split: 92f592023f3f4d6a66724772349fbdc4967ab50f
    2bfd600177
  65. Merge commit '2bfd6001775c258f81e48b84624286fb9d898800' into refresh-secp256k1 41cf626708
  66. crypto: add NUMS_H const b7724e9523
  67. Compare COutPoints lexicographically cb0b68e9ca
  68. Model the bech32 charlimit as an Enum
    Bech32(m) was defined with a 90 character limit so that certain
    guarantees for error detection could be made for segwit addresses.
    However, there is nothing about the encoding scheme itself that requires
    a limit and in practice bech32(m) has been used without the 90 char
    limit (e.g. lightning invoices).
    
    Further, increasing the character limit doesn't do away with error
    detection, it simply lessons the guarantees.
    
    Model charlimit as an Enum, so that if a different address scheme is
    using bech32(m), the character limit for that address scheme can be
    used, rather than always using the 90 charlimit defined for segwit
    addresses.
    145978049e
  69. conf: add ECDH,SILENTPAYMENTS secp256k1 modules 9fec70a2d4
  70. Add "sp" HRP 41f426aa22
  71. Add V0SilentPaymentDestination address type 622c7a98b9
  72. common: add bip352.{h,cpp} secp256k1 module
    Wrap the silentpayments module from libsecp256k1. This is placed in
    common as it is intended to be used by:
    
      * RPCs: for parsing addresses
      * Wallet: for sending, receiving, spending silent payment outputs
      * Node: for creating silent payment indexes for light clients
    5b06ccf1dc
  73. wallet: disable sending to silent payment address
    Have `IsValidDestination` return false for silent payment destinations
    and set an error string when decoding a silent payment address.
    
    This prevents anyone from sending to a silent payment address before
    sending is implemented in the wallet, but also allows the functions to
    be used in the unit testing famework.
    e565824a47
  74. tests: add BIP352 test vectors as unit tests
    Use the test vectors to test sending and receiving. A few cases are not
    covered here, namely anything that requires testing specific to the
    wallet. For example:
    
    * Taproot script path spending is not tested, as that is better tested in
      a wallets coin selection / signing logic
    * Re-computing outputs during RBF is not tested, as that is better
      tested in a wallets RBF logic
    
    The unit tests are written in such a way that adding new test cases is
    as easy as updating the JSON file
    246e2a24c5
  75. wallet: get serialized size from CRecipient
    Now that a CRecipient holds a CTxDestination, we can get the serialized
    size using a visitor. This doesnt change any current behavior, but provides
    a nice generalization that can be used to apply special logic to a CTxDestination
    serialization in the future.
    a5a7e09f3a
  76. move-only: refactor CreateTransactionInternal
    Move the output serialization size calculation into the loop where the
    outputs are iterated over to calculate the total sum.
    
    Move the code for adding the the txoutputs to the transaction to after
    coin selection.
    
    While this code structure generally follows a more logical flow,
    the primary motivation for moving the code for adding outputs to the
    transaction sets us up nicely for silent payments (in a future PR):
    we need to know the input set before generating the final output scriptPubKeys.
    f1668c83e1
  77. crypto: add method for applying the taptweak
    The wallet returns an untweaked internal key for taproot outputs. If the
    output commits to a tree of scripts, this key needs to be tweaked with
    the merkle root. Even if the output does not commit to a tree of
    scripts, BIP341/342 recommend commiting to a hash of the public key.
    
    Depending how the taproot output was created, we need to apply the merkle
    root tweak or hash of the public key tweak before doing ECDH
    a1c6d22f3e
  78. wallet: get serialized size for `V0SilentPayments`
    BIP352 v0 specifies that a silent payment output is a taproot output.
    Taproot scriptPubKeys are a fixed size, so when calculating the
    serialized size for a CRecipient with a V0SilentPayments destination,
    use WitnessV1Taproot for the serialized txout size.
    797e21c8c1
  79. wallet: add method for retreiving a private key
    Add a method for retreiving a private key for a given scriptPubKey.
    If the scriptPubKey is a taproot output, tweak the private key with the
    merkle root or hash of the public key, if applicable.
    9c0de0f580
  80. wallet: make coin selection silent payment aware
    Add a flag to the `CoinControl` object if silent payment destinations
    are provided. Before adding the flag, call a function which checks if:
    
    * The wallet has private keys
    * The wallet is unlocked
    
    Without both of the above being true, we cannot send to a silent payment
    address.
    
    During coin selection, if this flag is set, skip taproot inputs when
    script spend data is available. This is based on the assumption that if
    a user provides script spend data, they don't have access to the key
    path spend. As future improvement, we could instead check to see if we
    have access to the key path spend, and only exclude the output when we
    don't regardless of whether or not the user provides script spend data.
    
    Also skip UTXOs of type `WITNESS_UNKNOWN`, although it is very unlikely
    our wallet would ever try to spend a witness unknown output.
    26fd679d83
  81. wallet: add `IsInputForSharedSecretDerivation` function 36c8b7ca11
  82. wallet: add `CreateSilentPaymentOutputs` function
    `CreateSilentPaymentsOutputs` gets the correct private keys, adds them
    together, groups the silent payment destinations and then generates the
    taproot script pubkeys. These are then passed back to
    CreateTransactionInternal, which uses these scriptPubKeys to update
    vecSend before adding them to the transaction outputs.
    27d1fe8178
  83. wallet: update TransactionChangeType
    If sending to a silent payment destination, the change type should be taproot
    aaa9353f53
  84. wallet: enable sending to silent payment address 94cae4d175
  85. tests: add sending functional tests a4edd78570
  86. josibake force-pushed on May 5, 2024
  87. DrahtBot removed the label CI failed on May 5, 2024
  88. DrahtBot added the label Needs rebase on May 20, 2024
  89. DrahtBot commented at 11:55 am on May 20, 2024: contributor

    🐙 This pull request conflicts with the target branch and needs rebase.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-06-29 07:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me