Skip to content

Conversation

ryanofsky
Copy link
Contributor

@ryanofsky ryanofsky commented Feb 15, 2017

This is supposed to address the concern from @gmaxwell in #9761 that importmulti rescans on pruned nodes could unsuccessfully scan pruned blocks and fail to inform the user.

An alternative approach of just simply disabling importmulti rescans on pruned nodes was initially discussed in https://botbot.me/freenode/bitcoin-core-dev/msg/81023921/, but running being able to import keys and do partial rescans on pruned nodes was determined to be an important use-case.

@morcos
Copy link
Contributor

morcos commented Feb 15, 2017

Concept ACK
This looks like a reasonable approach to me.

Don't forget that you may want to include the grace period in detecting whether it scanned enough.
Also you might want to skip the rest of the loop if ReadBlockFromDisk is false.

@laanwj laanwj added this to the 0.14.0 milestone Feb 16, 2017
@laanwj
Copy link
Member

laanwj commented Feb 16, 2017

Concept ACK.

The code has not been tested at all, and I'm actually not sure how I'm going to go about writing a unit test because there doesn't seem to be an easy way to target individual blocks for pruning inside RPC tests.

There's pruneblockchain but yes pruning works on a per-file, not a per-block basis, so it would need some extra effort on regtest to generate full blocks instead of empty ones otherwise at block 30000 you're still in the first file, and that RPC will do nothing.

@gmaxwell
Copy link
Contributor

Concept ACK. Will test/review further.

@morcos
Copy link
Contributor

morcos commented Feb 16, 2017

Please rebase on #9761 so we can verify the grace period works properly

@ryanofsky
Copy link
Contributor Author

Rebased

