rpc: Require solvability in importmulti if importing more than the scriptPubKey #14558

pull achow101 wants to merge 14 commits into bitcoin:master from achow101:importmulti-solvability changing 8 files +506 −177
  1. achow101 commented at 4:45 am on October 24, 2018: member

    Currently, in importmulti, it is possible to import not enough information to make a scriptPubKey solvable. It is also possible to import more information than necessary to make a scriptPubKey solvable. This PR changes this to require that an import must be either just the scriptPubKey or include everything necessary to make it solvable without any extra data.

    This is built on top of #14454.

  2. Add SegWit support to importmulti with some ProcessImport cleanup 226671adfd
  3. Add segwit address tests for importmulti 36719c309e
  4. Fix typo in test_framework/blocktools f2b101a5c8
  5. Add release notes for importmulti segwit change d73f658aa2
  6. Refactor ProcessImport to allow P2SH-P2WPKH again cebab44dc0
  7. Make getaddressinfo return solvability f2a4e1e2a9
  8. Improve segwit importmulti tests 31d8b4b24a
  9. fixups for importmulti segwit support PR 417a64ea15
  10. Rename issolvable to solvable 7c0268acb5
  11. Do not add inner witness script as watch only e4a66bb791
  12. refactor: introduce script importing helper functions in ProcessImport
    Introduce two functions, ImportScriptsToKeystore and AddScriptsToWatchOnly.
    These functions move the actual script and public key importing to the
    end of ProcessImport.
    6e71d4f1bd
  13. Introduce AllUsedKeyStore
    AllUsedKeyStore is used to track whether all of the scripts and
    public keys in the keystore have been used in signing.
    
    To avoid issues with const-ness, the usage maps are in a separate
    struct which is pointed to by a pointer in AllUsedKeyStore. This
    allows GetPubKey and GetCScript to properly override the CBasicKeyStore
    functions.
    45a5d3d989
  14. rpc: importmulti: Check for solvability and minimal import
    Check that if more than just a scriptPubKey was imported, that there
    was enough data to be solvable.
    
    Check that if more than just a scriptPubKey was imported, that the
    minimal data needed for solvability was imported.
    9879272cf9
  15. Test solvability requirement 7b93302c48
  16. fanquake added the label RPC/REST/ZMQ on Oct 24, 2018
  17. sipa commented at 7:11 am on October 24, 2018: member
    Concept ACK
  18. in src/wallet/rpcdump.cpp:808 in 45a5d3d989 outdated
    804@@ -805,6 +805,111 @@ UniValue dumpwallet(const JSONRPCRequest& request)
    805     return reply;
    806 }
    807 
    808+struct UsageMaps {
    


    promag commented at 9:22 am on October 24, 2018:
    Any reason to not move these to AllUsedKeyStore?

    achow101 commented at 1:25 pm on October 24, 2018:
    Yes. The functions GetKey, GetPubKey, and GetCScript are all const functions and need to be in order to override the CBasicKeyStore versions of them. However, those functions need to modify the usage maps. If they were in AllUsedKeyStore, those functions would not be const. By having them in a separate struct that has a pointer in AllUsedKeyStore, the functions can remain const but still allow us to update the usage info.

    promag commented at 1:33 pm on October 24, 2018:
    Got it, thanks.
  19. in src/wallet/rpcdump.cpp:822 in 7b93302c48
    817+
    818+// Class which remembers whether every script and public key was used
    819+class AllUsedKeyStore : public CBasicKeyStore
    820+{
    821+private:
    822+    struct UsageMaps* usage = new UsageMaps();
    


    promag commented at 1:33 pm on October 24, 2018:
    This is leaking.

    promag commented at 1:34 pm on October 24, 2018:
    Nit, could remove struct?
  20. in src/wallet/rpcdump.cpp:1027 in 7b93302c48
    1034-            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid redeem script");
    1035-        }
    1036-
    1037-        // Process. //
    1038+        CScript scriptpubkey_script = script;
    1039+        CTxDestination scriptpubkey_dest = dest;
    


    practicalswift commented at 2:54 pm on October 24, 2018:
    scriptpubkey_dest is unused?
  21. in src/wallet/rpcdump.cpp:825 in 7b93302c48
    820+{
    821+private:
    822+    struct UsageMaps* usage = new UsageMaps();
    823+public:
    824+    bool AllUsed() const;
    825+    bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const override;
    


    practicalswift commented at 2:58 pm on October 24, 2018:
    Make the parameters names match between declaration and definition (CPubKey& vchPubKeyOut vs CPubKey &pubkey_out) :-)
  22. in src/wallet/rpcdump.cpp:827 in 7b93302c48
    822+    struct UsageMaps* usage = new UsageMaps();
    823+public:
    824+    bool AllUsed() const;
    825+    bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const override;
    826+    bool AddCScript(const CScript& redeemScript) override;
    827+    bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const override;
    


    practicalswift commented at 3:00 pm on October 24, 2018:
    Same here: CScript& redeemScriptOut vs CScript& script_out :-)
  23. DrahtBot commented at 4:54 pm on October 24, 2018: member
    • #14565 (Overhaul importmulti logic by sipa)
    • #14454 (Add SegWit support to importmulti by MeshCollider)
    • #14303 (rpc: Early call once CWallet::MarkDirty in import calls by promag)
    • #14075 (Import watch only pubkeys to the keypool if private keys are disabled by achow101)
    • #14021 (Import key origin data through importmulti by achow101)

    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.

  24. in src/wallet/rpcdump.cpp:837 in 7b93302c48
    832+
    833+bool AllUsedKeyStore::GetPubKey(const CKeyID &address, CPubKey &pubkey_out) const
    834+{
    835+    LOCK(cs_KeyStore);
    836+    if (CBasicKeyStore::GetPubKey(address, pubkey_out)) {
    837+        usage->map_watch_key_use[address] = true;
    


    promag commented at 9:57 pm on October 24, 2018:

    You could invert the logic and keep track of the unused

    • when adding a key, add to the unused set
    • when reading a key, remove from the unused set

    Then AllUsed could look like (s/usage/unused):

    0    return 
    1        unused->watch_keys.empty() &&
    2        unused->scripts.empty() &&
    3        unused->keys.empty();
    

    I could be missing some detail.

  25. achow101 commented at 4:24 am on October 30, 2018: member
    Closing in favor of #14565
  26. achow101 closed this on Oct 30, 2018

  27. meshcollider referenced this in commit f8a3ab3b29 on Dec 24, 2018
  28. 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: 2024-07-08 19:13 UTC

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