Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

listreceivedbyaddress Filter Address #9991

Open
wants to merge 2 commits into
from

Conversation

Projects
None yet
9 participants
Member

NicolasDorier commented Mar 14, 2017

Supersede #9503 created by @JeremyRubin , I will maintain it.

Member

NicolasDorier commented Mar 14, 2017

  1. Rebased and fixed conflicts
  2. Addressed @kallewoof nits
  3. Add the new parameter to client.cpp
Member

NicolasDorier commented Mar 16, 2017

@luke-jr @jnewbery @JeremyRubin nit addressed, can you re-ACK?

qa/rpc-tests/receivedby.py
+ #Test Address filtering
+ #Only on addr
+ expected = {"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]}
+ res = self.nodes[1].listreceivedbyaddress(0, True, True, addr)
@jnewbery

jnewbery Mar 16, 2017

Member

Nit: Consider using named arguments here, instead of positional arguments (since the meaning of the arguments is not clear without having to go back to the definition of listreceivedbyaddress).

@NicolasDorier

NicolasDorier Mar 17, 2017

Member

Listreceivedbyaddress is not known at compile time, and thus has no definition in python. This is interpreted at runtime. So I can't really use named argument. Would inline comment be good ?

EDIT: No mid line comments in python

@jnewbery

jnewbery Mar 17, 2017

Member

You can use named arguments in the RPC calls. See #9983 for example.

qa/rpc-tests/receivedby.py
+ {"address":empty_addr},
+ {"address":empty_addr, "account":"", "amount":0, "confirmations":0, "txids":[]})
+
+ #Test Address filtering
@jnewbery

jnewbery Mar 16, 2017

Member

I'd prefer this test if other_addr (currently declared on line 78) received some funds before you did your tests on listreceivedbyaddress() with a filter address. This isn't currently testing the case where the wallet contains multiple addresses with funds and you want to see the transactions received by one of those addresses. Ideally the test case would be:

  • define addr and send funds to it (already done for you in lines 42-43)
  • define other_addr and send funds to it
  • call listreceivedbyaddress() filtering on addr. Assert only one transaction is returned.
  • call listreceivedbyaddress() filtering on other_addr. Assert only one transaction is returned.
  • call listreceivedbyaddress() with no filtering. Assert both transactions are returned.
src/wallet/rpcwallet.cpp
"\nList balances by receiving address.\n"
"\nArguments:\n"
"1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
"2. include_empty (bool, optional, default=false) Whether to include addresses that haven't received any payments.\n"
"3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n"
-
+ "4. only_address (string, optional) If present, only return information on this address. Otherwise, return all information.\n"
@jnewbery

jnewbery Mar 16, 2017

Member

minor nit: align parentheses with line above.

Member

jnewbery commented Mar 16, 2017

Looks good. A couple of nits and a suggestion on improving the test case.

Contributor

JeremyRubin commented Mar 16, 2017

utAck

Member

NicolasDorier commented Mar 17, 2017

@jnewbery I improved the tests, and fixed the alignement. I can't use named parameter in the test though.

Member

NicolasDorier commented Mar 17, 2017

added named parameters to one call to listreceivedbyaddress in the tests for better readability.

Member

jnewbery commented Mar 17, 2017

line 73 minConf needs to be minconf.

with that change, tested ACK. Good stuff @NicolasDorier !

Member

NicolasDorier commented Mar 18, 2017

@jnewbery thanks done, @JeremyRubin did the hard work :)

Contributor

EthanHeilman commented Mar 21, 2017

utACK - the code looks good and this is very useful functionality.

Member

NicolasDorier commented Mar 22, 2017

@TheBlueMatt I fixed nits and added tests, can you re-ACK ?

ACK - works fine.
This could be (not sure if should be) combined with fixing this issue for correct GUI experience: #9192

@nopara73 nopara73 referenced this pull request in NTumbleBit/NTumbleBit May 25, 2017

Closed

Tumbling is very slow, lot's of Client's redeem broadcasted #34

Member

NicolasDorier commented Jun 14, 2017

Closing. I am using a workaround now, I am caching the whole listtransaction, at every block. This call would have been super useful though.

