Skip to content

Conversation

Empact
Copy link
Contributor

@Empact Empact commented Dec 14, 2018

Previously the argument would be untouched if the first block scan failed. This
makes the behavior predictable, and consistent with the documentation.

@Empact Empact changed the title wallet: Initialize stop_block to nullptr in CWallet::ScanForWalletTransactions wallet: Initialize stop_block in CWallet::ScanForWalletTransactions Dec 14, 2018
@maflcko
Copy link
Member

maflcko commented Dec 14, 2018

Bug fixes should come with test coverage, so that they wouldn't break again in the future.

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

utACK b5c20992a201c1711924cf09ab21c0a3ce6cbb93, thanks for addressing this so quickly. I agree a test would be nice, though looking more closely, maybe the bug doesn't really result in any consequences. For example, without file corruption I don't see a way to call rescanblockchain that would make the stopBlock->nHeight line segfault:

response.pushKV("stop_height", stopBlock->nHeight);

@maflcko
Copy link
Member

maflcko commented Dec 14, 2018

utACK b5c2099. I assumed it would segfault when there is a reorg during rescan, not sure how easy it is to write a test for that.

@maflcko maflcko added this to the 0.18.0 milestone Dec 14, 2018
@ryanofsky
Copy link
Contributor

I don't think even a reorg would be enough to cause a segfault with rescanblockchain unless the reorg happened in a racy way before even a single block could be read.

But alternately, it would be simple to write a c++ unit test that directly called ScanForWalletTransactions with an empty range and checked the value of stop_block afterwards. It would just be kind of a boring test.

@maflcko
Copy link
Member

maflcko commented Dec 14, 2018

Isn't the start block inclusive in the range? In that case an empty range couldn't be passed.

@ryanofsky
Copy link
Contributor

Passing null pindexStart might work, or using PruneOneBlockFile like the existing rescan tests:

PruneOneBlockFile(oldTip->GetBlockPos().nFile);

@Empact
Copy link
Contributor Author

Empact commented Dec 14, 2018

Thanks @ryanofsky, added the two cases you mention, both fail without the initialization. Looking into the importmulti test that follows immediately after...

@Empact
Copy link
Contributor Author

Empact commented Dec 14, 2018

Split the importmulti test into its own case for independence.

Copy link
Contributor

@promag promag left a comment

Choose a reason for hiding this comment

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

Needs rebase to account for #14979.

ACK 1c19a0b, just a comment in the tests.

BOOST_CHECK_EQUAL(wallet.ScanForWalletTransactions(nullptr, nullptr, reserver, failed_block, stop_block), CWallet::ScanResult::SUCCESS);
BOOST_CHECK_EQUAL(failed_block, null_block);
BOOST_CHECK_EQUAL(stop_block, null_block);
BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 0);
Copy link
Contributor

Choose a reason for hiding this comment

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

Irrelevant for this test case?

Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't hurt either

BOOST_CHECK_EQUAL(wallet.ScanForWalletTransactions(oldTip, nullptr, reserver, failed_block, stop_block), CWallet::ScanResult::FAILURE);
BOOST_CHECK_EQUAL(failed_block, newTip);
BOOST_CHECK_EQUAL(stop_block, null_block);
BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 0);
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above.

@maflcko
Copy link
Member

maflcko commented Dec 17, 2018

utACK 1c19a0b4812ba3b9e0a21985d8064801ca25e334

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

utACK 1c19a0b4812ba3b9e0a21985d8064801ca25e334, but one of the test comments appears to be wrong, so it would be good to fix that before merging.

…nsactions

Previously the argument would be untouched if the first block scan failed. This
makes the behavior predictable, and consistent with the documentation.
@Empact
Copy link
Contributor Author

Empact commented Dec 17, 2018

Thanks, fixed the nits - many of these had been fixed in b5de045 but I accidentally overwrote it on a second machine rebasing yesterday.

Here's the diff -w with 1c19a0b4812ba3b9e0a21985d8064801ca25e334:

diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index 28200123f..1ed1926af 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -53,7 +53,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
         AddKey(wallet, coinbaseKey);
         WalletRescanReserver reserver(&wallet);
         reserver.reserve();
