Directly operate with CMutableTransaction in SignSignature #13309

pull martinus wants to merge 1 commits into bitcoin:master from martinus:SignSignature-with-CMutableTransaction changing 5 files +55 −46
  1. martinus commented at 6:41 am on May 23, 2018: contributor

    Refactored TransactionSignatureCreator into a templated GenericTransactionSignatureCreator that works with both CMutableTransaction and CTransaction.

    The advantage is that now in SignSignature, the MutableTransactionSignatureCreator can now operate directly with the CMutableTransaction without the need to copy the data into a CTransaction.

    Running all unit tests brings a very noticable speedup on my machine:

    48.4 sec before this change
    36.4 sec with this change
    --------
    12.0 seconds saved
    

    running only --run_test=transaction_tests/test_big_witness_transaction:

    16.7 sec before this change
     5.9 sec with this change
    --------
    10.8 seconds saved
    

    This relates to my first attempt with the const_cast hack #13202, and to the slow unit test issue #10026.

    Also see #13050 which modifies the tests but not the production code (like this PR) to get a speedup.

  2. martinus renamed this:
    Faster unit tests: directloy operate with CMutableTransaction
    Directly operate with CMutableTransaction in SignSignature (faster unit tests)
    on May 23, 2018
  3. promag commented at 8:57 am on May 23, 2018: member
    Nice improvement, concept ACK.
  4. in src/script/interpreter.h:128 in c3e1a21902 outdated
    123@@ -124,7 +124,8 @@ struct PrecomputedTransactionData
    124     uint256 hashPrevouts, hashSequence, hashOutputs;
    125     bool ready = false;
    126 
    127-    explicit PrecomputedTransactionData(const CTransaction& tx);
    128+    template<class T>
    129+    PrecomputedTransactionData(const T& tx);
    


    Empact commented at 9:19 am on May 23, 2018:
    Why drop explicit here? I don’t see changes to the call sites.

    martinus commented at 10:26 am on May 23, 2018:
    you are right, I probably should not drop that.
  5. Empact commented at 9:25 am on May 23, 2018: member
    Concept ACK
  6. in src/script/interpreter.h:166 in c3e1a21902 outdated
    161@@ -160,10 +162,11 @@ class BaseSignatureChecker
    162     virtual ~BaseSignatureChecker() {}
    163 };
    164 
    165-class TransactionSignatureChecker : public BaseSignatureChecker
    166+template<class T>
    167+class GenericTransactionSignatureChecker : public BaseSignatureChecker
    


    promag commented at 9:34 am on May 23, 2018:
    nit, drop Generic prefix?

    martinus commented at 10:12 am on May 23, 2018:
    I’ve added it so that the names TransactionSignatureChecker and MutableTransactionSignatureChecker are still valid as used before

    promag commented at 10:38 am on May 23, 2018:
    Right.
  7. promag commented at 11:32 am on May 23, 2018: member
    utACK after squash.
  8. martinus force-pushed on May 23, 2018
  9. practicalswift commented at 2:31 pm on May 23, 2018: contributor

    Very nice!

    Concept ACK

  10. in src/script/sign.h:39 in b4fa297e7e outdated
    35@@ -36,26 +36,23 @@ class BaseSignatureCreator {
    36     virtual bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const =0;
    37 };
    38 
    39-/** A signature creator for transactions. */
    40-class TransactionSignatureCreator : public BaseSignatureCreator {
    41-    const CTransaction* txTo;
    42+template <class T>
    


    sipa commented at 5:58 pm on May 24, 2018:

    You don’t actually need a template here; all existing uses of TransactionSignatureCreator become more efficient to rewrite using MutableTransactionSignatureCreator (intuitively this makes sense - you can’t add a signature to an immutable transaction):

     0diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
     1index 2a2f8b5b20..c2b1915b11 100644
     2--- a/src/wallet/wallet.cpp
     3+++ b/src/wallet/wallet.cpp
     4@@ -2608,7 +2608,6 @@ bool CWallet::SignTransaction(CMutableTransaction &tx)
     5     AssertLockHeld(cs_wallet); // mapWallet
     6 
     7     // sign the new tx
     8-    CTransaction txNewConst(tx);
     9     int nIn = 0;
    10     for (const auto& input : tx.vin) {
    11         std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(input.prevout.hash);
    12@@ -2618,7 +2617,7 @@ bool CWallet::SignTransaction(CMutableTransaction &tx)
    13         const CScript& scriptPubKey = mi->second.tx->vout[input.prevout.n].scriptPubKey;
    14         const CAmount& amount = mi->second.tx->vout[input.prevout.n].nValue;
    15         SignatureData sigdata;
    16-        if (!ProduceSignature(*this, TransactionSignatureCreator(&txNewConst, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) {
    17+        if (!ProduceSignature(*this, MutableTransactionSignatureCreator(&tx, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) {
    18             return false;
    19         }
    20         UpdateTransaction(tx, nIn, sigdata);
    21@@ -3040,14 +3039,13 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
    22 
    23         if (sign)
    24         {
    25-            CTransaction txNewConst(txNew);
    26             int nIn = 0;
    27             for (const auto& coin : selected_coins)
    28             {
    29                 const CScript& scriptPubKey = coin.txout.scriptPubKey;
    30                 SignatureData sigdata;
    31 
    32-                if (!ProduceSignature(*this, TransactionSignatureCreator(&txNewConst, nIn, coin.txout.nValue, SIGHASH_ALL), scriptPubKey, sigdata))
    33+                if (!ProduceSignature(*this, MutableTransactionSignatureCreator(&txNew, nIn, coin.txout.nValue, SIGHASH_ALL), scriptPubKey, sigdata))
    34                 {
    35                     strFailReason = _("Signing transaction failed");
    36                     return false;
    
  11. martinus force-pushed on May 27, 2018
  12. martinus commented at 11:16 am on May 27, 2018: contributor
    As suggested by @sipa I have now removed the template for MutableTransactionSignatureCreator and used it directly in wallet.cpp. Also I ran the format script and squashed everything.
  13. sipa commented at 7:48 pm on May 27, 2018: member
    utACK d4ee6530535753292f73a8096a714b1be80f729f
  14. in src/script/sign.h:46 in d4ee653053 outdated
    44+    const CMutableTransaction* txTo;
    45     unsigned int nIn;
    46     int nHashType;
    47     CAmount amount;
    48-    const TransactionSignatureChecker checker;
    49+    const GenericTransactionSignatureChecker<CMutableTransaction> checker;
    


    Empact commented at 2:11 am on May 29, 2018:
    You can use MutableTransactionSignatureChecker here.
  15. MarcoFalke added the label Refactoring on May 29, 2018
  16. in src/script/interpreter.cpp:1107 in d4ee653053 outdated
    1110-        fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {}
    1111-
    1112+    CTransactionSignatureSerializer(const T& txToIn, const CScript& scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn),
    1113+                                                                                                                         fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)),
    1114+                                                                                                                         fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE),
    1115+                                                                                                                         fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {}
    


    MarcoFalke commented at 5:24 pm on May 29, 2018:
    style-nit: you can move the : to the next line to avoid excessive white space (which looks confusing in the diff and in editors with limited width.) sytle-nit: you could keep the empty new line between the constructor and the method to keep the diff minimal.
  17. in src/script/sign.cpp:17 in d4ee653053 outdated
    13@@ -14,9 +14,8 @@
    14 
    15 typedef std::vector<unsigned char> valtype;
    16 
    17-TransactionSignatureCreator::TransactionSignatureCreator(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
    18-
    19-bool TransactionSignatureCreator::CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
    20+MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
    


    MarcoFalke commented at 5:26 pm on May 29, 2018:
    sytle-nit: you could keep the empty new line between the constructor and the method to keep the diff minimal?
  18. MarcoFalke approved
  19. MarcoFalke commented at 5:27 pm on May 29, 2018: member
    utACK d4ee653053 beside style-nits
  20. MarcoFalke commented at 5:30 pm on May 29, 2018: member
    Tagged with “refactoring” since the only change should be removing the redundant member MutableTransactionSignatureCreator::tx
  21. MarcoFalke renamed this:
    Directly operate with CMutableTransaction in SignSignature (faster unit tests)
    Directly operate with CMutableTransaction in SignSignature
    on May 29, 2018
  22. Generic TransactionSignatureCreator works with both CTransaction and CMutableTransaction
    Templated version so that no copying of CMutableTransaction into a CTransaction is
    necessary. This speeds up the test case transaction_tests/test_big_witness_transaction
    from 7.9 seconds to 3.1 seconds on my machine.
    6b8b63af14
  23. martinus force-pushed on May 30, 2018
  24. martinus commented at 2:04 pm on May 30, 2018: contributor
    In 6b8b63a I’ve fixed all the nits, tried to keep the diff minimal, and squashed it again
  25. MarcoFalke commented at 2:20 pm on May 30, 2018: member
    re-utACK 6b8b63af1461dc11ffd813401e2c36fa44656715
  26. sipa commented at 10:56 pm on May 30, 2018: member
    re-utACK 6b8b63af1461dc11ffd813401e2c36fa44656715
  27. lucash-dev commented at 2:24 am on May 31, 2018: contributor
    Tested locally with similar speed-up. Pretty cool. ACK https://github.com/bitcoin/bitcoin/commit/6b8b63af1461dc11ffd813401e2c36fa44656715.
  28. fanquake commented at 7:08 am on May 31, 2018: member

    master (472fe8a):

    0$ time src/test/test_bitcoin --run_test=transaction_tests/test_big_witness_transaction
    1Running 1 test case...
    2*** No errors detected
    3real	0m20.634s
    4user	0m21.253s
    5sys	0m0.163s
    
    0$ time src/test/test_bitcoin
    1Running 291 test cases...
    2*** No errors detected
    3real	1m23.903s
    4user	0m56.010s
    5sys	0m40.136s
    

    This PR (6b8b63a):

    0time src/test/test_bitcoin --run_test=transaction_tests/test_big_witness_transaction
    1Running 1 test case...
    2*** No errors detected
    3real	0m4.316s
    4user	0m4.961s
    5sys	0m0.157s
    
    0time src/test/test_bitcoin
    1Running 291 test cases...
    2*** No errors detected
    3real	1m7.374s
    4user	0m38.687s
    5sys	0m41.480s
    
  29. laanwj commented at 8:39 am on May 31, 2018: member
    utACK 6b8b63af1461dc11ffd813401e2c36fa44656715
  30. laanwj merged this on May 31, 2018
  31. laanwj closed this on May 31, 2018

  32. laanwj referenced this in commit 36fc8052f6 on May 31, 2018
  33. martinus deleted the branch on Jun 1, 2018
  34. UdjinM6 referenced this in commit 3d00f2c563 on Jun 19, 2021
  35. UdjinM6 referenced this in commit 7a5b4f3aee on Jun 24, 2021
  36. UdjinM6 referenced this in commit f7c2a3844d on Jun 26, 2021
  37. UdjinM6 referenced this in commit 87c9b5c73e on Jun 26, 2021
  38. UdjinM6 referenced this in commit 3d4017d30d on Jun 28, 2021
  39. MarcoFalke locked this on Dec 16, 2021

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-12-18 18:12 UTC

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