Skip to content

Commit

Permalink
Added blockchain.transaction.dsproof.* documentation
Browse files Browse the repository at this point in the history
Plus misc fixups and added a section in Protocol Basics describing what
a double-spend proof object contains.

Bumped docs version to 1.4.5.
  • Loading branch information
cculianu committed Mar 2, 2021
1 parent 9061333 commit 005253d
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 7 deletions.
5 changes: 2 additions & 3 deletions conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
VERSION="Fulcrum Protocol Reference 1.4.3"
VERSION="Fulcrum Protocol Reference 1.4.5"

# -- Project information -----------------------------------------------------

project = 'Electrum Cash Protocol'
copyright = '2016-2019, Neil Booth, 2020, Electrum Cash protocol devs'
copyright = '2016-2019, Neil Booth, 2020-2021, Calin Culianu'
author = 'Neil Booth, Calin Culianu, Electrum Cash protocol devs'

# The full version including branding
Expand Down Expand Up @@ -163,4 +163,3 @@
author, 'Fulcrum', 'A Fast & Numble Bitcoin Cash SPV Server.',
'Finance'),
]

78 changes: 75 additions & 3 deletions protocol-basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ is *not implemented* in Fulcrum.
possibly blacklisted.

For the TCP and SSL transports: Each RPC call MUST be delimited by a single newline.
The JSON specification does not permit control characters within strings, so no
confusion is possible there. However it does permit newlines as extraneous
whitespace between elements; client and server MUST NOT use newlines in such a
The JSON specification does not permit control characters within strings, so no
confusion is possible there. However it does permit newlines as extraneous
whitespace between elements; client and server MUST NOT use newlines in such a
way.

A server advertising support for a particular protocol version MUST
Expand Down Expand Up @@ -194,3 +194,75 @@ and confirm the returned roots match.
implementation would require hashing approximately 88MB of data to
provide a single merkle proof. Fulcrum implements an optimization
such that it hashes only approximately 180KB of data per proof.


.. _dsproofs:

Double Spend Proofs (dsproofs)
------------------------------

A double spend proof is information collected by the Bitcoin Cash peer-to-peer
network on transaction inputs for transactions in the mempool that are seen to
have been attempted at being double-spent. Double-spend proofs only apply to
mempool transactions. Once a transaction is confirmed, the double-spend attempt
is no longer relevant (since the transaction cannot be double-spent anymore
unless there is a reorg). Double-spend proofs indicate that a transaction may
not confirm as expected, and that instead there is a risk that its conflicting
transaction will confirm instead.

`The specification for dsproofs can be found here <https://gitlab.com/-/snippets/1883331>`_.

In Fulcrum, the dsproofs are returned as JSON objects with the following keys:

* **dspid**

This is the hexadecimal hash of the :const:`dsproof` as would
be returned by querying the BCHN dsproof RPC :const:`getdsproof`.

* **hex**

The raw serialized double-spend proof itself.

* **outpoint**

A JSON object containing the following keys:

* **txid**

The transaction hash of the transaction that generated this outpoint.

* **vout**

The integer output number for this outpoint.

* **txid**

The primary transaction that is associated with this :const:`dsproof`.

* **descendants**

A JSON array of *txid*'s of all the transactions that are potentially
affected by this double-spend attempt. This list will include `txid` above
plus all of its descendant transactions.

An example `dsproof` object as might be returned by Fulcrum::

{
"dspid": "587d18bf8a64ede9c7450fdaeab27b9b3c46cfa8948f4c145f889601153c56b0",
"txid": "5b59ce35093fbd13549cd6f203d4b5b01762d70e75b8e9733dfc463e0ff8cc13",
"hex": "410c56078977120e828e4aacdd813a818d17c47d94183aa176d62c805d47697dddddf46c2ab68ee1e46a3e17aa7da548c38ec43416422d433b1782eb3298356df441",
"outpoint": {
"txid": "f6e2a16ba665d5402dad147fe35872961bc6961da62345a2171ee001cfcf7600",
"vout": 0
},
"descendants": [
"36fbb099e6de59d23477727e3199c65caae35ded957660f56fc681a6d81d5570",
"5b59ce35093fbd13549cd6f203d4b5b01762d70e75b8e9733dfc463e0ff8cc13"
]
}

Note that as of March 2021, only servers running Bitcoin Cash Node v22.3.0 or later
are capable of reporting double-spend proofs via RPC, and thus only such servers
will provide double-spend proofs to clients via the Electrum Cash protocol.
Servers that support `dsproof` will have the key :const:`"dsproof"` set to
:const:`true` in their :func:`server.features` map.
1 change: 1 addition & 0 deletions protocol-changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ Changes
* :func:`blockchain.transaction.get_merkle` now no longer requires the second
argument *height*. This argument is now optional but still recommended, in
order to save the server from having to look it up.
* :func:`server.features` added a new optional key, :const:`"dsproof"`.

New methods
-----------
Expand Down
130 changes: 129 additions & 1 deletion protocol-methods.rst
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,122 @@ Protocol version 1.0 returning an error as the result:

"258: txn-mempool-conflict"

blockchain.transaction.dsproof.get
==================================

Returns information on a :ref:`double-spend proof <dsproofs>`. The query can be
by either `tx_hash` or `dspid`.

**Signature**

.. function:: blockchain.transaction.dsproof.get(hash)
.. versionadded:: 1.4.5

*hash*

The transaction hash (or `dspid`) as a hexadecimal string.


**Result**

If the transaction in question has an associated :ref:`dsproof <dsproofs>`,
then a JSON object. Otherwise :const:`null`.

**Example Results**::

{
"dspid": "587d18bf8a64ede9c7450fdaeab27b9b3c46cfa8948f4c145f889601153c56b0",
"txid": "5b59ce35093fbd13549cd6f203d4b5b01762d70e75b8e9733dfc463e0ff8cc13",
"hex": "410c56078977120e828e4aacdd813a818d17c47d94183aa176d62c805d47697dddddf46c2ab68ee1e46a3e17aa7da548c38ec43416422d433b1782eb3298356df441",
"outpoint": {
"txid": "f6e2a16ba665d5402dad147fe35872961bc6961da62345a2171ee001cfcf7600",
"vout": 0
},
"descendants": [
"36fbb099e6de59d23477727e3199c65caae35ded957660f56fc681a6d81d5570",
"5b59ce35093fbd13549cd6f203d4b5b01762d70e75b8e9733dfc463e0ff8cc13"
]
}

blockchain.transaction.dsproof.list
===================================

List all of the transactions that currently have double-spend proofs associated
with them.

**Signature**

.. function:: blockchain.transaction.dsproof.list()
.. versionadded:: 1.4.5

**Result**

A JSON array of hexadecimal strings. May be empty. Each string is a
transaction hash of an in-mempool transaction that has a double-spend proof
associated with it. Each of the hashes appearing in the list may be given as
an argument to :func:`blockchain.transaction.dsproof.get` in order to obtain
the associated double-spend proof for that transaction.

**Example Results**::

[
"e67cc122f3c28a4243c3a1b14b38a9474c22ba928af9a194ca2b85426f0fd1bb",
"077f0cc2439f2e48567c72eeeba5a447f8649c00c3d18ab6516eccfd4119726f",
"ccc2f0d90b7067a83566024d4df842f0b6cb8180e18d642fcc85cae8acadbd58"
]

blockchain.transaction.dsproof.subscribe
========================================

Subscribe for :ref:`dsproof <dsproofs>` notifications for a transaction.

**Signature**

.. function:: blockchain.transaction.dsproof.subscribe(tx_hash)
.. versionadded:: 1.4.5

*tx_hash*

The transaction hash as a hexadecimal string.

**Result**

A result identical to what one would get from :func:`blockchain.transaction.dsproof.get`.

**Notifications**

The client will receive a notification when the :ref:`dsproof <dsproofs>` status
of the transaction changes. Its signature is

.. function:: blockchain.transction.dsproof.subscribe(tx_hash, dsproof)
:noindex:

With *dsproof* being identical to what one would get from invoking
:func:`blockchain.transaction.dsproof.get` for that particular *tx_hash*.

blockchain.transaction.dsproof.unsubscribe
==========================================

Unsubscribe from receiving any further :ref:`dsproof <dsproofs>` notifications
for a transaction.

**Signature**

.. function:: blockchain.transaction.dsproof.unsubscribe(tx_hash)
.. versionadded:: 1.4.5

*tx_hash*

The transaction hash as a hexadecimal string.

**Result**

Returns :const:`true` if the transaction was previously subscribed-to for
dsproof notifications, otherwise :const:`false`. Note that :const:`false`
might be returned even for something subscribed-to earlier, because the server
can drop subscriptions in rare circumstances.


blockchain.transaction.get
==========================

Expand Down Expand Up @@ -845,6 +961,8 @@ and, optionally, its height.
**Signature**

.. function:: blockchain.transaction.get_merkle(tx_hash, [height])
.. versionchanged:: 1.4.5
*height* is no longer required and is now optional

*tx_hash*

Expand Down Expand Up @@ -1166,6 +1284,8 @@ Return a list of features and services supported by the server.
.. function:: server.features()
.. versionchanged:: 1.4.2
*hosts* key is no longer required, but recommended.
.. versionchanged:: 1.4.5
*dsproof* key added (optional).

**Result**

Expand Down Expand Up @@ -1244,6 +1364,13 @@ Return a list of features and services supported by the server.
A server should ignore information provided about any host other
than the one it connected to.

* *dsproof*

A boolean value. If present and set to :const:`true`, then the server
has :ref:`double-spend proof <dsproofs>` support, and it supports the
:const:`blockchain.transaction.dsproof.*` set of RPC methods. If this key
is missing or :const:`false`, then the server does not support :ref:`dsproofs <dsproofs>`.


**Example Result**

Expand All @@ -1256,7 +1383,8 @@ Return a list of features and services supported by the server.
"protocol_min": "1.4.3",
"pruning": null,
"server_version": "Fulcrum 1.0.5",
"hash_function": "sha256"
"hash_function": "sha256",
"dsproof": true
}


Expand Down

0 comments on commit 005253d

Please sign in to comment.