decred.org/dcrdex@v1.0.5/spec/comm.mediawiki (about)

     1  =Communication Protocols=
     2  
     3  __TOC__
     4  
     5  ==WebSockets==
     6  
     7  Trustless negotiation of trades requires considerable messaging.
     8  Transaction details must be reported and relayed at appropriate times, sometimes
     9  with substantial delays between subsequent actions.
    10  Match notification via HTTP polling or other request interval-based methods are
    11  thus not suitable for the DEX system.
    12  Persistent, full-duplex communication is critical to minimizing communication
    13  latencies and wasted bandwidth.
    14  WebSockets ([https://tools.ietf.org/html/rfc6455 [3]]) are chosen as the
    15  default and preferred communications protocol for
    16  the DEX exchange API.
    17  In addition to fulfilling the aforementioned needs, Websockets are now a
    18  well-established technology with client software available for integration in
    19  virtually all popular programming languages.
    20  
    21  WebSocket messages are secured by encryption on Transport Layer
    22  Security (TLS) [https://tools.ietf.org/html/rfc8446 [4]] connections.
    23  
    24  ==Encoding==
    25  
    26  ===Timestamps===
    27  
    28  In all client-server messages that include a timestamp or duration field, the
    29  units of time are milliseconds unless otherwise specified. Location-independent
    30  timestamps are encoded as milliseconds since the UNIX epoch (Jan 01 00:00:00
    31  1970 UTC).
    32  
    33  If a timestamp must be converted to seconds, e.g. for encoding as a locktime in
    34  a swap contract, the timestamp should be rounded down.
    35  
    36  ===Rate Encoding===
    37  
    38  Because the rate assigned to a limit order is a quotient, the value is naturally
    39  expressed as a floating point number.
    40  To avoid floating-point error, rates in API messages are encoded using a
    41  custom unit, '''atoms quote asset per unit base asset'''.
    42  This is called the '''message-rate format'''.
    43  This can alternatively be viewed as conventional rate multiplied by
    44  10<sup>8</sup> and floored to the nearest integer.
    45  
    46  As an example of message-rate encoding, if someone wanted to purchase asset Z
    47  using asset Y on the Z/Y market, and the user wanted to pay 0.001 Y for each 1
    48  Z, the message-rate encoding would be
    49  
    50  '''''r<sub>msg</sub> = 1 x 10<sup>8</sup> x 0.001 = 100000'''''
    51  
    52  with unit ''atoms Y / unit Z''.
    53  
    54  ===Coin ID===
    55  
    56  In order to demonstrate control of unspent value on the blockchain, a user must
    57  provide its location. For Bitcoin-based blockchains, value is located by
    58  pointing to an unspent transaction output (UTXO), identified by its transaction
    59  ID and output index (vout). For account based assets, the coin id is different
    60  in different situations. Pre-swap it is simply an account address. While swapping,
    61  the value is transferred to a swap contract's address and can be found there in
    62  a map keyed by the swap's secret hash.
    63  
    64  In an effort to stay blockchain-protocol agnostic, the DEX accepts
    65  and recognizes the locating information as a single byte-array called the
    66  '''''coin ID''''', with the term '''''coin''''' being defined here as some
    67  amount of spendable value that is verifiable on the blockchain.
    68  It is up to backend and wallet developers to decide on how to properly encode the
    69  identifier as a coin ID. As an example, Bitcoin implements
    70  encoding as 36 bytes with the transaction hash being the first 32-bytes, and the
    71  big-endian encoded output index as the last 4 bytes.
    72  
    73  ==Message Protocol==
    74  
    75  DEX messaging is JSON-formatted [https://tools.ietf.org/html/rfc8259 &#91;5&#93;].
    76  All messages, regardless of originating party, use a common top-level
    77  structure called a '''Message'''.
    78  
    79  '''JSON Message object'''
    80  
    81  {|
    82  ! field    !! type !! description
    83  |-
    84  | type    || int || message type
    85  |-
    86  | payload || any || the data being transmitted
    87  |-
    88  | route   || string || the route identifier. requests and notifications only
    89  |-
    90  | id      || int > 0 || the request ID. requests and responses only
    91  |}
    92  
    93  There are three anticipated message types.
    94  
    95  '''Message types'''
    96  
    97  {|
    98  | type         || id || description
    99  |-
   100  | request      || 1 || a request is typically an uninitiated message that seeks a response
   101  |-
   102  | response     || 2 || a response to a request
   103  |-
   104  | notification || 3 || usually part of a data feed. requires no response
   105  |}
   106  
   107  '''Example request'''
   108  
   109  The payload for a request can be of any type.
   110  
   111  <pre>
   112  {
   113  	"type": 1,
   114  	"id": 123,
   115  	"route" "sendnum",
   116  	"payload": 5
   117  }
   118  </pre>
   119  
   120  '''Response payload'''
   121  
   122  The payload for a response has a structure that enables quick error checking.
   123  
   124  {|
   125  ! field    !! type !! description
   126  |-
   127  | result || any || the result. field is missing or null if an error was encountered
   128  |-
   129  | error   || string or null || the error. field is null or missing if no error was encountered
   130  |}
   131  
   132  '''Example response'''
   133  
   134  <pre>
   135  {
   136  	"type": 2,
   137  	"id": 123,
   138  	"payload": { "result": true }
   139  }
   140  </pre>
   141  
   142  '''Example notification'''
   143  
   144  <pre>
   145  {
   146  	"type": 3,
   147  	"route": "notifynums"
   148  	"payload": [1, 5, 3, 9]
   149  }
   150  </pre>
   151  
   152  ==Session Authentication==
   153  
   154  Many DEX messages must be sent on an authenticated connection. Once a WebSocket
   155  connection is established, the client will supply their account ID and signature.
   156  
   157  '''Request route:''' <code>connect</code>, '''originator: ''' client
   158  
   159  <code>payload</code>
   160  {|
   161  ! field      !! type   !! description
   162  |-
   163  | accountid || string || account ID
   164  |-
   165  | apiver    || int    || requested API version
   166  |-
   167  | timestamp || int    || UNIX timestamp (milliseconds)
   168  |-
   169  | sig       || string || hex-encoded signature of serialized connection data. serialization described below
   170  |}
   171  
   172  '''Connect serialization'''
   173  
   174  {|
   175  ! field   !! size (bytes) !! description
   176  |-
   177  | account ID || 32 || client [[accounts.mediawiki/#Step_1_Registration|account ID]]
   178  |-
   179  | API version || 2 || requested API version
   180  |-
   181  | timestamp || 8  || the client's UNIX timestamp (milliseconds)
   182  |}
   183  
   184  '''Connect response'''
   185  
   186  If a client unexpectedly disconnects with active orders, the orders may match in
   187  the client's absence. A list of any pending matches is included in the response.
   188  If the client has a broken rule, they will not be able to trade for the duration
   189  of their penalization.
   190  
   191  <code>result</code>
   192  {|
   193  ! field   !! type   !! description
   194  |-
   195  | activematches || <nowiki>[object]</nowiki> || list of active [[orders.mediawiki/#Match_negotiation|Match objects]]
   196  |-
   197  | activeorderstatuses || <nowiki>[object]</nowiki> || list of active <code>Order Status Object</code>
   198  |-
   199  | score || int || The user's score. The math behind this is currently being adjusted
   200  |-
   201  | tier || int || Bond tier. One or more indicates the account can trade. Legacy fee being paid gives a perpetual +1 to tier. Not set by legacy servers.
   202  |-
   203  | activeBonds || <nowiki>[object]</nowiki> || list of active <code>Bond Object</code>
   204  |-
   205  | legacyFeePaid || bool || Whether the legacy fee was paid. This currently has the internal value of one bond tier. Not set by legacy servers.
   206  |-
   207  | suspended || bool || DEPRECATED. For legacy servers true if suspended. Implies tier < 1, and means that the user cannot trade until posting more bond.
   208  |-
   209  | sig || string || hex-encoded server's signature of the serialized connection data
   210  |}
   211  
   212  '''Order Status Object'''
   213  
   214  {|
   215  ! field !! type !! description
   216  |-
   217  | ID || bytes || a unique order id
   218  |-
   219  | Status || int || the order status. See [[https://github.com/decred/dcrdex/blob/master/dex/order/status.go|status.go]] for statuses.
   220  |}
   221  
   222  '''Bond Object'''
   223  
   224  {|
   225  ! field !! type !! description
   226  |-
   227  | version || int || Bond version.
   228  |-
   229  | amount || int || Amount held in the bond in the lowest communicatable denomination of that coin. i.e. atoms for dcr, gwei for eth.
   230  |-
   231  | expiry || int || When the bond expires, NOT the bond locktime.
   232  |-
   233  | coinID || bytes || Coin ID that created the bond.
   234  |-
   235  | assetID || int || SLIP-0044 registered coin type of the bond asset.
   236  |}
   237  
   238  ==HTTP==
   239  
   240  An API using HTTP for message transport may be provided for basic account
   241  management and server status queries, however WebSocket connections are to be
   242  the sole means for
   243  [[orders.mediawiki/#Client_Order_Management|placing, monitoring, and executing orders]].
   244  The primary reason for limiting the scope of the HTTP API is to eliminate client
   245  polling for rapidly changing resources, such as order status API endpoints.