-        const CBlockIndex *stop_block, *failed_block;
+        const CBlockIndex *stop_block = null_block + 1, *failed_block = null_block + 1;
         BOOST_CHECK_EQUAL(wallet.ScanForWalletTransactions(nullptr, nullptr, reserver, failed_block, stop_block), CWallet::ScanResult::SUCCESS);
         BOOST_CHECK_EQUAL(failed_block, null_block);
         BOOST_CHECK_EQUAL(stop_block, null_block);
@@ -67,7 +67,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
         AddKey(wallet, coinbaseKey);
         WalletRescanReserver reserver(&wallet);
         reserver.reserve();
-        const CBlockIndex *stop_block, *failed_block;
+        const CBlockIndex *stop_block = null_block + 1, *failed_block = null_block + 1;
         BOOST_CHECK_EQUAL(wallet.ScanForWalletTransactions(oldTip, nullptr, reserver, failed_block, stop_block), CWallet::ScanResult::SUCCESS);
         BOOST_CHECK_EQUAL(failed_block, null_block);
         BOOST_CHECK_EQUAL(stop_block, newTip);
@@ -85,7 +85,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
         AddKey(wallet, coinbaseKey);
         WalletRescanReserver reserver(&wallet);
         reserver.reserve();
-        const CBlockIndex *stop_block, *failed_block;
+        const CBlockIndex *stop_block = null_block + 1, *failed_block = null_block + 1;
         BOOST_CHECK_EQUAL(wallet.ScanForWalletTransactions(oldTip, nullptr, reserver, failed_block, stop_block), CWallet::ScanResult::FAILURE);
         BOOST_CHECK_EQUAL(failed_block, oldTip);
         BOOST_CHECK_EQUAL(stop_block, newTip);
@@ -96,14 +96,13 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
     PruneOneBlockFile(newTip->GetBlockPos().nFile);
     UnlinkPrunedFiles({newTip->GetBlockPos().nFile});
 
-    // Verify ScanForWalletTransactions only picks transactions in the new block
-    // file.
+    // Verify ScanForWalletTransactions scans no blocks.
     {
         CWallet wallet(*chain, WalletLocation(), WalletDatabase::CreateDummy());
         AddKey(wallet, coinbaseKey);
         WalletRescanReserver reserver(&wallet);
         reserver.reserve();
-        const CBlockIndex *stop_block, *failed_block;
+        const CBlockIndex *stop_block = null_block + 1, *failed_block = null_block + 1;
         BOOST_CHECK_EQUAL(wallet.ScanForWalletTransactions(oldTip, nullptr, reserver, failed_block, stop_block), CWallet::ScanResult::FAILURE);
         BOOST_CHECK_EQUAL(failed_block, newTip);
         BOOST_CHECK_EQUAL(stop_block, null_block);
@@ -130,6 +129,7 @@ BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup)
     // Verify importmulti RPC returns failure for a key whose creation time is
     // before the missing block, and success for a key whose creation time is
     // after.
+    {
         std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(*chain, WalletLocation(), WalletDatabase::CreateDummy());
         AddWallet(wallet);
         UniValue keys;
@@ -164,6 +164,7 @@ BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup)
                               0, oldTip->GetBlockTimeMax(), TIMESTAMP_WINDOW));
         RemoveWallet(wallet);
     }
+}
 
 // Verify importwallet RPC starts rescan at earliest block with timestamp
 // greater or equal than key birthday. Previously there was a bug where
@@ -340,7 +341,7 @@ public:
         WalletRescanReserver reserver(wallet.get());
         reserver.reserve();
         const CBlockIndex* const null_block = nullptr;
-        const CBlockIndex *stop_block, *failed_block;
+        const CBlockIndex *stop_block = null_block + 1, *failed_block = null_block + 1;
         BOOST_CHECK_EQUAL(wallet->ScanForWalletTransactions(chainActive.Genesis(), nullptr, reserver, failed_block, stop_block), CWallet::ScanResult::SUCCESS);
         BOOST_CHECK_EQUAL(stop_block, chainActive.Tip());
         BOOST_CHECK_EQUAL(failed_block, null_block);

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

utACK 8b9171c. Only suggested changes since last review (Thanks!)

@maflcko
Copy link
Member

maflcko commented Dec 17, 2018

re-utACK 8b9171c

@meshcollider
Copy link
Contributor

meshcollider commented Dec 18, 2018

