Skip to content

DSProof: Add RPC methods

Calin Culianu requested to merge cculianu/bitcoin-cash-node:dsproof_rpc_1 into master

Co-authored-by: matricz 811338-matricz@users.noreply.gitlab.com

Summary

As per discussions here: https://bitcoincashresearch.org/t/rpc-api-considerations-for-dsproof/269 and in slack, I am pleased to introduce two new RPC methods for the double-spend proof subsystem.

  • getdsprooflist - lists all dsproofs (optionally returning verbose info as well as orphans).
    • This command is intended for "polling" to see if "anything changed" for services that don't use ZMQ (we don't even have dsproof notifications over ZMQ implemented yet anyway).
    • This command can also give an overview or a complete view of the dsproofs in the system currently (sort of like getrawmempool, but just for dsproofs).
  • getdsproof - gets a specific dsproof using dspid, txid, or coutpoint as the key. May return an orphan.
    • If searching by txid, the default is to do a recursive search and return a dsproof for any unconfirmed parents of txid (unless RPC argument recursive=false, in which case it does no recursive search).

RPC API Help

getdsprooflist
getdsprooflist ( verbosity include_orphans )

List double-spend proofs for transactions in the mempool.

Arguments:
1. verbosity          (numeric, optional, default=0) Values 0-3 return progressively more information for each increase in verbosity. This option may also be specified as a boolean where false is the same as verbosity=0 and true is verbosity=2.
2. include_orphans    (boolean, optional, default=false) If true, then also include double-spend proofs that we know about but which are for transactions that we don't yet have.

Result (for verbosity = 0 or false):
[                                  (json array of string)
  "dspid"                          (string) Double-spend proof ID as a hex string.
  , ...
]

Result (for verbosity = 1):
[                                  (json array of object)
  {                                (json object)
    "hex" : "xx",                  (string) The raw serialized double-spend proof data.
    "txid" : "xx"                  (string) The txid of the transaction associated with this double-spend. May be null for "orphan" double-spend proofs.
  }, ...
]

Result (for verbosity = 2 or true):
[                                  (json array of object)
  {                                (json object)
    "dspid" : "xx",                (string) Double-spend proof ID as a hex string.
    "txid" : "xx",                 (string) The txid of the transaction associated with this double-spend. May be null for "orphan" double-spend proofs.
    "outpoint" :                   (json object) The previous output (coin) that is being double-spent.
    {
      "txid" : "xx",               (string) The previous output txid.
      "vout" : n ,                 (numeric) The previous output index number.
    }
  }, ...
]

Result (additional keys for verbosity = 3):
    ...
    "spenders" :                   (json array of object) The conflicting spends.
    [
      {                            (json object)
        "txversion" : n,           (numeric) Transaction version number.
        "sequence" : n,            (numeric) Script sequence number.
        "locktime" : n,            (numeric) Spending tx locktime.
        "hashprevoutputs" : "xx",  (string) Hash of the previous outputs.
        "hashsequence" : "xx",     (string) Hash of the sequence.
        "hashoutputs" : "xx",      (string) Hash of the outputs.
        "pushdata" :               (json object) Script signature push data.
        {
          "asm" : "xx",            (string) Script assembly representation.
          "hex" : "xx"             (string) Script hex.
        }
      }, ...
    ]

Examples:
> bitcoin-cli getdsprooflist 2 false
> bitcoin-cli getdsprooflist false false
> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getdsprooflist", "params": [1, true] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/
getdsproof
getdsproof "dspid_or_txid_or_outpoint" ( verbosity recursive )

Get information for a double-spend proof.

Arguments:
1. dspid_or_txid_or_outpoint    (string, required) The dspid, txid, or output point associated with the double-spend proof you wish to retrieve. Outpoints should be specified as a json object containing keys "txid" (string) and "vout" (numeric).
2. verbosity                    (numeric, optional, default=2) Values 0-3 return progressively more information for each increase in verbosity. This option may also be specified as a boolean where false is the same as verbosity=0 and true is verbosity=2.
3. recursive                    (boolean, optional, default=true) If doing a lookup by txid, then search for a double-spend proof for all in-mempool ancestors of txid as well. This option is ignored if not searching by txid.

Result (for verbosity = 0, 1, false):
{                                (json object)
  "hex" : "xx",                  (string) The raw serialized double-spend proof data.
  "txid" : "xx"                  (string) The txid of the transaction associated with this double-spend. May be null for "orphan" double-spend proofs.
}

Result (for verbosity = 2, true):
{                                (json object)
  "dspid" : "xx",                (string) Double-spend proof ID as a hex string.
  "txid" : "xx",                 (string) The txid of the transaction associated with this double-spend. May be null for "orphan" double-spend proofs.
  "outpoint" :                   (json object) The previous output (coin) that is being double-spent.
  {
    "txid" : "xx",               (string) The previous output txid.
    "vout" : n ,                 (numeric) The previous output index number.
  }
}

Result (additional keys if verbosity >= 1 and there is a non-orphan result):
  ...
  "descendants" :                (json array of string) Set of all descendants of the double-spend tx, including the double-spend tx.
  [
    "txid" :                     (string) Txid hex.
    , ...
  ]

Result (additional keys if searching by txid and recursive = true):
  ...
  "path" :                       (json array of string) Path from the query tx leading up to and including the double-spend tx.
  [
    "txid" :                     (string) Txid hex, ordered by by child->parent.
    , ...
  ]

Result (additional keys for verbosity = 3):
  ...
  "spenders" :                   (json array of object) The conflicting spends.
  [
    {                            (json object)
      "txversion" : n,           (numeric) Transaction version number.
      "sequence" : n,            (numeric) Script sequence number.
      "locktime" : n,            (numeric) Spending tx locktime.
      "hashprevoutputs" : "xx",  (string) Hash of the previous outputs.
      "hashsequence" : "xx",     (string) Hash of the sequence.
      "hashoutputs" : "xx",      (string) Hash of the outputs.
      "pushdata" :               (json object) Script signature push data.
      {
        "asm" : "xx",            (string) Script assembly representation.
        "hex" : "xx"             (string) Script hex.
      }
    }, ...
  ]

Examples:
> bitcoin-cli getdsproof d3aac244e46f4bc5e2140a07496a179624b42d12600bfeafc358154ec89a720c false
> bitcoin-cli getdsproof fb5ae5344cb6995e529201fe24247ac38452f4e5ab5669b649e935853a7a180a
> bitcoin-cli getdsproof fb5ae5344cb6995e529201fe24247ac38452f4e5ab5669b649e935853a7a180a true true
> bitcoin-cli getdsproof fb5ae5344cb6995e529201fe24247ac38452f4e5ab5669b649e935853a7a180a 1 false
> bitcoin-cli getdsproof '{"txid": "e66c1848fd3268a7d1cfac833f9164057805cc9b22ea5521d36dc4cf63f5fe83", "vout": 0}' true
> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getdsproof", "params": ["fb5ae5344cb6995e529201fe24247ac38452f4e5ab5669b649e935853a7a180a", true, false] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/
> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getdsproof", "params": [{"txid": "e66c1848fd3268a7d1cfac833f9164057805cc9b22ea5521d36dc4cf63f5fe83", "vout": 0}, true] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/

Test Plan

  • Unit tests were added for some of the code changes on the C++ side.
  • Functional tests were added on the python side to test the RPC calls return the data we expect in the layout we expect.
  • ninja all check check-functional

Merge Instructions: Please SQUASH!

Edited by Calin Culianu

Merge request reports