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

     1  =Distributed Exchange Design Fundamentals=
     2  
     3  <!-- TODO: Previously, contents was just __TOC__, but scrolling does not seem to work
     4  by default on github for section names with spaces. Fix scrolling with the default
     5  _TOC_ and revert. Here and in other files. -->
     6  __NOTOC__
     7  ==Contents==
     8  * [[#exchange-variables|Exchange Variables]]
     9  ** [[#global-variables|Global Variables]]
    10  ** [[#asset-variables|Asset Variables]]
    11  ** [[#market-variables|Market Variables]]
    12  ** [[#bond-asset-variables|Bond Asset Variables]]
    13  ** [[#configuration-data-request|Configuration Data Request]]
    14  * [[#bonds|Bonds]]
    15  * [[#transaction-fees|Transaction Fees]]
    16  * [[#epoch-based-order-matching|Epoch-based Order Matching]]
    17  ** [[#epoch-time|Epoch Time]]
    18  ** [[#pseudorandom-order-matching|Pseudorandom Order Matching]]
    19  * [[#identities-based-on-public-key-infrastructure-pki-key-pairs|Identification]]
    20  * [[#blockchain-interaction|Blockchain Interaction]]
    21  * [[#adding-new-assets|Adding New Assets]]
    22  * [[#api-version|API Version]]
    23  ** [[#v0|v0]]
    24  
    25  ----
    26  
    27  There are several notable aspects of the DEX design that were chosen to permit
    28  peer-to-peer trades with the mechanics of order execution existing entirely on
    29  the separate blockchains via atomic swaps.
    30  These are:
    31  * Asset-specific order quantity increments and transaction fee rates
    32  * Epoch-based pseudorandom order matching, with epoch duration configured per-market
    33  * Client identities based on public key infrastructure (PKI)
    34  * An open and rigidly-defined interface for integration of arbitrary assets
    35  
    36  This section describes each of these design aspects.
    37  
    38  ==Exchange Variables==
    39  
    40  There are a number of exchange-wide, market-specific, asset-specific, and user specific
    41  variables that must be known by the client. These settings should be requested
    42  by the user immediately after connecting via the
    43  [[#configuration-data-request|<code>config</code> request]].
    44  
    45  ===Global Variables===
    46  
    47  The '''api version''' (<code>apiver</code>) is the server's communications API
    48  version. Check before attempting to trade.
    49  
    50  The '''dex public key''' (<code>pubkey</code>) is the public side of a
    51  [[#identities-based-on-public-key-infrastructure-pki-key-pairs|key pair]]
    52  and uniquely identifies the dex. It can be used to verify messages from the dex.
    53  
    54  The cancel rate for a user is the ratio of their canceled order count to
    55  completed order count. This only applies to cancels made within two epochs of
    56  the order being booked. After orders have sat for one epoch, they can be canceled
    57  for free.  A user's cancellation rate must remain below the configured
    58  [[community.mediawiki/#rule-3-an-accounts-cancellation-rate-must-not-exceed-the-threshold|'''cancellation threshold''']]
    59  (<code>cancelmax</code>) to avoid penalty.
    60  
    61  The '''broadcast timeout''' (<code>btimeout</code>) is the amount of time a
    62  client has to broadcast a transaction. For the maker, the broadcast time is
    63  measured from the time of match notification. For the taker, timeout is measured
    64  from the time when the maker's swap receives its
    65  <code>swapconf</code><sup>th</sup> confirmation (see [[#asset-variables|Asset Variables]]).
    66  
    67  The '''bin sizes''' (<code>binSizes</code>) are the bin sizes for candlestick data sets. i.e.
    68  "24h", "1h", "5m". Use in conjuction with <!-- TODO: create and link report notes --> epoch report notes to monitor trade history.
    69  
    70  The config has three subsections detailed more below. They are '''asset variables'''
    71  (<code>assets</code>), '''market variables''' (<code>markets</code>), and
    72  '''bond asset variables''' (<code>bondAssets</code>).
    73  
    74  ===Asset Variables===
    75  
    76  The '''version''' (<code>version</code>) is the asset version. Check before trading. A higher
    77  version indicates updated swap configurations.
    78  
    79  Every asset is assigned a unique integer '''ID''' (<code>id</code>) that will be used to identify the
    80  asset in serialized structures. Whenever possible, the ID is the same as the
    81  BIP-0044 registered [https://github.com/satoshilabs/slips/blob/master/slip-0044.md coin type index]
    82  [[references.mediawiki|<nowiki>[6]</nowiki>]]. The '''symbol''' (<code>symbol</code>) is also found there.
    83  
    84  The '''swap confirmations''' (<code>swapconf</code>) is the number of confirmations required during
    85  settlement on the first swap transaction, before the second swap transaction is
    86  broadcast, as well as on the second swap transaction, before the first
    87  redemption is broadcast.
    88  
    89  The '''max fee rate''' (<code>maxfeerate</code>) is the greatest fee the server
    90  may expect the client to pay on initiation transactions. This can be used by
    91  the client to determine how much needs to be reserved to trade.
    92  
    93  The '''unit info''' (<code>unitinfo</code>) contains information on unit names
    94  and includes the following variables:
    95  
    96  * The '''atomic unit''' (<code>atomicUnit</code>) is the unit the asset package will use in communications. i.e. Sats for btc and gwei for eth.
    97  
    98  * The '''conventional denomination''' (<code>conventional</code>) is the most commonly used denomination '''unit''' (<code>unit</code>) and its '''conversion factor''' (<code>conversionFactor</code>). i.e. BTC at 1e8 Sats or ETH at 1e9 gwei.
    99  
   100  * The '''alternatives''' (<code>denominations</code>) are other possible '''unit''' and '''conversion factor''' combinations. i.e. µBTC at 1e2 Sats. They may not exist for some assets.
   101  
   102  ===Market Variables===
   103  
   104  The '''name''' (<code>name</code>) is the market's name, composed of the base
   105  and quote asset symbols, lower case, with a hyphen inbetween. i.e. dcr_btc.
   106  
   107  The '''base''' (<code>base</code>) and '''quote''' (<code>quote</code>) are the
   108  BIP-0044 registered [https://github.com/satoshilabs/slips/blob/master/slip-0044.md coin type index]
   109  [[references.mediawiki|<nowiki>[6]</nowiki>]] of the base and quote assets that
   110  make up the market.
   111  
   112  The '''lot size''' (<code>lotsize</code>) for a market serves as both
   113  the minimum order quantity and the order quantity increment for limit orders
   114  and market buy orders, which are quantified in the market's base asset.
   115  In particular, for ''lot size''  '''''l''''', the requested ''order quantity'',
   116  '''''Q''''', must satisfy
   117  
   118  <!--Q = n l, n \in \{1, 2, 3, ...\}-->
   119  [[File:images/lot-sizes.png]]
   120  
   121  A trade's rate ''r'' is in units of the quote asset, and must be specified in
   122  integer multiples of the '''rate step''' (<code>ratestep</code>) shown here as ''p''.
   123  
   124  <!--r = n p, n \in \{1, 2, 3, ...\}-->
   125  [[File:images/price-increment.png]]
   126  
   127  The '''epoch duration''' (<code>epochlen</code>) is the length of one [[#epoch-time|epoch]].
   128  
   129  
   130  If the client connects shortly after a
   131  [[orders.mediawiki/#trade-suspension|trade suspension]], it's possible that
   132  trading will not commence until a future epoch. This information can be found in the config response's '''market status'''
   133  (<code>status</code>) which inclues a few variables:
   134  
   135  * If the market has been or will be susupended, the '''start epoch''' (<code>start epoch</code>) will be populated for each market and contains which epoch index trading did or will begin.
   136  
   137  * A '''final epoch''' (<code>finalepoch</code>) may also be present if the dex is scheduled to go into trade suspension. If this variable is present, there may also be a '''persists''' (<code>persistbook</code>) boolean that is true when booked orders will not be purged after market suspension.
   138  
   139  The [[orders.mediawiki/#market-buy-orders|'''market buy buffer''']] (<code>buybuffer</code>)
   140  defines the minimum order size for a market buy order.
   141  
   142  ===Bond Asset Variables===
   143  
   144  The '''version''' (<code>version</code>) is the bond version. A higher version indicates updated bond construction.
   145  
   146  The '''id''' (<code>id</code>) is the bond asset's BIP-0044 registered [https://github.com/satoshilabs/slips/blob/master/slip-0044.md coin type index]
   147  [[references.mediawiki|<nowiki>[6]</nowiki>]]
   148  
   149  The '''confirmations''' (<code>confs</code>) are the confirmations needed in order for the bond to be
   150  considered valid.
   151  
   152  The '''amount''' (<code>amount</code>) is how much is required for one bond, and
   153  the amount posted must be divisible by this amount. The amount will be in the
   154  asset's [[#asset-variables|asset's]] <code>atomic unit</code>.
   155  
   156  ===Configuration Data Request===
   157  
   158  '''Request route:''' <code>config</code>, '''originator:''' client
   159  
   160  The <code>config</code> request <code>payload</code> can be null. The DEX will
   161  respond with its current configuration.
   162  
   163  <code>result</code>
   164  {|
   165  ! field          !! type  !! description
   166  |-
   167  | cancelmax      || float || the [[community.mediawiki/#rule-3-an-accounts-cancellation-rate-must-not-exceed-the-threshold|cancellation threshold]]
   168  |-
   169  | btimeout       || int   || the broadcast timeout
   170  |-
   171  | apiver         || int   || the server's [[#api-version|api version]]
   172  |-
   173  | pubkey         || bytes || the server's public ecdsa key
   174  |-
   175  | binSizes       || <nowiki>[string]</nowiki>  || bin sizes for candlestick data sets (i.e. <nowiki>["24h", "1h", "5m"]</nowiki>)
   176  |-
   177  | bondAssets     || <nowiki>map[string]object</nowiki> || map of coin ticker symbols to Bond Asset objects (definition below)
   178  |-
   179  | assets         || <nowiki>[object]</nowiki> || list of Asset objects (definition below)
   180  |-
   181  | markets        || <nowiki>[object]</nowiki> || list of Market objects (definition below)
   182  |}
   183  
   184  '''Asset object'''
   185  
   186  {|
   187  ! field      !! type !! description
   188  |-
   189  | version    || int   || the asset's version
   190  |-
   191  | symbol     || string || ticker symbol
   192  |-
   193  | id         || int || a unique per-asset ID
   194  |-
   195  | maxfeerate || int || the maximum fee rate for transactions (atoms/byte)
   196  |-
   197  | swapconf   || int || minimum confirmations for swap transactions
   198  |-
   199  | unitinfo   || object || a Unit Info object (definition below)
   200  |}
   201  
   202  '''Unit Info object'''
   203  
   204  {|
   205  ! field      !! type !! description
   206  |-
   207  | atomicUnit  || string || the title of the smallest communicatable unit of the asset. i.e. Sats
   208  |-
   209  | conventional  || object || the most common Conversion Factor object (definition below)
   210  |-
   211  | denominations  || <nowiki>[object]</nowiki> || list of other optional Conversion Factor objects. May be empty (definition below)
   212  |}
   213  
   214  '''Conversion Factor object'''
   215  
   216  {|
   217  ! field      !! type !! description
   218  |-
   219  | unit  || string || the title of the denomination. i.e. BTC
   220  |-
   221  | conversionFactor  || int || the number of atomic units in the denomination. i.e. 1e8
   222  |}
   223  
   224  '''Market object'''
   225  
   226  {|
   227  ! field       !! type   !! description
   228  |-
   229  | name        || string || market name
   230  |-
   231  | base        || int    || base asset ID
   232  |-
   233  | quote       || int    || quote asset ID
   234  |-
   235  | lotsize     || int    || lot size (atoms)
   236  |-
   237  | ratestep    || int    || the price rate increment (atoms)
   238  |-
   239  | epochlen    || int    || the [[#epoch-based-order-matching|epoch duration]] (milliseconds)
   240  |-
   241  | buybuffer   || float  || the [[orders.mediawiki/#market-buy-orders|market buy buffer]]
   242  |-
   243  | status      || object || a Market Status object (definition below)
   244  |}
   245  
   246  '''Market Status object'''
   247  
   248  {|
   249  ! field      !! type !! description
   250  |-
   251  | startepoch  || int    || the epoch number at which trading did or will commence. May be in the future e.g. [[orders.mediawiki/#trade-suspension|after maintenance]]
   252  |-
   253  | finalepoch  || int    || the epoch number at which trading will be suspended. Only present when a suspension is scheduled
   254  |-
   255  | persistbook || bool   || whether or not booked orders will be persisted through a scheduled suspension. Only present when a suspension is scheduled
   256  |}
   257  
   258  ==Bonds==
   259  
   260  The DEX collects no trading fees.
   261  Collecting fees from trades executed via atomic swaps (where the server
   262  is never in control of funds and settlement occurs directly on-chain) would
   263  add considerable complexity to the swap process and incentivize DEX operators to
   264  facilitate wash trading.
   265  Instead, time locked bonds are considered during registration. <!-- TODO: Create and link to bond specifics. -->
   266  Locked funds discourage certain spam attacks and enable punitive actions when
   267  [[community.mediawiki/#rules-of-community-conduct|conduct rules]] are violated.
   268  
   269  ==Transaction Fees==
   270  
   271  The clients will cover on-chain transaction fees at a minimum fee rate set by
   272  the DEX operator.
   273  Failure to provide the specified fee rate in a transaction will result in a
   274  conduct violation.
   275  
   276  As part of any submitted order, a client is required to demonstrate control of
   277  funds that will back the atomic swap, and ensure that the backing funds are
   278  sufficient to create the swap contract transactions transferring the full order
   279  quantity as well as covering the network's transaction fees at the specified
   280  rate.
   281  
   282  Total on-chain fees associated with an order will increase as the number of swap
   283  transactions required to settle the order increases. Maximum fees paid
   284  [[orders.mediawiki/#calculating-transaction-fees|vary linearly with order size]], but the actual
   285  fees realized can be significantly less than the maximum.
   286  See the [[atomic.mediawiki/#atomic-settlement|atomic settlement]] section for examples of simple
   287  and complex matches and how that affects the swap transaction sizes.
   288  
   289  Fee rates can vary greatly between assets.
   290  For many assets, low fees are possible without increasing the time until mined.
   291  Transaction fees tend to rise as an asset pushes the limits of on-chain scaling.
   292  For high-fee assets, the DEX operator must find a balance between lower fees,
   293  which are preferable from an accounting standpoint, and higher fees, which can
   294  decrease settlement time by increasing the speed at which transactions are
   295  mined.
   296  
   297  ==Epoch-based Order Matching==
   298  
   299  In order to devalue predatory behavior exhibited by certain high-frequency
   300  trading algorithms, received orders are not processed continuously, but rather
   301  after a shuffling step with all other orders received in a fixed duration period
   302  called an ''epoch''.
   303  The goal of this algorithm is to ensure that an individual client cannot obtain
   304  a deterministic latency advantage over other clients when executing trades.
   305  Limiting this possibility mitigates advantages gained from front-running,
   306  spoofing, and other manipulative trading practices.
   307  
   308  ===Epoch Time===
   309  
   310  For a given epoch duration '''''d > 0''''' in milliseconds, and current UNIX
   311  epoch timestamp '''''t''''' (in milliseconds since Jan 01 00:00:00 1970 UTC),
   312  the current order matching epoch index, '''''i''''', and epoch range are
   313  computed as
   314  
   315  <!--i = t / d, i d \leq t_i < d (i + 1)-->
   316  [[File:images/epoch-index.png]]
   317  
   318  where '''''/''''' is integer division. For example, at the time of writing,
   319  '''''t = 1562008475123''''' , which for '''''d = 8000''''' (8 seconds)
   320  corresponds to epoch number '''''i = 195251059''''' spanning
   321  '''''&#91;1562008472000, 1562008480000)'''''. This convention allows epoch start
   322  and end times for any epoch duration to be known without querying the server.
   323  
   324  A clock synchronization protocol such as NTP will be used to ensure server and
   325  client clocks are synchronized within acceptable tolerances.
   326  
   327  ===Pseudorandom Order Matching===
   328  
   329  When the epoch ends, a match cycle begins. The preimage for each order is
   330  collected and the orders are sorted lexicographically by their
   331  [[orders.mediawiki/#order-id|order IDs]].
   332  
   333  A random seed is derived from the Blake-256 hash of the concatenated
   334  [[orders.mediawiki/#order-commitment|order preimages]].
   335  
   336  <!--H_{seed} = \text{\footnotesize BLAKE256}(p_1 || p_2 || ... || p_N)-->
   337  [[File:images/seed-eq.png]]
   338  
   339  where '''''||''''' indicates concatenation and
   340  '''''p<sub>i</sub>''''' is the preimage of the '''''i<sup>th</sup>''''' order.
   341  
   342  The integer series produced by evaluating the hash
   343  as a series of 8-byte big-endian integers is used to seed a Mersenne Twister
   344  (mt19937) random number generator.
   345  
   346  Shuffling is then performed using the The Fisher-Yates algorithm on the
   347  '''''N''''' orders, where at each step '''''i : i < N''''', the order at index
   348  '''''i''''' is swapped with the order at index '''''j''''',
   349  
   350  <!--j = i + [r_i \bmod (N - i)]-->
   351  [[File:images/fisher_yates_j.png]]
   352  
   353  '''''r<sub>i</sub>''''' is the '''''i<sup>th</sup>''''' number in the seeded
   354  mt19937 series.
   355  
   356  Orders are processed one at a time. Each order is matched according to its type.
   357  
   358  1. If the order is a '''cancel order''', any corresponding standing limit order is removed from the list and the cancel order is considered filled. If a cancellation is processed before the order that it cancels, the cancellation will fail, and will need to be re-submitted. That is, cancel orders do not affect down-queue orders, only standing orders.
   359  
   360  2. If the order is a limit order with time in force ''standing'' that cannot match immediately (a '''maker'''), it is added to the standing orders. It is immediately able to match orders further down the queue.
   361  
   362  3. If the order is a '''taker''', it is matched against the best available standing order. Clients for both orders are notified and the settlement process begins. The orders are set aside for monitoring. If a limit order with time in force ''standing'' on either side of the match is only partially filled, it is added to the standing orders with the appropriate modifications and is immediately available for matching again.
   363  
   364  Any unmatched quantity on a limit order with time in force ''immediate'' is
   365  left unfilled.
   366  Market orders and immediate limit orders cannot match orders further down the
   367  queue.
   368  
   369  When a limit order from the queue matches a standing limit order on the book,
   370  the match is assigned the price rate of the maker's order (the standing order's
   371  price rate).
   372  
   373  The process continues with the next order in the list and iterates until all
   374  orders have been processed.
   375  
   376  The preimages and seed are published at the start of the matching process. In
   377  addition, a '''''checksum''''' defined as the Blake-256 hash of the
   378  concatenation of the lexicographically sorted commitments of all orders in the
   379  epoch queue, is sent to the client. Because the client already has the
   380  commitments from their order book subscription, the checksum allows the client
   381  to check that the orders underlying the preimages are indeed the same set
   382  received in their order notification feed, and that no received orders were
   383  omitted from either preimage collection or shuffling.
   384  
   385  For the special case of an epoch with no orders, the checksum will be null.
   386  
   387  ==Identities based on Public Key Infrastructure (PKI) Key Pairs==
   388  
   389  The server and the clients are identified and authenticated using [https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm ECDSA]
   390  [[references.mediawiki|<nowiki>[7]</nowiki>]] public keys,
   391  with matching private keys used to sign and authorize orders and other messages.
   392  Establishing client identity with public keys keeps the notion of client
   393  identity to a minimum, while providing a number of other security benefits
   394  throughout the order placement and execution processes.
   395  
   396  All data submitted to the exchange server from a client must be signed with the
   397  client's private key and authenticated by the server using the corresponding
   398  public key, so using client public keys directly for identity purposes is a
   399  natural simplification that obviates the need for client user names and
   400  passwords.
   401  
   402  Further, since Politeia, Decred's governance platform, also employs PKI, the
   403  same identities may be used on both services to facilitate time-stamping
   404  exchange data via Politeia. For example, given common identities between the DEX
   405  and Politeia, anchoring data related to DEX client and server conduct on the
   406  Decred blockchain may be useful for establishing a reputation system.
   407  
   408  ==Blockchain Interaction==
   409  
   410  '''Clients''' need wallets that support atomic swaps and the ability to
   411  broadcast transactions to each of the blockchain networks involved in
   412  [[atomic.mediawiki/#atomic-settlement|the swap]].
   413  
   414  '''DEX operators''' need access to trusted full nodes for each of the
   415  assets supported.
   416  While operation via a surrogate blockchain data service such as a block explorer
   417  is potentially feasible, it would entail significant security risks.
   418  Initial development will require that the server have a direct connection to
   419  full nodes of each asset's blockchain.
   420  
   421  ==Adding New Assets==
   422  
   423  Adding support for an asset is accomplished by writing a
   424  [https://golang.org/ Go] package with types that implement a particular set of
   425  interfaces, defined [https://github.com/decred/dcrdex/blob/master/server/asset/common.go here]
   426  and [https://github.com/decred/dcrdex/blob/master/server/asset/driver.go here].
   427  There are then two ways to import the asset backend into the server software.
   428  
   429  # The package is compiled with <code>-buildmode=plugin</code> and imported at runtime by specifying the plugin in the server configuration.
   430  # The backend is added to the dcrdex repository, and imported directly at compile time.
   431  
   432  With the exception of a small handful of assets which will be implemented during
   433  initial phases of DEX development, it is expected that development communities
   434  will release their own appropriately vetted plugins.
   435  
   436  ==API Version==
   437  
   438  Since DEX v0.2, the dex server has an Application Programming Interface version.
   439  Clients should check this version before attempting to communicate further with
   440  the server. An unknown or incompatible version means that communications will
   441  fail, possibly resulting in penalties or a ban.
   442  
   443  ===v0===
   444  
   445  The server's pre-versioning api version with an apiver value of 0.