Skip to content

spec: maxfeerate, revoke_order, preimage response ack, feedless orderbook#526

Closed
buck54321 wants to merge 4 commits into
decred:masterfrom
buck54321:specstuff
Closed

spec: maxfeerate, revoke_order, preimage response ack, feedless orderbook#526
buck54321 wants to merge 4 commits into
decred:masterfrom
buck54321:specstuff

Conversation

@buck54321
Copy link
Copy Markdown
Member

@buck54321 buck54321 commented Jul 3, 2020

  1. config response "feerate" field changed to "maxfeerate". Changes implemented in multi: match fee rates and smart fees #505. Resolves spec: messaging update for fee rate changes #521
  2. A new revoke_order message to be sent to clients when their orders are revoked.
  3. A response acknowledgement for the preimage request. Possible resolution of comms: handle response errors #456.
  4. A new "nofeed" field in the orderbook request, which disables subscription to the order book feed. Can be used in client/rpcserver: Add orderbook route. #496.

@chappjc
Copy link
Copy Markdown
Member

chappjc commented Jul 3, 2020

  1. resolving the comments at https://github.com/decred/dcrdex/pull/525/files#diff-5c4d3ee4527d6c50d1379b8edb5ef11eR2502-R2504 ("match revocations are sent to both parties")? Would that be used when the market is flushed (persist=false) also, or would the suspend message be considered adequate there?

@buck54321
Copy link
Copy Markdown
Member Author

buck54321 commented Jul 3, 2020

Yep, though persist = false is already handled in #525.

Comment on lines +129 to 131
| swapconf || int || minimum confirmations for swap transactions
|}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After this object definition, can we link to Match Negotiation in orders.mediawiki, perhaps also saying that the maxfeerate is applied to the swap contract transaction as described in that section, as "assigned to matches" is a little vague.

Comment thread spec/orders.mediawiki Outdated
Comment on lines +587 to +594
|-
| 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 <code>ackid</code>. The signature message is the byte-encoded
preimage.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that if the server wanted to exclude an order from the shuffle, they would just not ack, so it's not clear if this adds a lot unless we adapt it to communicate error conditions with the response handling.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unless we adapt it to communicate error conditions with the response handling

That is the purpose here.

Comment thread spec/comm.mediawiki Outdated
Comment thread spec/orders.mediawiki
Comment on lines 584 to 587
! 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
|}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand this is part of a solution to the need for a response to a response, but I'm not sure if/how it will work out allowing the client to specify the message id for an outgoing server message. Although I think only requests really need to use comms.NextID to ensure a unique ID while it does not matter for notifications and responses. Pretty sure this is not a problem with that?

An alternative would be do change the acknowledgement payload to contain an ackid also so that the containing message's ID would continue to be serial, monotonically increasing.

Also, part of the need for a response to a response was in the case of an error during response handling requiring the server to inform the client of the error in processing their response, so could we use this ackid concept for errors? Maybe new fields in the acknowledgement payload for success and general-purpose text details along with the signature?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about flipping the semantics a little bit, and instead of sending a response to a response, we can instead send request for a request? For instance, the DEX-originating preimage request triggers the client to submit a submit_preimage request that just references either the preimage request ID, or maybe even just the market and order ID. It would require some reworking on the server side, since we can't use a request callback to process the preimage data. Just a thought.

Copy link
Copy Markdown
Member

@chappjc chappjc Jul 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think either request to a request, or a response to a response could be made to work. I've been mulling over the protocol recently I was imagining a request or response with no id set to indicate that it's not a usual request/response and there's a reference id in the payload instead, and it should be treated as both a request (requires a response) and a response (there should be a registered response handler). Alt. the id could be set in the usual place, but a new msgjson.Dialog type that signals the dual role.

Although, defining a new request like submit_preimage would be perhaps cleaner if not as generalized to the myriad of cases where we need this kind of communication sequence such as the match ack response from the client needing its own response so the client knows when it's OK to init (https://github.com/decred/dcrdex/pull/565/files#r460186427).

I guess one of us just needs to try out some ideas and start hacking.

Copy link
Copy Markdown
Member Author

@buck54321 buck54321 Jul 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alt. the id could be set in the usual place, but a new msgjson.Dialog type that signals the dual role.

I like this variation. The payload can then contain something like a sub-route as a sequencing field.

