Add support for watch-only addresses (rebased) #3383

pull laanwj wants to merge 2 commits into bitcoin:master from laanwj:2013_12_importaddress_rebase changing 16 files +237 −69
  1. laanwj commented at 2:11 pm on December 10, 2013: member

    Rebased version of #2861

    This is not mergeable in the current state, but people seem to be using this.

    Based on a patch by Eric Lombrozo, further work by Pieter Wuille.

    Some compatibility work for interaction with coin control was added by me. This needs to be tested carefully.

  2. gastonmorixe commented at 2:15 pm on December 10, 2013: none
    :+1:
  3. jgarzik commented at 11:50 pm on December 12, 2013: contributor

    re-ACK

    The previous pull request went around and around in an ultimately circular discussion. I disagree that the multi-balance situation is a blocker for this PR. Multi-balance has existed since the beginning of bitcoin, in the form of confirmed/unconfirmed balance. Add on top of that multi-sig. On top of that, locked outputs. Adding public-key-only to the wallet is elegant and does not overly complicate the existing multi-balance situation.

    The alternatives only truly make sense if multi-wallet support is deployed and fleshed out, making it trivial to divide up your coins across wallets without restarts etc. Otherwise, your choice is either running N copies of bitcoind – in parallel if real-time wallet access is required, or this pull req.

    That is the fundamental design choice. We are not close to multi-wallet, and this PR has people actively using it. This and coin control are two features that seem to continue to be requested, and IMO, need to be pushed based on user feedback.

  4. gavinandresen commented at 0:01 am on December 13, 2013: contributor
    OK from me, but I don’t have time to test.
  5. laanwj commented at 4:47 am on December 13, 2013: member

    @jgarzik But all the current balances can be seen by the user, it’s easy to see what part of the balance is confirmed, unconfirmed, etc. This patch as it is now provides no way to see what part of the balance is ‘watch-only’.

    This could be dangerous: there is no way to distinguish a wallet that only contains addresses from one that contains actual private keys for the same without trying to spend. Well – apart from getrawtransaction which can see spendable/unspendable status. But there is no way to see this at a glance.

  6. luke-jr commented at 1:43 pm on December 13, 2013: member
    I think we are pretty close to multi-wallet actually… just some relatively small glue needed to expose it to the GUI or daemon, right?
  7. sipa commented at 2:19 pm on December 13, 2013: member

    I think having non-spendable balances visible is a good thing. Adding a boolean for that to getbalance/getunconfirmedbalance sounds fine to me (it should also deal with locked outputs).

    For the GUI, something like:

    • Balance: X (+ Y unspendable)
    • Unconfirmed balance: Z (+ W unspendable) (where the bracketed part is only shown when Y/W are nonzero) would be fine to me.
  8. jgarzik commented at 3:33 pm on December 13, 2013: contributor

    @sipa agree @laanwj agree – and this is easy to fix, by simply exposing the information.

    For RPC, showing multiple balances and providing information about locked/multisig/readonly should be visible.

  9. kyledrake commented at 5:52 am on January 11, 2014: none

    Hi guys,

    I’m investigating a problem where importaddress fails to find unspents sent to the imported address, even when rescan is set to true. I’m currently using https://github.com/sipa/bitcoin/tree/watchonly, so I haven’t tested with this latest rebase yet, but I wanted to bring this up ASAP incase this is an issue that has not yet been discovered.

    Reproducing is pretty simple with a private testnet-in-a-box:

    Import an address:

    0$ bitcoind -datadir=2 importaddress mhou3jmi6Snxw4Y7nszn7gFTbUzHdiBt9y 'test' false
    

    Send to that address from the mining process:

    0$ bitcoind -datadir=1 sendtoaddress mhou3jmi6Snxw4Y7nszn7gFTbUzHdiBt9y 1
    

    Confirm the unspent has been sent:

     0$ bitcoind -datadir=2 listunspent 0
     1[
     2    {
     3        "txid" : "36016dffdfb5ca0d571f30349fa772123ac92be814c7945d6155869785e1f7d3",
     4        "vout" : 1,
     5        "address" : "mhou3jmi6Snxw4Y7nszn7gFTbUzHdiBt9y",
     6        "account" : "test",
     7        "scriptPubKey" : "76a91419249cd3bf74403fd1e918cc4cc07545b7b8cc2c88ac",
     8        "amount" : 1.00000000,
     9        "confirmations" : 0,
    10        "spendable" : false
    11    }
    12]
    

    Kill the second bitcoind, delete the wallet file, restart:

    0$ kill `cat 2/testnet3/bitcoind.pid`
    1$ rm 2/testnet3/wallet.dat
    2$ bitcoind -datadir=2 -daemon
    

    Reimport the address:

    0$ bitcoind -datadir=2 importaddress mhou3jmi6Snxw4Y7nszn7gFTbUzHdiBt9y 'test' true
    

    Look for unspents, and they no longer appear:

    0$ bitcoind -datadir=2 listunspent 0
    1[
    2]
    

    Any ideas/thoughts on this? I might have to disable wallet imports if I can’t figure this one out soon.

  10. wtogami commented at 6:58 am on January 11, 2014: contributor
    Could that issue be related to #3502 ?
  11. kyledrake commented at 8:00 pm on January 11, 2014: none

    @wtogami I’m not sure, but it’s similar for sure.

    importaddress <address> [label] [rescan=true]

    It does seem to rescan when rescan=true because the CPU spikes, but it doesn’t find the unspent transactions for the address.

  12. wtogami commented at 9:45 am on January 13, 2014: contributor
    @kyledrake mhou3jmi6Snxw4Y7nszn7gFTbUzHdiBt9y doesn’t seem to import any transactions into the wallet with master + #3383 while other addresses do.
  13. kyledrake commented at 8:47 pm on January 13, 2014: none
    That’s crazy. Is it possible there’s something wrong with that address?
  14. wtogami commented at 5:05 am on January 14, 2014: contributor

    I noticed there’s a bunch of instances of bool “isMine” in several parts of the code after this commit.

    0<sipa> warren: the return value of IsMine(CTransaction) is supposed to be a bool - it should be called "IsRelevantToMe", as it could just as easily be a mix
    1<sipa> for NotifyAddressBookChanged it could be made into isminetype, if the GUI uses/needs that information
    

    @sipa clarification?

  15. sipa commented at 10:35 pm on January 14, 2014: member

    So, there are two instances where something “IsMine”-like occurs in non-GUI code that returns a bool, and not an isminetype:

    • In CWallet::IsMine(CTransaction), we return a bool because it’s not about a particular output being spendable or not, just about whether the transaction is relevant to our wallet. So, this is correct. It would be more clear if the method were renamed to CWallet::IsRelevant or something.
    • The NotifyAddressBoolChanged signal passes a bool along to indicate whether a destination is ours or not. If we wanted to distinguish in the GUI whether listed addresses of ours are considered spendable-from, then it may make sense to upgrade that bool to an isminetype, but that will depend on the GUI using it for something.
  16. Add support for watch-only addresses
    Changes:
    * Add Add/Have WatchOnly methods to CKeyStore, and implementations
      in CBasicKeyStore.
    * Add similar methods to CWallet, and support entries for it in
      CWalletDB.
    * Make IsMine in script/wallet return a new enum 'isminetype',
      rather than a boolean. This allows distinguishing between
      spendable and unspendable coins.
    * Add a field fSpendable to COutput (GetAvailableCoins' return type).
    * Mark watchonly coins in listunspent as 'watchonly': true.
    * Add 'watchonly' to validateaddress, suppressing script/pubkey/...
      in this case.
    
    Based on a patch by Eric Lombrozo.
    33a7f23810
  17. qt: Hide unspendable outputs in coin control c1e048fbe4
  18. BitcoinPullTester commented at 1:22 pm on January 23, 2014: none
    Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/c1e048fbe4b59ffc539eb2e7b11d3dd5ae4abff6 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.
  19. ryancdotorg commented at 0:19 am on January 31, 2014: none
    I just patched bitcoin/bitcoin:master with this (which now has #3502 applied) and the rescan now picks up the transactions that were previously missed.
  20. kyledrake commented at 9:58 am on February 12, 2014: none

    @ryancdotorg where can I find your patch for latest?

    Your patch is possibly my last hope for getting the transaction malleability fixes into this.

  21. ryancdotorg commented at 3:56 pm on February 12, 2014: none

    @kyledrake not sure what you’re asking about. This patch applied cleanly against bitcoin/bitcoin:master at 19007cf5529bc35a3baf53b14c6559bda3b2b206

    easiest way to apply it is wget -O - #3383.diff | patch -p1

  22. erth64net commented at 1:31 am on February 15, 2014: none

    Yesterday, I decided to fork bitcoin/bitcoin and applied #3383 using: curl #3383.diff | patch -p1

    Patch applied without issue, and we’re now running a watch-only wallet. Over 10,000 addresses have been imported, and a mere ~15 minutes after starting rescan we were ready to rock. Wallet balance is accurate - so it looks like rescan picked up everything without issue.

    Thank you for putting this patch out there and considering(?) it for 0.9.0. Prior to this point, we were heavily dependent upon blockchain.info’s rawaddr/total_received API function. With hot-button topics such as transaction malleability, MITM attacks, and further decentralization of the bitcoin network. It would be immensely useful to leverage watch-only (e.g. public keys only) wallets when integrating a web app with bitcoind.

  23. tuttleorbuttle commented at 10:52 pm on February 18, 2014: none
    awesome! if this patch makes it into 0.9.0 it would be a great help for Open Transactions.
  24. luke-jr commented at 0:16 am on February 20, 2014: member
    @drak It remains inappropriate to merge due to lack of a reasonable use case.
  25. sipa commented at 0:23 am on February 20, 2014: member
    @luke-jr Um, what?
  26. luke-jr commented at 0:26 am on February 20, 2014: member
    @sipa It does not make sense to monitor individual addresses,in a wallet. Addresses only receive, so the balance would just grow unbounded. The only apparent “use case” for this AFAIK is trying to emulate watch-only wallets.
  27. sipa commented at 0:30 am on February 20, 2014: member

    It will require some manual synchronization with a live wallet, to feed it new addresses, but apart from that, there is not difference. You can monitor incoming payment, and remaining wallet balance.

    Yes, it would be nicer if we had BIP32 watch-only wallets that could generate these addresses automatically, but one does not prevent the other.

  28. luke-jr commented at 0:31 am on February 20, 2014: member
    @sipa You can’t see a remaining wallet balance, since sends are not related to mere addresses. If this tracks when outputs received by the address are spent, I’d consider that a bug since those are unrelated to the address.
  29. sipa commented at 0:32 am on February 20, 2014: member
    @luke-jr Please… how is that different from any other wallet?
  30. luke-jr commented at 0:45 am on February 20, 2014: member
    @sipa Addresses are not wallets.
  31. sipa commented at 0:47 am on February 20, 2014: member
    @luke-jr Collections of them are.
  32. sipa commented at 0:48 am on February 20, 2014: member
    @luke-jr The reason for not wanting to consider an address a wallet is because it encourages micromanagement and address reuse. What this does is just allowing you to build a wallet with addresses you control - you just don’t want to import their private keys.
  33. luke-jr commented at 0:51 am on February 20, 2014: member
    @sipa That’s already possible since 0.4.
  34. sipa commented at 0:54 am on February 20, 2014: member

    Do you seriously consider “encrypt your wallet file and throw away the key, then import it elsewhere” a user-friendly suggestion? Also, what do you do when new keys were generated in the mean time and you need to sync? Shut down and do the copying all over? Please…

    This just gives a way to import addresses instead of their private keys. Yes, it requires key-level management and with BIP32 it could be improved. But it is useful, and it’s currently the only decent way possible that I know.

  35. luke-jr commented at 1:03 am on February 20, 2014: member
    @sipa MUCH more user-friendly than “iterate over all the ECDSA private keys in your wallet, including ones intentionally hidden from you, find their addresses, and run “importaddress” with them one by one understanding you’re not really importing addresses, but a read-only copy of the original wallet”. Compared to what is suggested by this PR, copying a one-way-encrypted wallet file is much easier, especially if people know to use -keypool to ensure they never need to generate new keys in the wallet again. And yes, as you note, BIP32 will make it even easier Real Soon Now.
  36. luke-jr commented at 1:14 am on February 20, 2014: member
    @drak The only paper wallets are HD wallets. Saving an ECDSA private key on paper is not a wallet, and that is precisely the bad use cases we should be discouraging enough to avoid merging this.
  37. ghost commented at 1:25 am on February 20, 2014: none
    Well it’s good to know it works on HD paper wallets, but I still think this should be merged. Once BIP32 becomes widespread and is well integrated in wallets, address reuse go away by itself. But until then, really do need a way to watch addresses. Sorry, but this feature is not going to encourage address re-use and it is useful. There of course also needs to be a way to watch addresses from HD paper wallets, but that might be a separate PR.
  38. laanwj commented at 7:05 am on February 20, 2014: member

    @drak If you want this merged please solve the outstanding issues mentioned in the OP (as it was already ACKed once apart from those nits). Further discussion will not aid here:

    • Rebase
    • Show non-spendable/watch-only balance seperately from available balance in UI and RPC
    • Fix @kyledrake’s scanning issue above (if still a problem, I remember vaguely that it was solved with master)
    • Check @sipa’s comment about CWallet::IsMine/NotifyAddressBoolChanged about regarding IsMine to bool in some places, and if this turns out to be a problem and results in miscounted balance or other wtfs. I don’t think so but it doesn’t hurt to check.
  39. wangbus commented at 12:49 pm on March 2, 2014: none

    Interested in closing this issue out and it’s not clear how the UI will show the non-spendable/watch only balance. I believe we also need to show the confirmed/unconfirmed separately somehow. Moreover, the RPC’s representation of these values should maybe be in another RPC method?

    Suggestions?

  40. bitcoinder commented at 1:30 am on March 4, 2014: none

    @laanwj @erth64net @ryancdotorg i am in $ cd /bitcoin-0.8.2-linux/src/src now yum install patch done

    how do i use #3383.diff to get a watchonly bitcoind? thank you

  41. wtogami commented at 11:28 am on March 4, 2014: contributor

    @wtogami said: watch-only entirely separate from real balances in both RPC and qt right? separate unconfirmed and confirmed watchonly? @laanwj said: yes, basically all the balances would be duplicated available watchonly, pending watchonly, immature watchonly, total watchonly as to how to display this, could be done in two ways, most straightforward would be adding another table if the user uses watch-only @wtogami said: hide it entirely if zero watchonly? @laanwj said: yes like we do for immature now if there is no immature as for RPC, easiest would be to add the watch-only balances to the ‘getwalletinfo’ RPC @wtogami said: and hide it from the other balances @laanwj said: yes, certainly to be clear: the default balance is spendable coins only if it’s shown in ‘getbalance’ it can be spent here and now, we’ve always used this convention and this PR should keep it also it would be nice to have a flag in ’listtransactions’ output to mark transactions that are watch-only (there is already a flag in ’listunspent’ output)

    summary would be: completely isolate the watchonly balances from the “readwrite” balances, mark watchonly transactions

  42. laanwj commented at 11:33 am on March 4, 2014: member

    “as to how to display this, could be done in two ways” -> the other way would be having two columns in the “Wallet” table, one for the “readwrite” balance and one for the “watchonly” balance, hiding the watchonly column when the user doesn’t use watchonly.

    “and hide it from the other balances” -> to be clear, this means that the two (set of) balances are disjunct, “hide” sounds sneakier than intended

  43. nanotube commented at 4:11 am on March 16, 2014: none

    FWIW, i think it would be very useful to have a ‘watch-only’ address capability.

    Sidestepping all the UI issues herein discussed, (I think having separate balances, if any, is a fine idea), I will also note that it should be possible to author a transaction using the inaccessible inputs, for export and subsequent signing offline. That would be one of the major use cases, IMO - the ability to easily author transactions for later signing by your offline keys.

  44. laanwj commented at 11:04 am on March 23, 2014: member
    @wangbus Any luck finishing this? If you’re no longer working on this please let us know too, so someone else could pick this up.
  45. wangbus commented at 11:06 am on March 23, 2014: none
    Will pick this up early next week. Posting again if that doesn’t come through.
  46. wangbus commented at 10:20 am on March 27, 2014: none
    Apologies, swamped this week. Will be picking it up after Friday.
  47. tuttleorbuttle commented at 10:14 pm on March 28, 2014: none
    I am playing around with it a bit, added some simple changes to make it more clear which is watch-only and which is your own. maybe you can use this, I’ll upload my fork soon.
  48. tuttleorbuttle commented at 6:49 am on March 29, 2014: none
    here it is: 6824f5a44a776ee6124dcccf6f92c27b2fdb850d it adds another row below Immature balance and some details to transaction description.
  49. laanwj commented at 7:15 am on March 31, 2014: member

    @tuttleorbuttle it’s on the right track! however, see @wtogami’s post above and my reply to it; all the balances (available, immature, pending, total) would be replicated for watch-only.

    Putting ‘watch only’ in the same category as those balances is confusing because it raises questions like ‘is this only the confirmed part, or everything?’.

  50. rebroad commented at 12:13 pm on March 31, 2014: contributor
    I’d like to better understand @luke-jr’s argument that this shouldn’t be merged.
  51. sipa commented at 12:31 pm on March 31, 2014: member

    My interpretation of @luke-jr’s argument is that this allows building a wallet from arbitrary addresses, allowing tracking of transaction to individual address, and their spendability, essentially providing “balance of an address” - management at the address level rather than at the wallet level.

    I agree that is unfortunate, and shouldn’t be encouraged, but it is no different than allowing importing individual private keys in the first place, which also allows that level of micromanagement.

    A higher-level solution is using watch-only wallets, using public BIP32 chains, rather than needing to build them yourself from individual addresses. That isn’t available right now, however, and will not work for all legacy systems anyway. @luke-jr Correct me if I’m wrong, of course.

  52. kyledrake commented at 6:50 pm on March 31, 2014: none

    I get that the watchonly patch is not popular with the core team. I would like to propose an alternative idea here and get your thoughts on it.

    My alternative idea is to have bitcoind compile an index of all the existing utxos in the blockchain, with the address as the key.

    This is not related to the wallet. Instead, it’s exactly the same idea as the txindex. You could have a flag to bitcoind when it starts as such:

    utxoindex=1

    Signaling that you would like this. Then, there could be an api call to retreive the current list of utxos for addresses:

    getutxos <address> [confirmations]

    Or something similar. It wouldn’t be a wallet or related to the wallet code - it would just be an index of utxos, simple as that.

    Does this satiate the concerns core has with the watchonly patch?

  53. kyledrake commented at 6:56 pm on March 31, 2014: none
    The current way to do this outside of bitcoind is to manually scan the entire blockchain from bitcoind using the RPC and write code to track all of this elsewhere, which is 1) difficult to do safely (and correctly the first time), 2) requires a lot of code duplication that bitcoind already does, and 3) takes a very long time. It’s also lead to stability issues when for example blockchain.info had a database issue and had to manually rescan their entire database. It’s a really byzantine solution to the problem, one that is best handled by bitcoind IMHO and really could have nothing to do with the wallet code.
  54. gmaxwell commented at 6:59 pm on March 31, 2014: contributor

    @kyledrake What you’re suggesting is inherently unscalable. The watch-only patch isn’t liked by Luke, but other than some concerns about how the UI works for unspendable coins I think it’s fine with everyone else.

    I don’t think we’ll consider including an addr index until we have pruning deployed so that the full marginal cost (right now about 20Gbytes) of turning on such an index is visible to those who use it.

  55. sipa commented at 7:02 pm on March 31, 2014: member
    @gmaxwell I think @kyledrake is only suggesting indexing the UTXOs, not the full blockchain, which is far more scalable (and likely to happen with committed UTXOs anyway, if the address-indexed version of that gets deployed).
  56. kyledrake commented at 7:06 pm on March 31, 2014: none

    @sipa Yeah exactly! Just an index of the utxos. Same idea as the txindex. And you need to explicitly enable it in the config, so that it doesn’t build for people that don’t want it.

    I actually would prefer that approach vs watchonly, simply because it increases reliability: Instead of telling bitcoind which addresses I need to listen to, I can run a pool of them and just query addresses anytime I want. It also increases privacy because an attacker cannot get a full list of which addresses the server is managing from bitcoind.

  57. gmaxwell commented at 7:10 pm on March 31, 2014: contributor
    @sipa hm. indeed. utxo address indexing is an interesting thought. I don’t think it replaces watching wallets but I can certantly see uses for that.
  58. sipa commented at 7:18 pm on March 31, 2014: member
    @kyledrake But you can’t implement a full wallet using it (no history, only currently available).
  59. kyledrake commented at 7:30 pm on March 31, 2014: none
    @sipa I believe I can. The wallets I’m designing don’t have the notion of sending from other wallets, so payments can only be sent out from the wallet itself, which can record incoming utxos as transactions. And then when I send them out, I record that as a sent transaction. Coinpunk actually works this way as-is - I keep a transaction ledger with the wallet.
  60. laanwj commented at 6:50 am on April 1, 2014: member

    The watchonly patch is fine (see the amount of ACKs). As I’ve said about 10 times (browse back please) there are just a nit left that need to be fixed:

    • The watch-only balances must be separate from the main balance (both in RPC and UI)

    If someone picked this up and fixed the outstanding issues it could have been merged 10 times by now.

    Create a new issue for the UTXO index, this is not the place to discuss that, it just adds to the already cluttered thread.

  61. anton000 commented at 1:33 am on April 3, 2014: none
    Agree with @laanwj . On the other hand, although it’s not directly related to this PR kyle’s idea actually render’s watch-only wallets issue “moot”. I’m quite sure most, if not all, use case of watching addresses. @kyledrake would love to know if you’re pursuing this.
  62. kyledrake commented at 1:49 am on April 3, 2014: none
    @anton000 I will file an issue for this shortly, and reference it here.
  63. tuttleorbuttle commented at 9:16 pm on April 5, 2014: none

    here’s a commit that entirely separates watchonly and regular balance in the GUI: [deprecated]

    here’s one that marks watchonly transactions in transaction history with a “w”: [deprecated]

    I’ll also add a commit to fix the RPC commands if no one else is working on that right now.

  64. tuttleorbuttle commented at 4:51 pm on April 8, 2014: none

    I added a true/false flag to the affected RPC commands so you can select if you want watchonly transactions shown too. The GUI layout needs a little bit of work but everything works. https://github.com/tuttleorbuttle/bitcoin/commits/watchonly

    Not sure yet how to mark watchonly transactions in listtransactions but I’ll add something for that too.

  65. tuttleorbuttle commented at 4:03 pm on April 9, 2014: none
    Here’s a patch to mark watchonly transactions in listtransactions: 9497d4f493310bb645911031fb1e8a6c799baea2 (does not require 9ad838c3b65ab5d4aa92db6e47813530a6c66f33) I rebased my watchonly branch on bitcoin master. Can someone have a look at it?
  66. laanwj commented at 5:59 pm on April 9, 2014: member
    @tuttleorbuttle thanks a lot for your work on this! As for getting people to look at it, I suggest filing it as a new pull request (I’ll close this one), that’s easier for review and discussion and such.
  67. tuttleorbuttle commented at 6:25 pm on April 10, 2014: none
    Alright, i created a new pull request: #4045
  68. laanwj commented at 6:02 am on April 11, 2014: member
    Closing this one, thanks for picking this up @tuttleorbuttle
  69. laanwj closed this on Apr 11, 2014

  70. Bushstar referenced this in commit 8ab1a3734a on Apr 8, 2020
  71. 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-11-17 21:12 UTC

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