Member

jnewbery commented Jun 14, 2017

😞 I'm happy to reACK if you decide to reopen this!

@NicolasDorier NicolasDorier reopened this Jun 15, 2017

Member

NicolasDorier commented Jun 15, 2017

@jnewbery, if you have interest, I am reopening, I guess it does not hurt to keep it opens, it is not high maintenance PR. I was thinking to allow multiple addresses to be passed in the filter, instead of only one.

For NTumbleBit, I changed the design, I have a method called GetTransactions(address) which should send back the inputs AND outputs transactions of this address. listreceivedbyaddress would only show input transactions.

The way I ended up implemeting my need is by caching listtransaction then for each transaction in it, caching gettransaction in a internal database. I now have good performance, and I am not sure this RPC method would suit my case now.


EDIT: Documenting why I need also all transaction spent from this address: (not only transactions received)

In TumbleBit, there is a chain of transaction.

[Escrow] -> [Offer] -> [Fulfill]

Escrow is confirmed.
The user knows one of the ScriptPubKey inside Offer, but not the transaction ID.
His goal is to fetch Fulfill on the blockchain. (When the ScriptPubKey of Offer get spent, then important preimages are revealed)

So the way I am doing it now is adding Offer's ScriptPubKey as WatchOnly. Then fetching all the transactions from the wallet, caching them in internal database, and going through all those transactions to see if there is one input which is spent by the ScriptPubKey of Offer. If yes, then we have [Fulfill].

Watching all transactions related to one address is very useful, not only the received transaction of the address.

In Core, however it is not possible, because knowing if a transaction is "from an address" is considered bad practice.
At the root, this is the same reason as to why #10007 could not make it..

Owner

sipa commented Jun 16, 2017

@NicolasDorier Do you actually need the wallet functionality (balance tracking, UTXO management, coin selection, ...), or just a means to be notified of certain transactions?

@sipa Need the wallet functionality for NTumbleBit.

Owner

sipa commented Jun 17, 2017

Can you clarify what functionality it relies on?

A lot, but I am not sure which are relevant to this discussion with the workaround. @NicolasDorier will have a better insight. https://github.com/NTumbleBit/NTumbleBit/tree/master/NTumbleBit.TumblerServer/Services/RPCServices

@@ -1206,6 +1206,17 @@ UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByA
if(params[2].get_bool())
filter = filter | ISMINE_WATCH_ONLY;
+ bool fFilterAddress = false;
+ CTxDestination filterAddress = CNoDestination();
+ if (!fByAccounts && params.size() > 3) {
@jonasschnelli

jonasschnelli Aug 15, 2017

Member

Use a simpler check:

CBitcoinAddress address(request.params[3].get_str());
    if (!address.IsValid())
+
+ // Create mapAddressBook iterator
+ // If we aren't filtering, go from begin() to end()
+ auto start = pwallet->mapAddressBook.begin();
@jonasschnelli

jonasschnelli Aug 15, 2017

Member

This loop-or-find logic seems to be a bit wired.
I probably would have factored out the JSON object packing and either called the new function from within the range based loop or after the find().

Member

jonasschnelli commented Aug 15, 2017

Needs rebase.

Concept ACK. I think the by address filter is in general useful.

Member

NicolasDorier commented Aug 17, 2017

@sipa just saw now your previous question.
As far as TB is concerned, I am using balance tracking, UTXO management, and coin selection management of Bitcoin Core for funding the escrow transactions.

I am also using Core as a block explorer: There is some well known address on which I would like to be notified is money is sent to it, or sent from. This PR allows me to know when something is sent to the address.
However, I still need a new rpc method for knowing if something is sent from an address.

Until I have the two features, my only way is to poll periodically listtransaction then fetch all transaction with gettransaction, and see if the relevant addresses are inside. This work well but is very cumbersome. It also does not scale well, if I do not cache the result of gettransaction.

We kind of talked about that in Tokyo, and you seemed to think that the best is that I develop my own wallet, unrelated to bitcoin RPC. I don't like it but I think this is the way I will go for future projects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment