From d24bbc3963602066621245d7e301f644e801fb4c Mon Sep 17 00:00:00 2001 From: buck54321 Date: Fri, 3 Jul 2020 11:47:23 -0500 Subject: [PATCH 1/4] maxfeerate, revoke_order, preimage response ack, feedless orderbook --- dex/msgjson/types.go | 2 +- spec/README.mediawiki | 4 +- spec/comm.mediawiki | 15 +++++- spec/fundamentals.mediawiki | 16 +++---- spec/orders.mediawiki | 91 ++++++++++++++++++++++++++++--------- 5 files changed, 96 insertions(+), 32 deletions(-) diff --git a/dex/msgjson/types.go b/dex/msgjson/types.go index 5de731ecd1..d738f170e6 100644 --- a/dex/msgjson/types.go +++ b/dex/msgjson/types.go @@ -192,7 +192,7 @@ type Stampable interface { // requires an acknowledgement. It is typically a signature of some serialized // data associated with the request. type Acknowledgement struct { - MatchID Bytes `json:"matchid"` + MatchID Bytes `json:"matchid"` // TODO: Remove this field. Sig Bytes `json:"sig"` } diff --git a/spec/README.mediawiki b/spec/README.mediawiki index b8bb462715..a19475dcdf 100644 --- a/spec/README.mediawiki +++ b/spec/README.mediawiki @@ -65,6 +65,7 @@ for the DEX API. ** [[comm.mediawiki/#Coin_ID|Coin ID]] * [[comm.mediawiki/#Message_Protocol|Message Protocol]] * [[comm.mediawiki/#Session_Authentication|Session Authentication]] +* [[comm.mediawiki/#Acknowledgements|Acknowledgements]] * [[comm.mediawiki/#HTTP|HTTP]] '''[2] [[fundamentals.mediawiki|Distributed Exchange Design Fundamentals]]''' @@ -114,8 +115,9 @@ book and place orders. ** [[orders.mediawiki/#Cancel_Order|Cancel Order]] * [[orders.mediawiki/#Preimage_Reveal|Preimage Handling]] * [[orders.mediawiki/#Unmatched_Orders|Unmatched Orders]] +* [[orders.mediawiki/#Order_Revocation|Order Revocation]] +* [[orders.mediawiki/#Match_Negotiation|Match Negotiation]] * [[orders.mediawiki/#Match_Revocation|Match Revocation]] -* [[orders.mediawiki/#Match_negotiation|Match Negotiation]] * [[orders.mediawiki/#Trade_Suspension|Trade Suspension]] '''[6] [[api.mediawiki| Data API]]''' defines http and WebSocket APIs to browse diff --git a/spec/comm.mediawiki b/spec/comm.mediawiki index 6a008a22ae..3441005236 100644 --- a/spec/comm.mediawiki +++ b/spec/comm.mediawiki @@ -189,13 +189,26 @@ of their penalization. {| ! field !! type !! description |- -| matches || [object] || list of [[orders.mediawiki/#Match_negotiation|Match objects]] +| matches || [object] || list of [[orders.mediawiki/#Match_Negotiation|Match objects]] |- | penalty || object || a [[community.mediawiki/#Penalty_Object|Penalty Object]]. omitted if in good standing |- | sig || string || hex-encoded server's signature of the serialized connection data |} +==Acknowledgements== + +Often, the server only requires a simple signed acknowledgement for a request. +The specification will provide instructions for serialization of the request +data. The client will then sign the serialized data with their private key, and +send an acknowledgement of the following form. + +{| +! field !! type !! description +|- +| sig || string || hex-encoded signature of the notification data +|} + ==HTTP== An API using HTTP for message transport may be provided for basic account diff --git a/spec/fundamentals.mediawiki b/spec/fundamentals.mediawiki index 7d70e54fbd..93f9b71101 100644 --- a/spec/fundamentals.mediawiki +++ b/spec/fundamentals.mediawiki @@ -112,21 +112,21 @@ respond with its current configuration. '''Asset object''' {| -! field !! type !! description +! field !! type !! description |- -| symbol || string || ticker symbol +| symbol || string || ticker symbol |- -| id || int || a unique per-asset ID +| id || int || a unique per-asset ID |- -| lotsize || int || lot size (atoms) +| lotsize || int || lot size (atoms) |- -| ratestep || int || the price rate increment (atoms) +| ratestep || int || the price rate increment (atoms) |- -| feerate || int || the fee rate for transactions (atoms/byte) +| maxfeerate || int || the max on-chain transaction fee rate that can be assigned to matches (atoms/byte) |- -| swapsize || int || the size of the initialization transaction (bytes) +| swapsize || int || the size of the initialization transaction (bytes) |- -| swapconf || int || minimum confirmations for swap transactions +| swapconf || int || minimum confirmations for swap transactions |} '''Market object''' diff --git a/spec/orders.mediawiki b/spec/orders.mediawiki index b45eae6d1e..b3a026fbfe 100644 --- a/spec/orders.mediawiki +++ b/spec/orders.mediawiki @@ -41,9 +41,11 @@ An order book can be viewed and tracked by subscribing to a market. {| ! field !! type !! description |- -| base || string || currency code for the market's base asset +| base || string || currency code for the market's base asset |- -| quote || string || currency code for the market's quote asset +| quote || string || currency code for the market's quote asset +|- +| nofeed || bool || If set to true, client will not receive order book updates |} The response will contain the complete market order book. @@ -582,29 +584,65 @@ the checksum generated from their local copy of the epoch queue. ! field !! size (bytes) !! description |- | pimg || string || hex-encoded preimage for the order's commitment +|- +| ackid || int || the message ID to be used for the server's preimage acknowledgement |} -==Match negotiation== +The server will send an [[comm.mediawiki/#Acknowledgements|acknowledgement]] of +their receipt of the preimage. The message ID of the acknowledgement will be set +to the specified ackid. The signature message is the byte-encoded +preimage. -Swap negotiation details will be relayed through the DEX with a series of -notifications. -Both the DEX and the clients will need to serialize and sign the notification -data. The originator includes their signature with the request, while the -recipient will return an '''acknowledgement''', or a list of -acknowledgements, as the result of their response payload. +==Order Revocation== + +In a couple of situations, the server will revoke a client's orders. + +1. A client in violation of the rules of community conduct may have their existing orders revoked. In this case, the revocation will count against the client's cancellation statistics. + +2. If a client does not reconnect after a trade suspension with persist = true, the client's orders will be revoked. This revocation does not count against the client's cancellation statistics. + +The server will send a revoke_order request to the client when an +order is revoked. -'''Acknowledgement''' +'''Request route:''' revoke_order, '''originator:''' DEX +payload {| -! field !! type !! description +! field !! type !! description +|- +| orderid || string || order ID |- -| matchid || string || the match ID +| reason || string || the reason the order is being revoked |- -| sig || string || hex-encoded signature of the notification data +| sig || string || DEX's hex-encoded signature of the serialized notification data. serialization described below |} +'''Order revocation serialization''' + +{| +! field !! size (bytes) !! description +|- +| orderid || 32 || the order ID +|- +| reason || varies || the UTF-8 encoded reason +|} + +The client will respond with an +[[comm.mediawiki/#Acknowledgements|acknowledgement]]. + +==Match Negotiation== + +Swap negotiation details will be relayed through the DEX with a series of +notifications. Both the DEX and the clients will need to serialize and sign the +notification data. The originator includes their signature with the request, +while the recipient will return an +[[comm.mediawiki/#Acknowledgements|acknowledgement]], or a list of +acknowledgements, as the result of their response payload. + If the client's order has one or more matches at the end of a match cycle, the -DEX will send a list of '''match objects'''. The maker is the first to act, so +DEX will send a list of '''match objects'''. + +The maker is the first to act, so after sending their acknowledgement, they should broadcast their initialization transaction and inform the server with an init notification (described after). @@ -631,6 +669,10 @@ transaction and inform the server with an init notification |- | status || int || only provided in 'connect' response. For 'match' requests, status is 0 = 'MakerSwapCast'. See [[https://github.com/decred/dcrdex/blob/master/dex/order/match.go|match.go]] for codes. |- +| feeratebase || int || the fee rate assigned to the swap transaction broadcast on the base asset blockchain. units: atoms/byte +|- +| feeratequote || int || the fee rate assigned to the swap transaction broadcast on the quote asset blockchain. units: atoms/byte +|- | sig || string || DEX's hex-encoded signature of the serialized notification data. serialization described below |} @@ -652,15 +694,22 @@ transaction and inform the server with an init notification | address || varies || UTF-8 encoded receiving address for the match |} +The client will respond with a list of signed match acknowledgements. + '''The tserver value is used as the basis for the the locktimes.''' If it is necessary to convert the time to seconds, the value should be rounded down. -The client will respond with a list of signed match acknowledgements. +The match object includes fields specifying the required transaction fee rates +for both blockchains. These rates will be at or below the +maxfeerate specified in the +[[fundamentals.mediawiki/#Configuration_Data_Request|asset configuration]]. The +actual rates comes from the server asset backends, so the algorithm is +implementation-specific. -After a client broadcasts their initialization transaction, they are -expected to report the transaction details to the server for verification and -relay to the matching party. +After a client broadcasts their initialization transaction, they will report the +transaction details to the server for verification. The server will relay the +details to the counter-party. '''Request route:''' init, '''originator:''' client @@ -670,7 +719,7 @@ relay to the matching party. |- | orderid || string || the order ID |- -| matchid || string || the matchid, retrieved from the [[#Match_negotiation|match notification]] +| matchid || string || the matchid, retrieved from the [[#Match_Negotiation|match notification]] |- | coinid || string || hex-encoded coin ID |- @@ -833,7 +882,7 @@ client. ==Match Revocation== -A match can be revoked by the server if a client fails to act within the +A match can be revoked by the server if one party fails to act within the [[fundamentals.mediawiki/#Exchange_Variables|broadcast timeout]]. A match revocation will result in penalties for the violating party only. The revoked match quantity is not added back to the order book in any form. @@ -851,7 +900,7 @@ The revoked match quantity is not added back to the order book in any form. | sig || string || DEX's hex-encoded signature of serialized revocation. serialization described below |} -'''Revocation serialization''' +'''Match revocation serialization''' {| ! field !! size (bytes) !! description From 15baa3c79e3a41d940e86222a1ac74ff874ae1ed Mon Sep 17 00:00:00 2001 From: buck54321 Date: Tue, 14 Jul 2020 14:41:16 -0500 Subject: [PATCH 2/4] generalize acks language. link to match negotiation in maxfeerate desc. --- spec/comm.mediawiki | 8 ++++---- spec/fundamentals.mediawiki | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/comm.mediawiki b/spec/comm.mediawiki index 3441005236..2ad964de28 100644 --- a/spec/comm.mediawiki +++ b/spec/comm.mediawiki @@ -198,10 +198,10 @@ of their penalization. ==Acknowledgements== -Often, the server only requires a simple signed acknowledgement for a request. -The specification will provide instructions for serialization of the request -data. The client will then sign the serialized data with their private key, and -send an acknowledgement of the following form. +Often, message only requires a simple signed acknowledgement. The specification +will provide instructions for serialization of the message data. The recipient +will then sign the serialized data with their private key, and send an +acknowledgement of the following form. {| ! field !! type !! description diff --git a/spec/fundamentals.mediawiki b/spec/fundamentals.mediawiki index 93f9b71101..7a346e0842 100644 --- a/spec/fundamentals.mediawiki +++ b/spec/fundamentals.mediawiki @@ -122,7 +122,7 @@ respond with its current configuration. |- | ratestep || int || the price rate increment (atoms) |- -| maxfeerate || int || the max on-chain transaction fee rate that can be assigned to matches (atoms/byte) +| maxfeerate || int || the max on-chain transaction fee rate [[orders.mediawiki/#Match_Negotiation|that can be assigned to matches]] (atoms/byte) |- | swapsize || int || the size of the initialization transaction (bytes) |- From 55ce6f259414c10f2ba086be7afadab58a641ddb Mon Sep 17 00:00:00 2001 From: buck54321 Date: Wed, 29 Jul 2020 15:56:30 -0500 Subject: [PATCH 3/4] add unmatched orders header --- spec/orders.mediawiki | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/orders.mediawiki b/spec/orders.mediawiki index b3a026fbfe..08f6d12943 100644 --- a/spec/orders.mediawiki +++ b/spec/orders.mediawiki @@ -865,6 +865,8 @@ The client will respond with an acknowledgement. The taker will get the key from the maker's redemption and broadcast their own redemption transaction. +==Unmatched Orders== + It is also possible for an epoch order to go through the matching cycle without generating a match. This will be common for limit orders, but can also occur for market orders if there are no booked orders to match with. When the server fails From 8ed901f5b5529f7140fc0c79dd35fa5cb29d9b5c Mon Sep 17 00:00:00 2001 From: buck54321 Date: Wed, 19 Aug 2020 14:20:39 -0500 Subject: [PATCH 4/4] add dialogue-type message --- spec/comm.mediawiki | 59 ++++++++++++++++++++++++++++++++++++------- spec/orders.mediawiki | 16 +++++------- 2 files changed, 56 insertions(+), 19 deletions(-) diff --git a/spec/comm.mediawiki b/spec/comm.mediawiki index 2ad964de28..37f07f90d8 100644 --- a/spec/comm.mediawiki +++ b/spec/comm.mediawiki @@ -78,18 +78,20 @@ structure called a '''Message'''. {| ! field !! type !! description |- -| type || int || message type +| type || int || message type |- -| payload || any || the data being transmitted +| payload || any || the data being transmitted |- -| route || string || the route identifier. requests and notifications only +| route || string || the route identifier. requests and notifications only |- -| id || int > 0 || the request ID. requests and responses only +| id || int > 0 || the message ID. not set for notifications. +|- +| returnid || int > 0 || the return ID. dialogue-type messages only |} There are three anticipated message types. -'''Message types''' +===Message types=== {| | type || id || description @@ -99,9 +101,11 @@ There are three anticipated message types. | response || 2 || a response to a request |- | notification || 3 || usually part of a data feed. requires no response +|- +| dialogue || 4 || used for more complicated, multi-step data transactions |} -'''Example request''' +===Request=== The payload for a request can be of any type. @@ -114,7 +118,7 @@ The payload for a request can be of any type. } -'''Response payload''' +===Response Payload=== The payload for a response has a structure that enables quick error checking. @@ -126,7 +130,7 @@ The payload for a response has a structure that enables quick error checking. | error || string or null || the error. field is null or missing if no error was encountered |} -'''Example response''' +===Response===
 {
@@ -136,7 +140,7 @@ The payload for a response has a structure that enables quick error checking.
 }
 
-'''Example notification''' +===Notification===
 {
@@ -146,6 +150,43 @@ The payload for a response has a structure that enables quick error checking.
 }
 
+===Dialogue=== + +A dialogue type message is initiated the same as a request. The initiator +will set the ID, which they will then use to identify dialogue messages from the +other party. The primary difference between a dialogue and a request is that the +non-initiator must set a `returnid` in their first response. Any subsequent +dialogue messages from the initiator will use this `returnid` as the message ID. + +'''Dialogue initiation''' + +
+{
+	"type": 4,
+	"id": 100,
+	"route" "exchangeinfo",
+	"payload": {"info": "initiator_data_1"},
+}
+
+ +'''Dialogue initiation response''' + +
+{
+	"type": 4,
+	"id": 100,
+	"returnid": 200,
+	"route" "exchangeinfo",
+	"payload": {"info"; "recipient_data_1"},
+}
+
+ +The dialogue can then continue, with the initiator addressing messages to the +specified returnid, and the non-initiator addressing messages to +the original message ID. The returnid is only expected to be set in +the first non-initiator message. The initiator will continue to use that ID for +all subsequent messaging. + ==Session Authentication== Many DEX messages must be sent on an authenticated connection. Once a WebSocket diff --git a/spec/orders.mediawiki b/spec/orders.mediawiki index 08f6d12943..e387c42c61 100644 --- a/spec/orders.mediawiki +++ b/spec/orders.mediawiki @@ -554,19 +554,19 @@ This is by design and discourages certain types of spoofing. ==Preimage Reveal== -At the expiration of the epoch, the DEX sends out a preimage -request for each order in the epoch queue. The match cycle begins 5 seconds +At the expiration of the epoch, the DEX initiate a preimage +dialogue for each order in the epoch queue. The match cycle begins 5 seconds after the last preimage request is sent by the server, so clients must respond before then. A '''''commitment checksum''''' is included as part of the -preimage request. +preimage dialogue initiation. The checksum is the Blake-256 hash of the concatenated, lexicographically-sorted commitments for every order in the epoch. For clients subscribed to the order book for the entire duration of the epoch, the checksum can be validated against the checksum generated from their local copy of the epoch queue. -'''Request route:''' preimage, '''originator:''' DEX +'''Dialogue route:''' preimage, '''originator:''' DEX payload {| @@ -577,21 +577,17 @@ the checksum generated from their local copy of the epoch queue. | csum || string || the commitment checksum |} -'''Preimage response''' +'''Dialogue step 2: preimage reveal''', '''originator:''' client result {| ! field !! size (bytes) !! description |- | pimg || string || hex-encoded preimage for the order's commitment -|- -| ackid || int || the message ID to be used for the server's preimage acknowledgement |} The server will send an [[comm.mediawiki/#Acknowledgements|acknowledgement]] of -their receipt of the preimage. The message ID of the acknowledgement will be set -to the specified ackid. The signature message is the byte-encoded -preimage. +their receipt of the preimage. ==Order Revocation==