Make CCryptoKeyStore::Unlock check all keys. #4011

pull gmaxwell wants to merge 1 commits into bitcoin:master from gmaxwell:keystore_loop changing 1 files +22 −4
  1. gmaxwell commented at 7:28 AM on April 6, 2014: contributor

    CCryptoKeyStore::Unlock has a loop to attempt decrypting each key which only executes once, likely due to a simple mistake when the code was originally written.

    This patch fixes the behavior by making it check all keys. It also adds a fatal assertion in the case some decrypt but some do not, since that indicates that the wallet is in some kind of really bad state.

    This may make unlocking noticeably slower on wallets with many keys.

  2. Make CCryptoKeyStore::Unlock check all keys.
    CCryptoKeyStore::Unlock has a loop to attempt decrypting each key which
     only executes once, likely due to a simple mistake when the code was
     originally written.
    
    This patch fixes the behavior by making it check all keys. It also adds
     a fatal assertion in the case some decrypt but some do not, since that
     indicates that the wallet is in some kind of really bad state.
    
    This may make unlocking noticeably slower on wallets with many keys.
    f36754839b
  3. gmaxwell commented at 7:29 AM on April 6, 2014: contributor

    If people don't think that checking all keys and handling the error in this way is stupid, I'll go ahead and check with a huge wallet to verify that the slowdown isn't excessive. At least with a 100 key keypool it's not noticeable.

  4. Telepatheic commented at 10:39 AM on April 6, 2014: contributor

    This seems very sensible to me. What is the biggest size of wallet that is known to have been used?

  5. sipa commented at 2:07 PM on April 6, 2014: member

    Checking just one key was always the original intention, as far as I remember.

    This will require an EC multiplication per key (and GetPubKey may be doing more than one...).

  6. laanwj commented at 6:53 AM on April 7, 2014: member

    Sorry for the dumb question, but what does checking all the keys in this case get us? If it makes wallets with lots of keys even slower, we'd need to have a good reason to do this.

  7. gmaxwell commented at 7:11 AM on April 7, 2014: contributor

    @sipa Bluematt seemed to think otherwise wrt intention. :) @laanwj it would catch any case where the public keys and the secret keys in the wallet didn't agree with each other, either due to corruption or due to malicious modification (e.g. so that newly issued keys were really someone elses private keys). How much thats worth I dunno. I don't have that much of an opinion: The existing code is brain damanged, either it should check more than one or the loop should be removed. I don't have that much of an opinion which we do, which is why I was asking what people thought before I went into benchmarking it on wallets with lots of keys.

  8. laanwj commented at 7:15 AM on April 16, 2014: member

    Right. Checking all the keys is a good wallet integrity check. But it doesn't seem necessary to me to check all the keys every time that the wallet is unlocked. One idea would be to do it the first time, or to even add an argument to walletpassphrase for a 'deep' validation.

  9. gmaxwell commented at 7:23 AM on April 16, 2014: contributor

    First time makes sense, I don't like adding more api surface. I'll go and check it on a huge wallet and verify that it's not too disruptive and if not I'll make it check all just once.

  10. TheBlueMatt commented at 12:13 AM on April 27, 2014: member

    @sipa I dont remember the intention, but the code appears to intend to check it all and just not bother doing it (I mean why is there even a loop?)... In any case, I agree with @gmaxwell, if its not too disruptive, I'd prefer checking it all.

  11. BitcoinPullTester commented at 11:42 AM on June 23, 2014: none

    Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/p4011_f36754839b5462b330b92fa488c467cc4b38a028/ for binaries and test log. This test script verifies pulls every time they are updated. It, however, dies sometimes and fails to test properly. If you are waiting on a test, please check timestamps to verify that the test.log is moving at http://jenkins.bluematt.me/pull-tester/current/ Contact BlueMatt on freenode if something looks broken.

  12. laanwj commented at 3:55 PM on June 24, 2014: member

    @gmaxwell Did you ever get around to testing this with a large encrypted wallet?

  13. laanwj added the label Wallet on Jul 31, 2014
  14. Diapolo commented at 9:34 AM on August 6, 2014: none

    @gmaxwell Any news/benchmarks for this? I remember it was also caught as a problem in a recent audit via a static analyzer tool.

  15. laanwj commented at 9:27 AM on August 8, 2014: member

    I'm still of the opinion that it is not acceptable to do the decoding and checking all keys in the wallet every time that walletpassphrase is called, which would be the effect of this. This command is very frequently used, sometimes for every transaction.

    So let's just go with doing this only the first time.

  16. Diapolo commented at 9:31 AM on August 8, 2014: none

    Is there an easy way to make PVS-Studio happy without the burden of checking every time? Or make this a santiy check on startup?

  17. laanwj commented at 9:36 AM on August 8, 2014: member

    Sure, add a boolean flag to CCryptoKeyStore::Unlock whether to do a full check. Do the early return only if that is not set.

  18. Diapolo commented at 9:37 AM on August 8, 2014: none

    @gmaxwell If you agree, can you update this?

  19. TheBlueMatt commented at 9:03 AM on August 9, 2014: member

    Meh, just static boolean fAlreadyChecked = false; set to true after the first run. Early return if its true.

  20. gmaxwell commented at 9:07 AM on August 9, 2014: contributor

    That might be a good compromise. The tension I see is that the performance is important, but if you can't actually spend what you think you can thats very bad and ought to be detected (e.g. as a result of corruption). If the once-per-run test matt proposes is too slow, A compromise would be checking the keypool (or at least the near term keypool) only might also be reasonable.

  21. laanwj commented at 9:09 AM on August 9, 2014: member

    A once-per-run check is fine.

  22. gmaxwell commented at 12:52 PM on August 14, 2014: contributor

    Subsumed by Bluematt's

  23. gmaxwell closed this on Aug 14, 2014

  24. DrahtBot locked this on Sep 8, 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: 2026-04-18 21:15 UTC

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