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..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
@@ -189,13 +230,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, 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
+|-
+| 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..7a346e0842 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 [[orders.mediawiki/#Match_Negotiation|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..e387c42c61 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.
@@ -552,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
{|
@@ -575,7 +577,7 @@ 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
{|
@@ -584,27 +586,59 @@ the checksum generated from their local copy of the epoch queue.
| pimg || string || hex-encoded preimage for the order's commitment
|}
-==Match negotiation==
+The server will send an [[comm.mediawiki/#Acknowledgements|acknowledgement]] of
+their receipt of the 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.
-'''Acknowledgement'''
+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.
+
+'''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 +665,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 +690,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 +715,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
|-
@@ -816,6 +861,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
@@ -833,7 +880,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 +898,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