@ryanofsky is null_block + 1 defined behavior? null_block is a nullptr, doesn't feel like arithmetic on a nullptr should be defined. @practicalswift might know

@DrahtBot
Copy link
Contributor

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

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #14711 (Remove uses of chainActive and mapBlockIndex in wallet code by ryanofsky)
  • #10973 (Refactor: separate wallet from node by ryanofsky)

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.

@Empact
Copy link
Contributor Author

Empact commented Dec 18, 2018

"There exist implicit conversions from nullptr to null pointer value of any pointer type and any pointer to member type." so the arithmetic is on a 0-initialized const CBlockIndex*, so it's regular pointer math.
https://en.cppreference.com/w/cpp/language/nullptr
https://github.com/llvm-mirror/libcxx/blob/master/include/__nullptr

That said, I don't know how much less likely the value 1 is to be found in uninitialized memory, over the value 0.

@meshcollider
Copy link
Contributor

Ok, utACK 8b9171c

@meshcollider meshcollider merged commit 8b9171c into bitcoin:master Dec 18, 2018
meshcollider added a commit that referenced this pull request Dec 18, 2018
…Transactions

8b9171c wallet: Initialize stop_block to nullptr in CWallet::ScanForWalletTransactions (Ben Woosley)

Pull request description:

  Previously the argument would be untouched if the first block scan failed. This
  makes the behavior predictable, and consistent with the documentation.

Tree-SHA512: 3efadf9fd5e25ecd9450f32545f58e61a123ad883e921ef427b13e4782ffdd8ffe905c9ad3edc7e8f9e4953342cd72247bb4cc9eeaf9e5fd04291ac5c1bb5eec
@Empact Empact deleted the stop-block-null branch December 18, 2018 03:15
@@ -47,14 +47,27 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup)

auto locked_chain = chain->lock();

// Verify ScanForWalletTransactions accomodates a null start block.
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems to trigger a lint warning from test/lint/lint-all.sh on master:

src/wallet/test/wallet_tests.cpp:50: accomodates  ==> accommodates
^ Warning: codespell identified likely spelling errors. Any false positives? Add them to the list of ignored words in test/lint/lint-spelling.ignore-words.txt

Copy link
Member

Choose a reason for hiding this comment

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

Should be fixed in #15102.

deadalnix pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Mar 26, 2020
Summary:
```
Previously the argument would be untouched if the first block scan
failed. This makes the behavior predictable, and consistent with the
documentation.
```

