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

Directly operate with CMutableTransaction in SignSignature #13309

Merged

Conversation

martinus
Copy link
Contributor

@martinus martinus commented May 23, 2018

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.

@martinus martinus changed the title Faster unit tests: directloy operate with CMutableTransaction Directly operate with CMutableTransaction in SignSignature (faster unit tests) May 23, 2018
@promag
Copy link
Member

promag commented May 23, 2018

Nice improvement, concept ACK.

@@ -124,7 +124,8 @@ struct PrecomputedTransactionData
uint256 hashPrevouts, hashSequence, hashOutputs;
bool ready = false;

explicit PrecomputedTransactionData(const CTransaction& tx);
template<class T>
PrecomputedTransactionData(const T& tx);
Copy link
Member

Choose a reason for hiding this comment

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

Why drop explicit here? I don't see changes to the call sites.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

you are right, I probably should not drop that.

@Empact
Copy link
Member

Empact commented May 23, 2018

Concept ACK

@@ -160,10 +162,11 @@ class BaseSignatureChecker
virtual ~BaseSignatureChecker() {}
};

class TransactionSignatureChecker : public BaseSignatureChecker
template<class T>
class GenericTransactionSignatureChecker : public BaseSignatureChecker
Copy link
Member

Choose a reason for hiding this comment

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

nit, drop Generic prefix?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added it so that the names TransactionSignatureChecker and MutableTransactionSignatureChecker are still valid as used before

Copy link
Member

Choose a reason for hiding this comment

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

Right.

@promag
Copy link
Member

promag commented May 23, 2018

utACK after squash.

@martinus martinus force-pushed the SignSignature-with-CMutableTransaction branch from d621953 to b4fa297 Compare May 23, 2018 11:55
@practicalswift
Copy link
Contributor

Very nice!

Concept ACK

/** A signature creator for transactions. */
class TransactionSignatureCreator : public BaseSignatureCreator {
const CTransaction* txTo;
template <class T>
Copy link
Member

@sipa sipa May 24, 2018

Choose a reason for hiding this comment

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

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):

diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 2a2f8b5b20..c2b1915b11 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -2608,7 +2608,6 @@ bool CWallet::SignTransaction(CMutableTransaction &tx)
     AssertLockHeld(cs_wallet); // mapWallet
 
     // sign the new tx
