I have been writing tests of the IPDB Test Network HTTP API. To start, I posted a valid, fulfilled CREATE transaction with one output:
{
"outputs": [
{
"amount": 1,
"condition": {
"uri": "cc:4:20:nNMIBNeaFkw-Dv3ZLyyVy75nj58e67jkuPs7PUrxLE0:96",
"details": {
"signature": null,
"type": "fulfillment",
"bitmask": 32,
"public_key": "BZBEoiDpspkQWdW1rXKA7eiXrYqm41q6HAmot3yDEoTi",
"type_id": 4
}
},
"public_keys": [
"BZBEoiDpspkQWdW1rXKA7eiXrYqm41q6HAmot3yDEoTi"
]
}
],
"operation": "CREATE",
"version": "0.9",
"asset": {
"data": {
"type": "test asset",
"time": "14:07:02 02/23/17 CET"
}
},
"inputs": [
{
"owners_before": [
"BZBEoiDpspkQWdW1rXKA7eiXrYqm41q6HAmot3yDEoTi"
],
"fulfillment": "cf:4:nNMIBNeaFkw-Dv3ZLyyVy75nj58e67jkuPs7PUrxLE0ZaSj8aJ7dGA7YFEiMTQTnrMQN3GRLqt7CHJszkqqkn_aI5gpvvWHdxEBto9zt9ckQeBTzZxrbeQFSLfZ_QZ8F",
"fulfills": null
}
],
"id": "9c06ea2c88077f44f0a9147416184e4a3f294ae6958d52067737e23c7c959f25",
"metadata": null
}
I didn't build or post any TRANSFER transactions, so that one output is unspent, i.e. "unspent=true".
When I did a GET /outputs?public_key=BZBEoiDpspkQWdW1rXKA7eiXrYqm41q6HAmot3yDEoTi&unspent=true, I got the response:
["../transactions/9c06ea2c88077f44f0a9147416184e4a3f294ae6958d52067737e23c7c959f25/outputs/0"]
Okay, so far so good. That output (output 0) is indeed unspent.
When I did a GET /outputs?public_key=BZBEoiDpspkQWdW1rXKA7eiXrYqm41q6HAmot3yDEoTi&unspent=false, I got the response:
["../transactions/9c06ea2c88077f44f0a9147416184e4a3f294ae6958d52067737e23c7c959f25/outputs/0"]
That's the exact same response I got when I had unspent=true. This is _not_ what I expected. I expected to get back an empty array or similar, because that public key has no spent (unspent=false) outputs.
A couple of other notes:
Here's how I expected the GET /outputs endpoint to work:
@diminator is this the issue you were experiencing in Kyber a week ago?
No, that was something giving a 500
There is a lot going on in this issue. This may or may not be a bug depending on how you look at it.
We have a method call get_outputs that takes a public key and retrieves all the outputs for that public key (spent and unspent). This method also takes an optional argument include_spent which defaults to True. This allows us to get all outputs and filter out the outputs that were already spent.
So the backend logic allows me to gell _all_ outputs or just the _unspent_ outputs. It has no logic to give me only the _spent_ outputs.
GET /api/v1/outputs?public_key=DPpzzKjtMvqEvUgLYHhELMS9Y6wp5vEdis6dNkS8d9SY
["../transactions/9edb78a33ca97c06e87d69bac5fe711945fcf1fa9e2f1d05ffbc5ab0322719ca/outputs/0",
"../transactions/b138a64586e79a3e4b4ec84843097fda8dfbe2309420b2fb759cd21899622e65/outputs/0"]
This gives all outputs which is the same as GET /api/v1/outputs?public_key=DPpzzKjtMvqEvUgLYHhELMS9Y6wp5vEdis6dNkS8d9SY&unspent=false.
GET /api/v1/outputs?public_key=DPpzzKjtMvqEvUgLYHhELMS9Y6wp5vEdis6dNkS8d9SY&unspent=true
["../transactions/9edb78a33ca97c06e87d69bac5fe711945fcf1fa9e2f1d05ffbc5ab0322719ca/outputs/0"]
This gives only the unspent output.
So if no outputs are spent then &unspent=true, &unspent=false will return the same thing. And from the documentation
unspent – Boolean value (“true” or “false”) indicating if the result set should be limited to outputs that are available to spend. Defaults to “false”.
@ttmc was expecting that &unspent=false would return only the outputs that were already spent when what it actually does is something like don't give me only the unspent outputs.
So either the api logic is wrong and what we want is:
&unspent=false get only the spent outputs&unspent=true get only the unspent outputsOr the api language is wrong and maybe we just rename the &unspent argument to &exclude_spent.
Either way I think this endpoint should go through another design iteration.
This is one of the most important endpoints, so it needs to be easy to understand. I agree that it needs another design iteration.
Or the api language is wrong and maybe we just rename the &unspent argument to &exclude_spent.
👍 for removing double negations like unspents=false. It's quite confusing 🤔