Merge remote-tracking branch 'origin/master' into changelog-for-1.0.0

This commit is contained in:
Troy McConaghy 2017-07-05 10:46:51 +02:00
commit 48f295da9b
7 changed files with 508 additions and 5 deletions

View File

@ -13,6 +13,7 @@ import gunicorn.app.base
from bigchaindb import utils from bigchaindb import utils
from bigchaindb import Bigchain from bigchaindb import Bigchain
from bigchaindb.web.routes import add_routes from bigchaindb.web.routes import add_routes
from bigchaindb.web.strip_content_type_middleware import StripContentTypeMiddleware
# TODO: Figure out if we do we need all this boilerplate. # TODO: Figure out if we do we need all this boilerplate.
@ -60,6 +61,7 @@ def create_app(*, debug=False, threads=1):
""" """
app = Flask(__name__) app = Flask(__name__)
app.wsgi_app = StripContentTypeMiddleware(app.wsgi_app)
CORS(app) CORS(app)

View File

@ -0,0 +1,27 @@
import logging
logger = logging.getLogger(__name__)
class StripContentTypeMiddleware:
"""WSGI middleware to strip Content-Type header for GETs."""
def __init__(self, app):
"""Create the new middleware.
Args:
app: a flask application
"""
self.app = app
def __call__(self, environ, start_response):
"""Run the middleware and then call the original WSGI application."""
if environ['REQUEST_METHOD'] == 'GET':
try:
del environ['CONTENT_TYPE']
except KeyError:
pass
else:
logger.debug('Remove header "Content-Type" from GET request')
return self.app(environ, start_response)

View File

@ -1,4 +1,5 @@
[Documentation on ReadTheDocs](http://bigchaindb.readthedocs.org/) - [Documentation on ReadTheDocs](http://bigchaindb.readthedocs.org/)
- [BigchainDB Upgrade Guides](upgrade-guides/)
# The BigchainDB Documentation Strategy # The BigchainDB Documentation Strategy

View File

@ -29,7 +29,7 @@ A CREATE transaction should have exactly one input. That input can contain one o
See the reference on :ref:`inputs <Input>` for more description about the meaning of each field. See the reference on :ref:`inputs <Input>` for more description about the meaning of each field.
To calculate a fulfillment URI, you can use one of the To calculate a fulfillment URI, you can use one of the
:ref:`BigchainDB drivers or transaction-builders <Drivers & Clients>`, :ref:`BigchainDB drivers or transaction-builders <Drivers & Tools>`,
or use a low-level crypto-conditions library as illustrated or use a low-level crypto-conditions library as illustrated
in the page about `Handcrafting Transactions <https://docs.bigchaindb.com/projects/py-driver/en/latest/handcraft.html>`_. in the page about `Handcrafting Transactions <https://docs.bigchaindb.com/projects/py-driver/en/latest/handcraft.html>`_.
@ -52,7 +52,7 @@ See the reference on :ref:`outputs <Output>` for more description about the mean
Below is a high-level description of what goes into building a ``condition`` object. Below is a high-level description of what goes into building a ``condition`` object.
To construct an actual ``condition`` object, you can use one of the To construct an actual ``condition`` object, you can use one of the
:ref:`BigchainDB drivers or transaction-builders <Drivers & Clients>`, :ref:`BigchainDB drivers or transaction-builders <Drivers & Tools>`,
or use a low-level crypto-conditions library as illustrated or use a low-level crypto-conditions library as illustrated
in the page about `Handcrafting Transactions <https://docs.bigchaindb.com/projects/py-driver/en/latest/handcraft.html>`_. in the page about `Handcrafting Transactions <https://docs.bigchaindb.com/projects/py-driver/en/latest/handcraft.html>`_.

View File

@ -1,5 +1,5 @@
Drivers & Clients Drivers & Tools
================= ===============
Libraries and Tools Maintained by the BigchainDB Team Libraries and Tools Maintained by the BigchainDB Team
----------------------------------------------------- -----------------------------------------------------

View File

@ -0,0 +1,433 @@
# Updating from BigchainDB v0.10 to v1.0
BigchainDB v1.0 stands for backwards compatibility. This means that all
following [minor](http://semver.org/) releases after version 1.0 will always be
backwards-compatible to previous versions.
For all future releases, we commit to not introduce breaking changes to the
public interfaces of BigchainDB's:
- [Data
model](https://docs.bigchaindb.com/projects/server/en/latest/data-models/index.html)
- [HTTP
API](https://docs.bigchaindb.com/projects/server/en/latest/http-client-server-api.html)
- [WebSocket Event Stream
API](https://docs.bigchaindb.com/projects/server/en/latest/websocket-event-stream-api.html)
As we saw the version bump to v1.0 as our last chance in a while to fix minor
annoyances, we intentionally did clean up on the above interfaces. In this
document, we'd like to give a comprehensive summary of those changes to allow
you to upgrade efficiently.
The next sections will go over each of the above mentioned interfaces and
detail the exact changes.
## A note upfront
We tried to test this upgrade guide as best as we could by using it to adjust
our official drivers. If you still find breaking changes that causes your
software to crash, please let us and others reading this guide know by sending
over a Pull-Request or notifying us on Gitter.
Thank you very much :)
## Syntactical changes
#### `tx`, `txid` and `tx_id` becomes `transaction_id`
To establish better consistency between external interfaces, all usages of
`txid`, `tx` and `tx_id` in data models and HTTP API were renamed to
`transaction_id` or `transaction`.
## Breaking Changes to the Data Model
#### Output amount is now a string
BigchainDB transactions may have multiple inputs and outputs, and each output
has an amount, which is the integral number of the asset being transferred. In
prior versions of BigchainDB, the amount was encoded as a number, which on the
face of it is the obvious way to encode an integer. However, as usual the devil
is in the details; JSON, the encoding of choice for BigchainDB transactions,
encodes all numbers including integers as floating point. This isn't a problem
for the majority of circumstances where numbers are small, however in some
environments and for some use cases\*, the number may lose precision.
In order to safeguard against this, amounts are now encoded as strings, and it
is recommended to use a decimal math library (such as
[big.js](https://github.com/MikeMcl/big.js)) when dealing with large numbers in
Javascript. Additionally, numbers are capped at 9e18 to stay comfortably within
the boundary of a 64 bit signed integer.
\* Try this in the Chrome developer console: `2**60 == 2**60+1`.
#### Input `fulfills.txid` is now `transaction_id`
We renamed a TRANSFER transaction's `inputs.fulfills.txid` to
`inputs.fulfills.transaction_id`.
#### Input `fulfills.output` is now `output_index`
We renamed a TRANSFER transaction's `inputs.fulfills.output` to
`inputs.fulfills.output_index`.
#### Signing payload is now the transaction body
The signature payload of a BigchainDB transaction is now "just" the JSON
serialized body of the transaction. This change is invisible to applications
that do not produce transactions with more than one input. However, prior to
the 1.0 release, transactions with multiple inputs had a special signing
protocol, which included reassembly of the transaction. This was identified as
being unneeded, so now the payload that is signed is always just the serialized
transaction, minus signatures. More details, take a look at the
[Pull-Request](https://github.com/bigchaindb/bigchaindb/pull/1225) introducing
the change or at our updated [Handcrafting
Transactions](https://docs.bigchaindb.com/projects/py-driver/en/latest/handcraft.html)
document.
#### Update to Crypto-Conditions version 2
Earlier this year the IETF Interledger working group released an [updated
draft](https://tools.ietf.org/html/draft-thomas-crypto-conditions-02) of their
Crypto-Conditions specification. To send transactions to BigchainDB v1.0, all
transaction's inputs and outputs need to comply to this new version.
Several of the language specific implementations have already been updated,
including:
- [py-crypto-conditions](https://github.com/bigchaindb/cryptoconditions)
- [js-crypto-conditions](https://github.com/interledgerjs/five-bells-condition)
- [java-crypto-conditions](https://github.com/interledger/java-crypto-conditions)
If you don't find your preferred language in this list, do not despair but
reach out to us for help on Github/Gitter or product@bigchaindb.com.
#### Revamp of Crypto-Conditions signing details
In order to create a correct fulfillment for an output condition in BigchainDB,
we include the conditon URI ("ni:///sha-256;..."), to verify the fulfillment
against. However, the condition URI does not tell you who may sign in order to
create a correct fulfillment.
For this, we have the `condition.details` object. This is a recursive data structure
which mirrors the n-of-m threshold / ed25519 condition types that we support.
An example of the new structure is:
```json
{
"details": {
"type": "threshold-sha-256",
"threshold": 2,
"subconditions": [
{
"public_key": "<new owner 1 public key>",
"type": "ed25519-sha-256",
},
{
"public_key": "<new owner 2 public key>",
"type": "ed25519-sha-256",
}
],
},
}
```
#### Transaction version is now 1.0
The `version` key in the transaction is now set to `'1.0'`.
## Breaking Changes to the HTTP API
In this section, we'll go over each of the endpoints separately and list the
changes done to them:
### `GET /`
Documentation:
- [Old](https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html#bigchaindb-root-url)
- [New](https://docs.bigchaindb.com/projects/server/en/v1.0.0/http-client-server-api.html#bigchaindb-root-url)
Changes:
- All notion of `_links` was removed
- `api_v1` is now an object including currently only one further object called
`v1`
- `api.v1` includes links that were originally only available through
`/api/v1/`
- `api.v1` now also includes links to `assets` (a new endpoint) and `outputs`
- `streams_v1`'s link was changed from `streams/valid_tx` to
`streams/valid_transactions`
- `streams_v1` was renamed to `streams`
- Usages of scheme, host and port to API V1's endpoints were removed to allow
for configurations of BigchainDB behind reverse proxies
- e.g. `http://example.com:9984/api/v1/transactions` ==>
`/api/v1/transactions`
```json
// Old
{
"_links": {
"api_v1": "http://example.com:9984/api/v1/",
"docs": "https://docs.bigchaindb.com/projects/server/en/v0.10.2/"
},
"keyring": [
"6qHyZew94NMmUTYyHnkZsB8cxJYuRNEiEpXHe1ih9QX3",
"AdDuyrTyjrDt935YnFu4VBCVDhHtY2Y6rcy7x2TFeiRi"
],
"public_key": "NC8c8rYcAhyKVpx1PCV65CBmyq4YUbLysy3Rqrg8L8mz",
"software": "BigchainDB",
"version": "0.10.2"
}
// New
{
"api": {
"v1": {
"docs": "https://docs.bigchaindb.com/projects/server/en/v0.11.0.dev/http-client-server-api.html",
"statuses": "/api/v1/statuses/",
"streams": "ws://example.com:9985/api/v1/streams/valid_transactions",
"transactions": "/api/v1/transactions/",
"assets": "/api/v1/assets/",
"outputs": "/api/v1/outputs/"
}
},
"docs": "https://docs.bigchaindb.com/projects/server/en/v0.11.0.dev/",
"keyring": [
"6qHyZew94NMmUTYyHnkZsB8cxJYuRNEiEpXHe1ih9QX3",
"AdDuyrTyjrDt935YnFu4VBCVDhHtY2Y6rcy7x2TFeiRi"
],
"public_key": "NC8c8rYcAhyKVpx1PCV65CBmyq4YUbLysy3Rqrg8L8mz",
"software": "BigchainDB",
"version": "0.11.0.dev"
}
```
### `GET /api/v1`
Documentation:
- [Old](https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html#api-root-endpoint)
- [New](https://docs.bigchaindb.com/projects/server/en/v1.0.0/http-client-server-api.html#api-root-endpoint)
Changes:
- All notion of `_links` was removed
- The response object of `/api/v1` now includes links to `assets` (a new
endpoint) and `outputs`
- `streams_v1`'s link was changed from `streams/valid_tx` to
`streams/valid_transactions`
- `streams_v1` was renamed to `streams`
- Usages of scheme, host and port to API V1's endpoints were removed to allow
for configurations of BigchainDB behind reverse proxies
- e.g. `http://example.com:9984/api/v1/transactions` ==>
`/api/v1/transactions`
```json
// Old
{
"_links": {
"docs": "https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html",
"self": "http://example.com:9984/api/v1/",
"statuses": "http://example.com:9984/api/v1/statuses/",
"streams_v1": "ws://example.com:9985/api/v1/streams/valid_tx",
"transactions": "http://example.com:9984/api/v1/transactions/"
}
}
// New
{
"docs": "https://docs.bigchaindb.com/projects/server/en/v0.11.0.dev/http-client-server-api.html",
"statuses": "/api/v1/statuses/",
"streams": "ws://example.com:9985/api/v1/streams/valid_transactions",
"transactions": "/api/v1/transactions/",
"assets": "/api/v1/assets/",
"outputs": "/api/v1/outputs/"
}
```
### `GET /api/v1/transactions/{tx_id}`
Documentation:
- [Old](https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html#get--api-v1-transactions-tx_id)
- [New](https://docs.bigchaindb.com/projects/server/en/v1.0.0/http-client-server-api.html#get--api-v1-transactions-transaction_id)
Changes:
- Previously this endpoint returned transactions from BigchainDB's `BACKLOG`
and from blocks marked as `UNDECIDED`. With version 1.0, this endpoint will
only return transactions included in blocks marked as `VALID`.
### `POST /api/v1/transactions`
Documentation:
- [Old](https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html#post--api-v1-transactions)
- [New](https://docs.bigchaindb.com/projects/server/en/v1.0.0/http-client-server-api.html#post--api-v1-transactions)
Changes:
- A `Location` HTTP header was included in the endpoint's response to allow
users to check the transaction's status more easily via the
`/statuses?transaction_id` endpoint
### `GET /api/v1/outputs`
Documentation:
- [Old](https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html#get--api-v1-outputs?public_key=public_key)
- [New](https://docs.bigchaindb.com/projects/server/en/v1.0.0/http-client-server-api.html#get--api-v1-outputs?public_key=public_key)
Changes:
- Reversed the behavior of the `unspent` query parameter to `spent`, implying
the following behavior:
- If `?spent=true`, the response is an array of all spent outputs
associated with a given public key
- If `?spent=false`, response is an array of all NOT YET spent (or
"unspent" outputs associated with a given public key
- If no ``spent=` filter is present in the request, the response is an
array of all outputs associated with a given public key (spent and
unspent)
Previously the response included a list of relative URLs pointed to
transations' outputs:
```json
// Old
[
"../transactions/2d431073e1477f3073a4693ac7ff9be5634751de1b8abaa1f4e19548ef0b4b0e/outputs/0"
]
// New
[
{
"output_index": 0,
"transaction_id": "2d431073e1477f3073a4693ac7ff9be5634751de1b8abaa1f4e19548ef0b4b0e"
}
]
```
In the future, we're planning to [upgrade this endpoint
further](https://github.com/bigchaindb/bigchaindb/blob/99499b1f8783719a082813912ac9a0d363ae278f/bdb-ip.md#6-a-new-outputs-endpoint)
to meet the requirements of [our
users](https://github.com/bigchaindb/bigchaindb/issues/1227#issuecomment-307297473).
### `GET /api/v1/statuses?tx_id`
Documentation:
- [Old](https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html#get--api-v1-statuses?tx_id=tx_id)
- [New](https://docs.bigchaindb.com/projects/server/en/v1.0.0/http-client-server-api.html#get--api-v1-statuses?transaction_id=transaction_id)
Changes:
- All notion of `_links` was removed. In case of querying the status of a
transaction already included in a block marked `VALID`, no `_links` object is
provided anymore. The response object now only contains a single key value
pair named `status`
- The query parameter `tx_id` was renamed to `transaction_id`, e.g. `GET
/api/v1/statuses?transaction_id=`
```json
// Old
{
"status": "valid",
"_links": {
"tx": "/transactions/04c00267af82c161b4bf2ad4a47d1ddbfeb47eef1a14b8d51f37d6ee00ea5cdd"
}
}
// New
{
"status": "valid",
}
```
### `GET /api/v1/statuses?block_id`
Documentation:
- [Old](https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html#get--api-v1-statuses?block_id=block_id)
- [New](https://docs.bigchaindb.com/projects/server/en/v1.0.0/http-client-server-api.html#get--api-v1-statuses?block_id=block_id)
Changes:
- All notion of `_links` was removed. The response object now only contains a
single key value pair named `status`
```json
// Old
{
"status": "valid",
"_links": {
"tx": "/transactions/04c00267af82c161b4bf2ad4a47d1ddbfeb47eef1a14b8d51f37d6ee00ea5cdd"
}
}
// New
{
"status": "valid",
}
```
### `GET /api/v1/blocks?tx_id`
Documentation:
- [Old](https://docs.bigchaindb.com/projects/server/en/v0.10.2/http-client-server-api.html#get--api-v1-blocks?tx_id=tx_id&status=UNDECIDED|VALID|INVALID)
- [New](https://docs.bigchaindb.com/projects/server/en/v1.0.0/http-client-server-api.html#get--api-v1-blocks?transaction_id=transaction_id&status=UNDECIDED|VALID|INVALID)
Changes:
- The query parameter `tx_id` was renamed to `transaction_id`, e.g. `GET
/api/v1/blocks?transaction_id`
## Breaking Changes to the WebSocket Event Stream API
In the event object sent to a listener, `tx_id` was renamed to
`transaction_id`.
```json
// Old
{
"tx_id": "<sha3-256 hash>",
"asset_id": "<sha3-256 hash>",
"block_id": "<sha3-256 hash>"
}
// New
{
"transaction_id": "<sha3-256 hash>",
"asset_id": "<sha3-256 hash>",
"block_id": "<sha3-256 hash>"
}
```

View File

@ -0,0 +1,40 @@
from unittest.mock import Mock
OUTPUTS_ENDPOINT = '/api/v1/outputs/'
def test_middleware_does_nothing_when_no_content_type_is_provided():
from bigchaindb.web.strip_content_type_middleware import StripContentTypeMiddleware
mock = Mock()
middleware = StripContentTypeMiddleware(mock)
middleware({'REQUEST_METHOD': 'GET'}, None)
assert 'CONTENT_TYPE' not in mock.call_args[0][0]
def test_middleware_strips_content_type_from_gets():
from bigchaindb.web.strip_content_type_middleware import StripContentTypeMiddleware
mock = Mock()
middleware = StripContentTypeMiddleware(mock)
middleware({'REQUEST_METHOD': 'GET',
'CONTENT_TYPE': 'application/json'},
None)
assert 'CONTENT_TYPE' not in mock.call_args[0][0]
def test_middleware_does_notstrip_content_type_from_other_methods():
from bigchaindb.web.strip_content_type_middleware import StripContentTypeMiddleware
mock = Mock()
middleware = StripContentTypeMiddleware(mock)
middleware({'REQUEST_METHOD': 'POST',
'CONTENT_TYPE': 'application/json'},
None)
assert 'CONTENT_TYPE' in mock.call_args[0][0]
def test_get_outputs_endpoint_with_content_type(client, user_pk):
res = client.get(OUTPUTS_ENDPOINT + '?public_key={}'.format(user_pk),
headers=[('Content-Type', 'application/json')])
assert res.status_code == 200