Backport of core [[bitcoin/bitcoin#14957 | PR14957]] and the remaining of [[bitcoin/bitcoin#15321 | PR15321]] (see D5238).

Depends on D5563.

Test Plan:
With Clang:
  cmake -GNinja .. -DCMAKE_BUILD_TYPE=Debug -DENABLE_WERROR=ON
  ninja all check check-functional

Reviewers: #bitcoin_abc, deadalnix

Reviewed By: #bitcoin_abc, deadalnix

Differential Revision: https://reviews.bitcoinabc.org/D5564
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Oct 23, 2021
…rWalletTransactions

8b9171c wallet: Initialize stop_block to nullptr in CWallet::ScanForWalletTransactions (Ben Woosley)

Pull request description:

  Previously the argument would be untouched if the first block scan failed. This
  makes the behavior predictable, and consistent with the documentation.

Tree-SHA512: 3efadf9fd5e25ecd9450f32545f58e61a123ad883e921ef427b13e4782ffdd8ffe905c9ad3edc7e8f9e4953342cd72247bb4cc9eeaf9e5fd04291ac5c1bb5eec

# Conflicts:
#	src/wallet/test/wallet_tests.cpp
#	src/wallet/wallet.cpp
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Oct 23, 2021
…rWalletTransactions

8b9171c wallet: Initialize stop_block to nullptr in CWallet::ScanForWalletTransactions (Ben Woosley)

Pull request description:

  Previously the argument would be untouched if the first block scan failed. This
  makes the behavior predictable, and consistent with the documentation.

Tree-SHA512: 3efadf9fd5e25ecd9450f32545f58e61a123ad883e921ef427b13e4782ffdd8ffe905c9ad3edc7e8f9e4953342cd72247bb4cc9eeaf9e5fd04291ac5c1bb5eec

# Conflicts:
#	src/wallet/test/wallet_tests.cpp
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Oct 24, 2021
…rWalletTransactions

8b9171c wallet: Initialize stop_block to nullptr in CWallet::ScanForWalletTransactions (Ben Woosley)

Pull request description:

  Previously the argument would be untouched if the first block scan failed. This
  makes the behavior predictable, and consistent with the documentation.

Tree-SHA512: 3efadf9fd5e25ecd9450f32545f58e61a123ad883e921ef427b13e4782ffdd8ffe905c9ad3edc7e8f9e4953342cd72247bb4cc9eeaf9e5fd04291ac5c1bb5eec

# Conflicts:
#	src/wallet/test/wallet_tests.cpp
#	src/wallet/wallet.cpp
UdjinM6 pushed a commit to dashpay/dash that referenced this pull request Oct 25, 2021
…rWalletTransactions (#4538)

* Merge bitcoin#14957: wallet: Initialize stop_block in CWallet::ScanForWalletTransactions

8b9171c wallet: Initialize stop_block to nullptr in CWallet::ScanForWalletTransactions (Ben Woosley)

Pull request description:

  Previously the argument would be untouched if the first block scan failed. This
  makes the behavior predictable, and consistent with the documentation.

Tree-SHA512: 3efadf9fd5e25ecd9450f32545f58e61a123ad883e921ef427b13e4782ffdd8ffe905c9ad3edc7e8f9e4953342cd72247bb4cc9eeaf9e5fd04291ac5c1bb5eec

# Conflicts:
#	src/wallet/test/wallet_tests.cpp

* Add lock annotation

* fix

Co-authored-by: MeshCollider <dobsonsa68@gmail.com>
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Oct 25, 2021
…rWalletTransactions

8b9171c wallet: Initialize stop_block to nullptr in CWallet::ScanForWalletTransactions (Ben Woosley)

Pull request description:

  Previously the argument would be untouched if the first block scan failed. This
  makes the behavior predictable, and consistent with the documentation.

Tree-SHA512: 3efadf9fd5e25ecd9450f32545f58e61a123ad883e921ef427b13e4782ffdd8ffe905c9ad3edc7e8f9e4953342cd72247bb4cc9eeaf9e5fd04291ac5c1bb5eec

# Conflicts:
#	src/wallet/test/wallet_tests.cpp
#	src/wallet/wallet.cpp
PastaPastaPasta added a commit to PastaPastaPasta/dash that referenced this pull request Nov 1, 2021
…rWalletTransactions (dashpay#4538)

* Merge bitcoin#14957: wallet: Initialize stop_block in CWallet::ScanForWalletTransactions

8b9171c wallet: Initialize stop_block to nullptr in CWallet::ScanForWalletTransactions (Ben Woosley)

Pull request description:

  Previously the argument would be untouched if the first block scan failed. This
  makes the behavior predictable, and consistent with the documentation.

Tree-SHA512: 3efadf9fd5e25ecd9450f32545f58e61a123ad883e921ef427b13e4782ffdd8ffe905c9ad3edc7e8f9e4953342cd72247bb4cc9eeaf9e5fd04291ac5c1bb5eec

# Conflicts:
#	src/wallet/test/wallet_tests.cpp

* Add lock annotation

* fix

Co-authored-by: MeshCollider <dobsonsa68@gmail.com>
pravblockc pushed a commit to pravblockc/dash that referenced this pull request Nov 18, 2021
…rWalletTransactions (dashpay#4538)

* Merge bitcoin#14957: wallet: Initialize stop_block in CWallet::ScanForWalletTransactions

8b9171c wallet: Initialize stop_block to nullptr in CWallet::ScanForWalletTransactions (Ben Woosley)

Pull request description:

  Previously the argument would be untouched if the first block scan failed. This
  makes the behavior predictable, and consistent with the documentation.

Tree-SHA512: 3efadf9fd5e25ecd9450f32545f58e61a123ad883e921ef427b13e4782ffdd8ffe905c9ad3edc7e8f9e4953342cd72247bb4cc9eeaf9e5fd04291ac5c1bb5eec

# Conflicts:
#	src/wallet/test/wallet_tests.cpp

* Add lock annotation

* fix

Co-authored-by: MeshCollider <dobsonsa68@gmail.com>
@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.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants