Properly document target_confirmations in listsinceblock #10655

Merged
merged 1 commit into from Jul 26, 2017

Conversation

Projects
None yet
7 participants
Contributor

RHavar commented Jun 23, 2017

There seems to be some misunderstandings about this, but it's a heavily used function so I'd like to make sure the docs are clear about how it works.

For a later issue:

  • Change the default of target_confirmations to 6 (1 is a pretty silly default)
  • Change the name of target_confirmations (it's really a horrible name)
Contributor

TheBlueMatt commented Jul 14, 2017

utACK I know this is a super old issue but I find the current docs astoundingly confusing, can we try for 15?

Member

instagibbs commented Jul 14, 2017

@kallewoof I think you have experience with this call?

documentation sounds reasonable, but I don't actually know how it's used.

Contributor

RHavar commented Jul 14, 2017 edited

The way the API is designed to be used is like this:

Let's say I care about only rescanning of 10:

let confsCareAbout = 10
let  hash = ""
while (true) {
     let res = exec(`bitcoin-cli listsinceblock ${hash} ${confsCareAbout)`)
     process(res.transactions)
     hash = res.lastblock;
}

It's a pretty sweet work flow for handling deposits. Just unfortunately listsinceblock is too buggy and ill-defined (I'll create some bug reports when I can).

But this PR fixes the docs, that makes it a bit clearer what it does. Most people when they read the docs think it's a filter, when it's not.

src/wallet/rpcwallet.cpp
@@ -1690,7 +1690,7 @@ UniValue listsinceblock(const JSONRPCRequest& request)
"\nGet all transactions in blocks since block [blockhash], or all transactions if omitted\n"
"\nArguments:\n"
"1. \"blockhash\" (string, optional) The block hash to list transactions since\n"
- "2. target_confirmations: (numeric, optional) The confirmations required, must be 1 or more\n"
+ "2. target_confirmations: (numeric, optional, default=1) Return the nth block hash from the main chain. 1 would mean the bestblockhash (see lastblock in return value)\n"
@TheBlueMatt

TheBlueMatt Jul 14, 2017

Contributor

Maybe add a note that transactions with fewer confirmations than this are still included in the response, only lastblock is changed by this argument.

Contributor

morcos commented Jul 14, 2017

NACK as is

The documentation is very misleading. But it needs to be made even more clear than this.
Perhaps add "Transactions with any number of confirmations in the range from blockhash to current tip (or the fork point if blockhash is not on current chain) will be returned." somewhere

Contributor

RHavar commented Jul 14, 2017

(or the fork point if blockhash is not on current chain)

Is that what it actually does? o.0 If so thats ....bizarre and wtf.

Contributor

TheBlueMatt commented Jul 14, 2017

Yes, thats what it appears to have always done...docs need to be a shitload clearer here.

Contributor

RHavar commented Jul 14, 2017

I pushed another stab at documenting it based on what @morcos said, but it honestly makes no sense to me. I assume I'm misunderstanding.

Let's imagine I have the blocks:

           /--> C 
A--->B
           \-->D -->E

Where E is the main chain tip. And C is orphaned.

So you're saying if I call listsinceblock C, it's going to return me only transactions between [B, C) AKA transactions I've already processed, and are orphaned?). The expected set of transactions it would return you is between [B, E).

Contributor

morcos commented Jul 14, 2017

Yes it will return between B and E

Contributor

RHavar commented Jul 14, 2017 edited

Hm, so when you said:

Transactions with any number of confirmations in the range from blockhash to current tip (or the fork point if blockhash is not on current chain) will be returned.

You mean that just the lastblock returns $target_confirmations from the (mainTip or convergencePoint) ?.

But this is independent to the transaction filtering stuff?

src/wallet/rpcwallet.cpp
@@ -1690,7 +1690,7 @@ UniValue listsinceblock(const JSONRPCRequest& request)
"\nGet all transactions in blocks since block [blockhash], or all transactions if omitted\n"
"\nArguments:\n"
"1. \"blockhash\" (string, optional) The block hash to list transactions since\n"
- "2. target_confirmations: (numeric, optional) The confirmations required, must be 1 or more\n"
+ "2. target_confirmations: (numeric, optional, default=1) Return the nth block hash from the main chain. e.g. 1 would mean the bestblockhash, unless [blockhash] is not on the current chain, in which case it would return be the common ancestor block between it an the main chain). Note: this is not used as a filter, but only affects [lastblock] in the return value\n"
@TheBlueMatt

TheBlueMatt Jul 14, 2017

Contributor

No, the value returned is always the Nth-from-top block on the best chain.

@RHavar

RHavar Jul 14, 2017

Contributor

Yeah, that's what i thought ><

Contributor

kallewoof commented Jul 15, 2017

target_confirmations seems to be handled in a very weird way right now. It only affects the returned last block, and does not actually affect the transactions being returned in any way. I would declare this a bug, personally. The only time the value is used is at https://github.com/bitcoin/bitcoin/blob/0d457c7b274a66d66d59725f5fe1ee1cef5b6391/src/wallet/rpcwallet.cpp#L1859 where

    CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms];

i.e. to determine the block hash of he last block.

Correct me if I'm wrong.

Contributor

TheBlueMatt commented Jul 15, 2017

@kallewoof you are correct, but that behavior long predates the documentation for the function. I have no idea if anyone uses its previous behavior, but assuming people test things before putting them in production, best to fix the docs and leave the behavior IMO.

Contributor

kallewoof commented Jul 15, 2017

@TheBlueMatt That makes sense to me.

Contributor

RHavar commented Jul 15, 2017 edited

I don't think the behavior is a bug at all, it was intentionally designed for use in a loop like I describe in an earlier comment.

It's actually a really nice and simple way to handle deposits, and I know a few people who do it that way. Note how it works really well if your depositor goes down, because you keep storing the hash you want to scan from. Changing the behavior at this point would be totally unreasonable.

(The only reason I don't handle deposits myself that way, is how it handles double spend (attempts) are weird and inconsistent, which make it very difficult to work with when you're showing unconfirmed stuff)

Contributor

morcos commented Jul 15, 2017

ACK 52295ba

I think that language is clear and accurate

(except I'm not sure about putting brackets around the argument names in the help text, is that something we do anywhere else?)

Contributor

RHavar commented Jul 15, 2017

(except I'm not sure about putting brackets around the argument names in the help text, is that something we do anywhere else?)

I just copied it from the original. It's a bit messy, but it's pretty clear and makes things a lot less ambiguous.

Contributor

kallewoof commented Jul 15, 2017

(The only reason I don't handle deposits myself that way, is how it handles double spend (attempts) are weird and inconsistent, which make it very difficult to work with when you're showing unconfirmed stuff)

The reason why double spends are weird and inconsistent is probably because you are using target_confs > 1. This means if there's a 1-2 block fork, and your target_confs = 10 or something, you will not be told of the differences caused by the orphan since you're listing a block that preceded the fork point.

That's how I interpret this, anyway.

fanquake deleted a comment from Mr-Paradox Jul 15, 2017

Contributor

kallewoof commented Jul 15, 2017

My initial expectation was that transactions with less than target_confs confirmations (i.e. transactions in blocks newer than the returned lastblock at the end) would be excluded from the results. This would give you a buffer of 0-confs and 1-confs that are still at risk. That's not what is happening though.

src/wallet/rpcwallet.cpp
@@ -1717,7 +1718,7 @@ UniValue listsinceblock(const JSONRPCRequest& request)
" \"label\" : \"label\" (string) A comment for the address/transaction, if any\n"
" \"to\": \"...\", (string) If a comment to is associated with the transaction.\n"
" ],\n"
- " \"lastblock\": \"lastblockhash\" (string) The hash of the last block\n"
+ " \"lastblock\": \"lastblockhash\" (string) The hash of the block (target_confirmations-1) from the best block on the main chain. This is typically used to feed back into listsinceblock the next time you call it. So you would generally use a target_confirmations of say 6, so you can keep rescanning the last 6 blocks plus any new ones\n"
@TheBlueMatt

TheBlueMatt Jul 15, 2017

Contributor

"rescanning" means something specific, maybe "so you will be continually re-notified of transactions until they've reached 6 confirmations"

laanwj added this to the 0.15.0 milestone Jul 19, 2017

Owner

laanwj commented Jul 25, 2017

Needs rebase and addressing of @TheBlueMatt 's nit, if this is still to make 0.15

Contributor

RHavar commented Jul 25, 2017

Ok, rebased and addressed Matt's nit

@TheBlueMatt

Looks like a few rebase errors.

src/wallet/rpcwallet.cpp
- "listsinceblock ( \"blockhash\" target_confirmations include_watchonly include_removed )\n"
- "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted.\n"
- "If \"blockhash\" is no longer a part of the main chain, transactions from the fork point onward are included.\n"
- "Additionally, if include_removed is set, transactions affecting the wallet which were removed are returned in the \"removed\" array.\n"
@TheBlueMatt

TheBlueMatt Jul 25, 2017

Contributor

Rebase error here, too.

src/wallet/rpcwallet.cpp
- "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted.\n"
- "If \"blockhash\" is no longer a part of the main chain, transactions from the fork point onward are included.\n"
- "Additionally, if include_removed is set, transactions affecting the wallet which were removed are returned in the \"removed\" array.\n"
+ "listsinceblock ( \"blockhash\" target_confirmations include_watchonly)\n"
@TheBlueMatt

TheBlueMatt Jul 25, 2017

Contributor

Looks like a rebase error - you've removed the include_removed parameter here.

@RHavar

RHavar Jul 25, 2017

Contributor

Sorry, yeah. I fail. Pushed a fix.

src/wallet/rpcwallet.cpp
- "2. target_confirmations: (numeric, optional, default=1) The confirmations required, must be 1 or more\n"
- "3. include_watchonly: (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n"
+ "2. target_confirmations: (numeric, optional, default=1) Return the nth block hash from the main chain. e.g. 1 would mean the bestblockhash. Note: this is not used as a filter, but only affects [lastblock] in the return value\n"
+ "3. include_watchonly: (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')"
@TheBlueMatt

TheBlueMatt Jul 25, 2017

Contributor

Why did you delete the \n here?

@RHavar

RHavar Jul 25, 2017

Contributor

some how screwed that up in the rebase. fixed

Contributor

RHavar commented Jul 25, 2017

Ok, fixed my rebase fail...

src/wallet/rpcwallet.cpp
"Additionally, if include_removed is set, transactions affecting the wallet which were removed are returned in the \"removed\" array.\n"
"\nArguments:\n"
"1. \"blockhash\" (string, optional) The block hash to list transactions since\n"
- "2. target_confirmations: (numeric, optional, default=1) The confirmations required, must be 1 or more\n"
+ "2. target_confirmations: (numeric, optional, default=1) Return the nth block hash from the main chain. e.g. 1 would mean the bestblockhash. Note: this is not used as a filter, but only affects [lastblock] in the return value\n"
@TheBlueMatt

TheBlueMatt Jul 25, 2017

Contributor

I dont think "bestblockhash" is one word.

@RHavar

RHavar Jul 25, 2017

Contributor

Ok. 😭

Contributor

TheBlueMatt commented Jul 25, 2017

utACK

Owner

laanwj commented Jul 26, 2017

utACK 9f8a46f

@laanwj laanwj merged commit 9f8a46f into bitcoin:master Jul 26, 2017

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details

@laanwj laanwj added a commit that referenced this pull request Jul 26, 2017

@laanwj laanwj Merge #10655: Properly document target_confirmations in listsinceblock
9f8a46f Properly document target_confirmations in listsinceblock (Ryan Havar)

Pull request description:

  There seems to be some misunderstandings about this, but it's a heavily used function so I'd like to make sure the docs are clear about how it works.

  For a later issue:
  * Change the default of target_confirmations to 6  (1 is a pretty silly default)
  * Change the name of target_confirmations (it's really a horrible name)

Tree-SHA512: a2fba2fab30019cea9db56cd7e31de95ba31090617ab336bdf130f9591bfcf3fc5fbd9e7e1e40b6c7bd2f74b9b4658afb1fdc7fc44e1f79520d1319758982a1c
78f307b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment