Skip to content
New issue

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

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: describe protocol version 2.0 #90

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
68 changes: 59 additions & 9 deletions docs/protocol-basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,12 @@ revision number.

A party to a connection will speak all protocol versions in a range,
say from `protocol_min` to `protocol_max`, which may be the same.
When a connection is made, both client and server must initially
assume the protocol to use is their own `protocol_min`.

The client should send a :func:`server.version` RPC call as early as
possible in order to negotiate the precise protocol version; see its
description for more detail. All responses received in the stream
from and including the server's response to this call will use its
negotiated protocol version.
The client must send a :func:`server.version` RPC call as the first
message on the wire, in order to negotiate the precise protocol
version; see its description for more detail.
All responses received in the stream from and including the server's
response to this call will use its negotiated protocol version.


.. _script hashes:
Expand Down Expand Up @@ -138,8 +136,60 @@ block public key.

.. _status:

Status
------
Status (protocol 2.0 and later)
-------------------------------

To calculate the `status` of a :ref:`script hash <script hashes>` (or
address):

1. Consider all transactions touching the script hash (both those spending
from it, and those funding it), both confirmed and unconfirmed (in mempool).

2. Order confirmed transactions by increasing height (and position in the
block if there are more than one in a block).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script hash status is dependent on the transaction ordering.
If I order transactions incorrectly, I get the wrong script status hash and I'll do some extra requests which increase the server load.
This is more likely to happen if I have multiple transactions involving a script in the same block.

How the client should know the (relative) position of a transaction in the block?
Should the client infer it from the order in the returned list by previous calls to get_history?

Does it make sense to use the same ordering that is used for mempool transactions for confirmed transactions too?

AFAICT it would be simpler for client libraries to implement correctly, and indirectly it should help the server too.


3. For mempool transactions, we define **height** to be ``-1`` if the
transaction has at least one unconfirmed input, and ``0`` if all inputs are
confirmed.

4. Order mempool transactions by ``(-height, tx_hash)``, that is,
``0`` height txs come before ``-1`` height txs, and secondarily the
txid (in network byteorder) is used to arrive at a canonical ordering.

5. For each confirmed tx, form a bytearray: ``tx_hash+height``, where:

* ``tx_hash`` is the 32-byte transaction hash in network byteorder
(reverse of human display endianness)

* ``height`` is the height of the block the tx is included in,
serialised as 4-bytes, little-endian, signed (two's complement)

6. For each mempool tx, form a bytearray: ``tx_hash+height+fee``, where:

* ``tx_hash`` is the 32-byte transaction hash in network byteorder
(reverse of human display endianness)

* ``height`` is either ``0`` or ``-1``, as defined above,
serialised as 4-bytes, little-endian, signed (two's complement)

* ``fee`` is the transaction fee in minimum coin units (satoshis),
serialised as 8-bytes, little-endian, unsigned

7. The :dfn:`status` of the script hash is defined by the following recursion:

* ``status_0`` is 32 zero bytes

* ``status_n`` is calculated as ``sha256(status_(n-1) + tx_n)``

That is, for a script hash with an empty history, the status is ``status_0``.
If the history contains ``n`` txs, the status is ``status_n``. The ``tx_n``
series consists of, first the confirmed txs touching the script hash,
followed by the mempool txs touching it; formatted as described above, as
bytearrays of length 36 or 44.


Old Status (before protocol 2.0)
--------------------------------

To calculate the `status` of a :ref:`script hash <script hashes>` (or
address):
Expand Down
34 changes: 33 additions & 1 deletion docs/protocol-changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Protocol Changes
================

This documents lists changes made by protocol version.
This document lists changes made by protocol version.

Version 1.0
===========
Expand Down Expand Up @@ -175,3 +175,35 @@ New methods
-----------

* :func:`blockchain.name.get_value_proof` to resolve a name (with proof). Name index coins (e.g. Namecoin) only.


.. _version 2.0:

Version 2.0
===========

Changes
-------

* Breaking change for the version negotiation: we now mandate that
the :func:`server.version` message must be the first message sent.
That is, version negotiation must happen before any other messages.
* The status of a scripthash has been re-defined. The new definition is
recursive and makes it possible not to redo all hashing for most
updates.
* :func:`blockchain.scripthash.get_history` changed significantly to
allow pagination of long histories.
* :func:`blockchain.scripthash.get_mempool` previously did not define
an order for mempool transactions. We now mandate a specific ordering.
* The previously required *height* argument for
:func:`blockchain.transaction.get_merkle` is now optional.
* Optional *mode* argument added to :func:`blockchain.estimatefee`.
* :func:`blockchain.block.headers` now returns headers as a list,
instead of a single concatenated hex string.

New methods
-----------

* :func:`blockchain.outpoint.subscribe` to subscribe to a transaction
outpoint, and get a notification when it gets spent.
* :func:`blockchain.outpoint.unsubscribe` to unsubscribe from a TXO.
Loading