Comment thread spec/orders.mediawiki
Comment on lines +630 to +627
The client will respond with an
[[comm.mediawiki/#Acknowledgements|acknowledgement]].
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also not sure if this ack serves a real purpose either. What would the server do with the client's ack? Much like with revoke_match, the server does nothing with the ack presently, just logging it.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You okay with removing both acknowledgements and making these notifications instead?

@chappjc chappjc added the spec label Jul 14, 2020
@buck54321 buck54321 marked this pull request as draft August 13, 2020 19:51
@buck54321
Copy link
Copy Markdown
Member Author

Going back to draft while I make some changes.

@buck54321
Copy link
Copy Markdown
Member Author

I've roughed out a dialogue-type message and used it for the preimage. Leaving in draft, but critique is welcome.

Comment thread spec/comm.mediawiki
"id": 100,
"returnid": 200,
"route" "exchangeinfo",
"payload": {"info"; "recipient_data_1"},
Copy link
Copy Markdown
Member

@chappjc chappjc Aug 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would all subsequent messages/responses not be using a ResponsePayload as the Message.Payload? This shows a free-form payload structure with no "response" or "error" keys. This could work if "error" is a possible key that the handler for this route would look for to detect an early dialog termination. More on this in my subsequent comments...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to leave it as general as possible, but maybe you're right that we should use ResponsePayload or similar because errors.

Comment thread spec/orders.mediawiki
Comment on lines +580 to 587
'''Dialogue step 2: preimage reveal''', '''originator:''' client

<code>result</code>
{|
! 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
|}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This step is headed with <code>result</code>, suggesting that this data (a PreimageResponse) would be encoded into the "result" of a ResponsePayload, which goes inside a Message.Payload, as it is presently. I got the impression the Message.Payload would be whatever, but a ResponsePayload would work too.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry. That should say payload.

Comment thread spec/comm.mediawiki
Comment on lines +186 to +188
the original message ID. The <code>returnid</code> is only expected to be set in
the first non-initiator message. The initiator will continue to use that ID for
all subsequent messaging.
Copy link
Copy Markdown
Member

@chappjc chappjc Aug 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For my comment below, s/non-initiator/participant/, but we could do that in the spec too if you like.

My understanding of these lines is reflected by slightly different language, but I think we are saying the same thing:

A "returnid" field is only present in the participant's dialog initialization response. In all subsequent messages, the initiator will use the value of that field for the "id" field in dialog messages to the participant, while the participant will continue to use the initiator's "id" from the initialization request.

Spelled out with some implementation hints, what I think we are describing is this:

  • The dialog initialization request from the initiator would have "id": x. Before sending the initialization request, the initiator registers some dialog-scoped data or a handler function for the dialog keyed by x.
  • The participant gets the request and uses "route" (and "type": 4) to find the associated global handler to start this dialog.
  • The dialog initialization response from the participant has "id": x and "returnid": y. Before sending this message, the participant registers some dialog-scoped data or a handler keyed by y for further messages for this dialog, storing the value of x with this data/handler for dialog y.
  • Initiator gets the initialization response with "id": x, finds the data/handler for they dialog keyed by x, and stores the value of y just provided in "returnid".
  • Now both parties have some dialog-scoped data or a handler in a map keyed by their own unique id that stores the other party's unique id. The dialog is established.
  • Subsequent messages from the initiator have "id": y so that the participant can find the dialog.
  • Subsequent messages from the participant have "id": x so that the initiator can find the dialog.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The relevance of the "route" field in all dialog messages depends on the implementation. Options alluded to above:

  • a request-response approach where the initial message from each party creates a new handler for the dialog, not needing the route except for the handling of the dialog initialization request by the participant's global request handler
  • an "all requests" approach where the global request handler for the specified route is always used, but this global handler attempts to locate dialog-scoped data from some map specific to this route.

I actually like the second option, but hacking on this might change my mind.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your implementation description is spot on, and the "all requests" approach is the one I was picturing, but like you said, let the hacking flesh it out. No need to rush this out of draft either. Might be time to just do it, and implement the solution for preimage errors (#597), and then come back to this.

Copy link
Copy Markdown
Member

@chappjc chappjc Aug 25, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May also be a good candidate for the match request, so that the client can get confirmation that their ack was recorded before starting their 'init' request. ref: #565 (comment) Perhaps I'm seeing a logic race where there isn't one, but it seems like an OK is needed back from the server before the maker does its 'init' request, otherwise the server could be not ready.

But there are a host of server-originating requests that may be best off as dialogs to allow the server to respond with an error to the client's response.

Comment thread spec/comm.mediawiki
Comment on lines +186 to +188
the original message ID. The <code>returnid</code> is only expected to be set in
the first non-initiator message. The initiator will continue to use that ID for
all subsequent messaging.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about termination of the dialog, there would presumably just be a known dialog sequence for this particular route, which could terminate early with an error or run to completion.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. The specification for the route will define any required sub-sequencing requirements, but really it'll probably just be that both sides remember what step they're at.

@chappjc
Copy link
Copy Markdown
Member

chappjc commented Feb 24, 2022

The whole spec is getting a review and update as part of phase 3, so I suggest we start fresh. I'm not sure how accurate this current change is anymore given how much has changed, but if it's basically right we can finish this one off. But would be nice to close up some of the older PR drafts.

@chappjc
Copy link
Copy Markdown
Member

chappjc commented Jun 9, 2022

See pinned issue #1641
Need a fresh start

@chappjc chappjc closed this Jun 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

spec: messaging update for fee rate changes

2 participants