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 '''''[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.