@ryanofsky ryanofsky changed the title WIP: Return errors from importmulti if complete rescans are not successful WIP: Return errors from importmulti if complete rescans are not successful (on top of #9761) Feb 16, 2017
int posInBlock;
for (posInBlock = 0; posInBlock < (int)block.vtx.size(); posInBlock++)
{
if (AddToWalletIfInvolvingMe(*block.vtx[posInBlock], pindex, posInBlock, fUpdate))
ret++;
AddToWalletIfInvolvingMe(*block.vtx[posInBlock], pindex, posInBlock, fUpdate);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this loop should also be skipped if ReadBlockFromDisk fails

Copy link
Contributor Author

@ryanofsky ryanofsky Feb 16, 2017

Choose a reason for hiding this comment

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

Skipped in d6f6a23

ryanofsky added a commit to ryanofsky/bitcoin that referenced this pull request Feb 16, 2017
…cessful

Skip empty loop if ReadBlockFromDisk fails as suggested
bitcoin#9773 (comment)
Copy link
Contributor Author

@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.

Add test for CWallet::ScanForWalletTransactions in e3d4f25

int posInBlock;
for (posInBlock = 0; posInBlock < (int)block.vtx.size(); posInBlock++)
{
if (AddToWalletIfInvolvingMe(*block.vtx[posInBlock], pindex, posInBlock, fUpdate))
ret++;
AddToWalletIfInvolvingMe(*block.vtx[posInBlock], pindex, posInBlock, fUpdate);
Copy link
Contributor Author

@ryanofsky ryanofsky Feb 16, 2017

Choose a reason for hiding this comment

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

Skipped in d6f6a23

@ryanofsky ryanofsky changed the title WIP: Return errors from importmulti if complete rescans are not successful (on top of #9761) Return errors from importmulti if complete rescans are not successful (on top of #9761) Feb 16, 2017
} else {
UniValue result = UniValue(UniValue::VOBJ);
result.pushKV("success", UniValue(false));
result.pushKV("error", JSONRPCError(RPC_MISC_ERROR, strprintf("Failed to rescan before time %" PRId64 ", transactions may be missing.", (long long)scannedRange->GetBlockTimeMax())));
Copy link
Contributor

@jonasschnelli jonasschnelli Feb 16, 2017

Choose a reason for hiding this comment

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

just curious: Is there an advantage using PRId64 over %ul (rest of the code uses this)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually I need to change this to either remove PRId64 or the (long long) cast.

You're supposed to use PRId64 whenever you pass an int64_t type to printf. %ld or %lld aren't always correct because longs and long longs just have minimum widths in standard c++, not fixed widths that are the same on all systems.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed cast in e49f039.

@ryanofsky
Copy link
Contributor Author

Previously squashed e3d4f25 -> 455b8f7 (multicheck.2 -> multicheck.3)

ryanofsky added a commit to ryanofsky/bitcoin that referenced this pull request Feb 16, 2017
…cessful

Add missing response.setArray call and fix string formatting issue pointed out
bitcoin#9773 (comment)
@ryanofsky
Copy link
Contributor Author

Added C++ test for new importmulti RPC code in e64cdfb

Squashed e64cdfb -> b73252d (multicheck.4 -> multicheck.5)

@sipa
Copy link
Member

sipa commented Feb 16, 2017

Note that our strprintf is a wrapper around tfm::format, and doesn't need type specs at all.

@morcos
Copy link
Contributor

morcos commented Feb 16, 2017

lightly tested ACK b73252d
Only reviewed/tested code, not the tests.

Copy link
Contributor

@jonasschnelli jonasschnelli left a comment

Choose a reason for hiding this comment

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

utACK b73252d

} else {
UniValue result = UniValue(UniValue::VOBJ);
result.pushKV("success", UniValue(false));
result.pushKV("error", JSONRPCError(RPC_MISC_ERROR, strprintf("Failed to rescan before time %" PRId64 ", transactions may be missing.", scannedRange->GetBlockTimeMax())));
Copy link
Member

@laanwj laanwj Feb 17, 2017

Choose a reason for hiding this comment

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

Please remove the PRI64d here. It gives problems with some platforms, and as @sipa says don't need it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok will change, but what are the problems with some platforms?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed in aaaf65a.

Reason I am asking about the problem you're seeing is that not using PRI64d for int64_t would prevent us from using compile time format string checking (as suggested in #9423 (comment)) which would be much better than the runtime checking we currently use.

Copy link
Member

@laanwj laanwj Feb 22, 2017

Choose a reason for hiding this comment

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

Ok will change, but what are the problems with some platforms?

The conceptual problem is that PRI64d can evaluate to anything depending on the platform, e.g. "%ponyfood". tinyformat.h cannot know about all these platform-dependent escape sequences, so might produce garbled output or even raise an exception. We had a lot of problems with this back in the day with windows and mingw. It is wrong to pass platform-specific stuff to a platform-independent library. Also PRI64d is C99, so not all C++ compilers are guaranteed to have it at all.

Offline checking could still work, the script would just need to be smart enough to cope with a) translations b) tinyformat's specifiers and type-safety. (b) is actually a subset, not a superset of what platform printfs support (none of the insecure ones like %n) so if anything that should make it easier.

@ryanofsky
Copy link
Contributor Author

Rebased b73252d -> 90671ee (multicheck.5 -> multicheck.6)

@ryanofsky ryanofsky changed the title Return errors from importmulti if complete rescans are not successful (on top of #9761) Return errors from importmulti if complete rescans are not successful Feb 17, 2017
ryanofsky added a commit to ryanofsky/bitcoin that referenced this pull request Feb 17, 2017
@ryanofsky
Copy link
Contributor Author

Squashed aaaf65a -> 1425c72 (multicheck.7 -> multicheck.8)

@maflcko
Copy link
Member

maflcko commented Feb 17, 2017 via email

@ryanofsky
Copy link
Contributor Author

Somehow travis didn't like your commit.

Appears to be a spurious error. The travis run for b72521dd7f570b0c557439d534f7523a5be52999 which is aaaf65a merged into 9828f9a succeeded: https://travis-ci.org/bitcoin/bitcoin/builds/202600321

Only the travis run for 64072b74ebbf7b5585b39f6c117c6ffa9dc820f0 which is 1425c72 merged into 9828f9a failed: https://travis-ci.org/bitcoin/bitcoin/builds/202600549

There are no differences between the two commits:

$ git rev-parse aaaf65a90b87c18889d177ff3f0ab8a868f849f3^{tree} 1425c727863b335bf98bb4b17b575e59552d38e9^{tree}
9e695fd32f65b1596f3ff613b96ec756bb2f1d2b
9e695fd32f65b1596f3ff613b96ec756bb2f1d2b

@ryanofsky ryanofsky force-pushed the pr/multicheck branch 2 times, most recently from 1425c72 to 68da3ee Compare February 17, 2017 15:45
@ryanofsky
Copy link
Contributor Author

ryanofsky commented Feb 17, 2017

Touched CommitDate to rerun travis 1425c72 -> e2e2f4c (multicheck.8 -> multicheck.12)

@jtimon
Copy link
Contributor

jtimon commented Feb 18, 2017

Concept ACK

@laanwj laanwj merged commit e2e2f4c into bitcoin:master Feb 22, 2017
laanwj added a commit that referenced this pull request Feb 22, 2017
…ot successful

e2e2f4c Return errors from importmulti if complete rescans are not successful (Russell Yanofsky)
laanwj pushed a commit that referenced this pull request Feb 22, 2017
// Verify ScanForWalletTransactions picks up transactions in both the old
// and new block files.
{
CWallet wallet;
Copy link
Contributor

@paveljanik paveljanik Feb 22, 2017

Choose a reason for hiding this comment

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

This brings a few Wshadow warnings:

Wshadow statistics: 
   1 wallet/test/wallet_tests.cpp:377:17: warning: declaration shadows a variable in namespace 'wallet_tests' [-Wshadow]
   1 wallet/test/wallet_tests.cpp:391:17: warning: declaration shadows a variable in namespace 'wallet_tests' [-Wshadow]
   1 wallet/test/wallet_tests.cpp:399:17: warning: declaration shadows a variable in namespace 'wallet_tests' [-Wshadow]

ryanofsky added a commit to ryanofsky/bitcoin that referenced this pull request Feb 22, 2017
Warnings introduced by commit e2e2f4c "Return errors from importmulti if
complete rescans are not successful" and reported by Pavel Janík
<Pavel@Janik.cz> in bitcoin#9773 and
bitcoin#9827

wallet/test/wallet_tests.cpp: In member function ‘void wallet_tests::rescan::test_method()’:
wallet/test/wallet_tests.cpp:377:17: warning: declaration of ‘wallet’ shadows a global declaration [-Wshadow]
         CWallet wallet;
codablock pushed a commit to codablock/dash that referenced this pull request Jan 26, 2018
…s are not successful

e2e2f4c Return errors from importmulti if complete rescans are not successful (Russell Yanofsky)
andvgal pushed a commit to energicryptocurrency/gen2-energi that referenced this pull request Jan 6, 2019
…s are not successful

e2e2f4c Return errors from importmulti if complete rescans are not successful (Russell Yanofsky)
CryptoCentric pushed a commit to absolute-community/absolute that referenced this pull request Feb 27, 2019
…s are not successful

e2e2f4c Return errors from importmulti if complete rescans are not successful (Russell Yanofsky)
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 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.

10 participants