-    CTransaction txNewConst(tx);
     int nIn = 0;
     for (const auto& input : tx.vin) {
         std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(input.prevout.hash);
@@ -2618,7 +2617,7 @@ bool CWallet::SignTransaction(CMutableTransaction &tx)
         const CScript& scriptPubKey = mi->second.tx->vout[input.prevout.n].scriptPubKey;
         const CAmount& amount = mi->second.tx->vout[input.prevout.n].nValue;
         SignatureData sigdata;
-        if (!ProduceSignature(*this, TransactionSignatureCreator(&txNewConst, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) {
+        if (!ProduceSignature(*this, MutableTransactionSignatureCreator(&tx, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) {
             return false;
         }
         UpdateTransaction(tx, nIn, sigdata);
@@ -3040,14 +3039,13 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
 
         if (sign)
         {
-            CTransaction txNewConst(txNew);
             int nIn = 0;
             for (const auto& coin : selected_coins)
             {
                 const CScript& scriptPubKey = coin.txout.scriptPubKey;
                 SignatureData sigdata;
 
-                if (!ProduceSignature(*this, TransactionSignatureCreator(&txNewConst, nIn, coin.txout.nValue, SIGHASH_ALL), scriptPubKey, sigdata))
+                if (!ProduceSignature(*this, MutableTransactionSignatureCreator(&txNew, nIn, coin.txout.nValue, SIGHASH_ALL), scriptPubKey, sigdata))
                 {
                     strFailReason = _("Signing transaction failed");
                     return false;

@martinus martinus force-pushed the SignSignature-with-CMutableTransaction branch from 62b53ea to d4ee653 Compare May 27, 2018 11:11
@martinus
Copy link
Contributor Author

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.

@sipa
Copy link
Member

sipa commented May 27, 2018

utACK d4ee6530535753292f73a8096a714b1be80f729f

unsigned int nIn;
int nHashType;
CAmount amount;
const TransactionSignatureChecker checker;
const GenericTransactionSignatureChecker<CMutableTransaction> checker;
Copy link
Member

@Empact Empact May 29, 2018

Choose a reason for hiding this comment

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

You can use MutableTransactionSignatureChecker here.

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

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

utACK d4ee653053 beside style-nits

CTransactionSignatureSerializer(const T& txToIn, const CScript& scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn),
fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)),
fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE),
fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {}
Copy link
Member

Choose a reason for hiding this comment

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

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.

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) {}

bool TransactionSignatureCreator::CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
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) {}
Copy link
Member

Choose a reason for hiding this comment

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

sytle-nit: you could keep the empty new line between the constructor and the method to keep the diff minimal?

@maflcko
Copy link
Member

maflcko commented May 29, 2018

Tagged with "refactoring" since the only change should be removing the redundant member MutableTransactionSignatureCreator::tx

@maflcko maflcko changed the title Directly operate with CMutableTransaction in SignSignature (faster unit tests) Directly operate with CMutableTransaction in SignSignature May 29, 2018
…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.
@martinus martinus force-pushed the SignSignature-with-CMutableTransaction branch from d4ee653 to 6b8b63a Compare May 30, 2018 14:02
@martinus
Copy link
Contributor Author

In 6b8b63a I've fixed all the nits, tried to keep the diff minimal, and squashed it again

@maflcko
Copy link
Member

maflcko commented May 30, 2018

re-utACK 6b8b63a

@sipa
Copy link
Member

sipa commented May 30, 2018

re-utACK 6b8b63a

@lucash-dev
Copy link
Contributor

lucash-dev commented May 31, 2018

Tested locally with similar speed-up. Pretty cool. ACK 6b8b63a.

@fanquake
Copy link
Member

fanquake commented May 31, 2018

master (472fe8a):

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

This PR (6b8b63a):

time src/test/test_bitcoin --run_test=transaction_tests/test_big_witness_transaction
Running 1 test case...
*** No errors detected
real	0m4.316s
user	0m4.961s
sys	0m0.157s
time src/test/test_bitcoin
Running 291 test cases...
*** No errors detected
real	1m7.374s
user	0m38.687s
sys	0m41.480s

@laanwj
Copy link
Member

laanwj commented May 31, 2018

utACK 6b8b63a

@laanwj laanwj merged commit 6b8b63a into bitcoin:master May 31, 2018
laanwj added a commit that referenced this pull request May 31, 2018
6b8b63a Generic TransactionSignatureCreator works with both CTransaction and CMutableTransaction (Martin Ankerl)

Pull request description:

  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.

Tree-SHA512: 2cff0e9699f484f26120a40e431a24c8bc8f9e780fd89cb0ecf20c5be3eab6c43f9c359cde244abd9f3620d06c7c354e3b9dd3da41fa2ca1ac1e09386fea25fb
@martinus martinus deleted the SignSignature-with-CMutableTransaction branch June 1, 2018 20:34
UdjinM6 pushed a commit to UdjinM6/dash that referenced this pull request Jun 19, 2021
…nSignature

6b8b63a Generic TransactionSignatureCreator works with both CTransaction and CMutableTransaction (Martin Ankerl)

Pull request description:

  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 bitcoin#13202, and to the slow unit test issue bitcoin#10026.

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

Tree-SHA512: 2cff0e9699f484f26120a40e431a24c8bc8f9e780fd89cb0ecf20c5be3eab6c43f9c359cde244abd9f3620d06c7c354e3b9dd3da41fa2ca1ac1e09386fea25fb
UdjinM6 pushed a commit to UdjinM6/dash that referenced this pull request Jun 24, 2021
…nSignature

6b8b63a Generic TransactionSignatureCreator works with both CTransaction and CMutableTransaction (Martin Ankerl)

Pull request description:

  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 bitcoin#13202, and to the slow unit test issue bitcoin#10026.

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

Tree-SHA512: 2cff0e9699f484f26120a40e431a24c8bc8f9e780fd89cb0ecf20c5be3eab6c43f9c359cde244abd9f3620d06c7c354e3b9dd3da41fa2ca1ac1e09386fea25fb
UdjinM6 pushed a commit to UdjinM6/dash that referenced this pull request Jun 26, 2021
…nSignature

6b8b63a Generic TransactionSignatureCreator works with both CTransaction and CMutableTransaction (Martin Ankerl)

Pull request description:

  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 bitcoin#13202, and to the slow unit test issue bitcoin#10026.

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

Tree-SHA512: 2cff0e9699f484f26120a40e431a24c8bc8f9e780fd89cb0ecf20c5be3eab6c43f9c359cde244abd9f3620d06c7c354e3b9dd3da41fa2ca1ac1e09386fea25fb
UdjinM6 pushed a commit to UdjinM6/dash that referenced this pull request Jun 26, 2021
…nSignature

6b8b63a Generic TransactionSignatureCreator works with both CTransaction and CMutableTransaction (Martin Ankerl)

Pull request description:

  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 bitcoin#13202, and to the slow unit test issue bitcoin#10026.

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

Tree-SHA512: 2cff0e9699f484f26120a40e431a24c8bc8f9e780fd89cb0ecf20c5be3eab6c43f9c359cde244abd9f3620d06c7c354e3b9dd3da41fa2ca1ac1e09386fea25fb
UdjinM6 pushed a commit to UdjinM6/dash that referenced this pull request Jun 28, 2021
…nSignature

6b8b63a Generic TransactionSignatureCreator works with both CTransaction and CMutableTransaction (Martin Ankerl)

Pull request description:

  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 bitcoin#13202, and to the slow unit test issue bitcoin#10026.

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

Tree-SHA512: 2cff0e9699f484f26120a40e431a24c8bc8f9e780fd89cb0ecf20c5be3eab6c43f9c359cde244abd9f3620d06c7c354e3b9dd3da41fa2ca1ac1e09386fea25fb
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Dec 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants