multi: connect response includes active orders#677
Conversation
df865a6 to
bf301eb
Compare
d6fd5f6 to
7613348
Compare
|
Converting this to draft to allow #687 go in first, as the new order_status route will find good uses here. |
| // Order 1: | ||
| // - Standing order, preimage not revealed, "missed" revoke_order note. | ||
| // - Expect order status to stay at Epoch status before going AWOL and to become | ||
| // Revoked after re-connecting the DEX. Locked coins should be returned. | ||
| // Order 2: | ||
| // - Non-standing order, preimage revealed, "missed" nomatch or match request (if | ||
| // matched). | ||
| // - Expect order status to stay at Epoch status before going AWOL and to become | ||
| // Executed after re-connecting the DEX, even if the order was matched and the | ||
| // matches got revoked due to client inaction. | ||
| // Order 3: | ||
| // - Standing order, partially matched, booked, revoked due to inaction on a | ||
| // match. | ||
| // - Expect order status to be Booked before going AWOL and to become Revoked | ||
| // after re-connecting the DEX. Locked coins should be returned. |
There was a problem hiding this comment.
These simulated and tested scenarios are 3 of the 4 scenarios documented in the table in #648 (comment) where coins may remain needlessly locked.
|
The last 2 commits are to enable me test with the order_status feature (cherry-picked the commit from #687). Will likely get edited a little bit more and force-pushed before this will be ready for review. I expect #687 will go in and I'll rebase this branch over the updated master before this becomes ready for review. |
5bce26b to
a729612
Compare
|
I'm satisfied with the workings of this branch as is. I was able to simulate some of the problematic conditions described in #648 (comment) using the webserver on master branch and get decent but incomplete resolution without the order_status route and complete resolution with the order_status route. Details below: Master branch2 clients, each with 2 orders stuck at an incorrect status and had funds locked.
Testing resolution with 87b781c (connect response includes active orders + order.PreimageRevealed)
Reconcilation logsTesting resolution with a729612 (connect response includes active orders - order.PreimageRevealed + order_status)
Reconcilation logs |
|
I'm gonna leave this as is for now until #687 goes in, then I'll clean it up and mark ready for review. |
|
Excellent analysis and summary of resolutions in that table. Certainly seems like the proper resolution is w/o the PreimageRevealed flag (although the v1 OrderProof "soft upgrade" was a clever approach) - order_status allows no db scheme changes, and correct status updates. I'm pretty happy happy with PR #687 , and looking at this a bit it looks like querying for status of cancel orders may not be needed. Thoughts about that? We do still need to deal with cancel orders in epoch status, even if indirectly (checking the status of the targeted order instead). |
|
Iirc, the only reason a cancel order will not get matched to the target order is if the cancel order's preimage was not sent or if the target order gets completely matched before the cancel order is processed. If that's correct, we can infer the final status of the cancel order without querying for it:
Make sense? |
|
Client can also disappear after providing the cancel order's preimage, but before getting a match/nomatch back. A very brief window, but has happened several times. But even in this case it sounds like we can make the same inferences. |
|
Right. We won't need to rely on the match/nomatch to determine the status of the cancel order. We just need to know the current status of the target order, if the target order is canceled, we know we missed a match request on the cancel order. If the target order is executed, we missed the preimage request or the nomatch request for the cancel order. Reading that again, looks like we can't completely infer. If the target order is executed, it could be that the cancel order's preimage was not received and the target order went on to match completely; or it was received but the target order got executed before the cancel order was processed. |
|
We can safely retire stale cancel orders anyway, but we would need the order_status route to account for cancel orders if we want to know the final status of the cancel order. Basically, we can retire the cancel order if the target order
The second case allows the client to submit another cancel order if they wish. The second case also means the cancel order was revoked. |
|
I want to say that we don't care what the cancel order status is as long as we know what happened with the trade, but I have a feeling that's going to haunt us. That said, I'm ok with moving forward with #687 without the ability to query cancel order statuses directly. We can modify that behavior as needed. |
a729612 to
b5678de
Compare
|
Marking this as ready for review. Feature complete now, just want to push another commit that refactors the db methods and types used in preparing the active orders for the connect response and the order_status response. |
There was a problem hiding this comment.
Simnet tests stopped twice in the same place:
--- FAIL: TestOrderStatusReconciliation (283.01s)
trade_simnet_test.go:641: status not updated for client 2 order b9617f72b6cf122d796c9e01d509ccd750a86877629dd618f4d87266ff9abd88, expected revoked, got epoch
5de3c35 to
dc35ddf
Compare
|
@JoeGruffins simnet issue should be fixed now. Noticed it a while ago and just force-pushed 😬 the fix. Didn't think anyone had eyes on this yet. |
buck54321
left a comment
There was a problem hiding this comment.
Just a cursory look with some questions and suggestions.
| oid := trade.ID() | ||
| previousStatus := trade.metaData.Status | ||
| newStatus := order.OrderStatus(msgOrder.Status) | ||
| trade.Trade().SetFill(msgOrder.Fill) |
There was a problem hiding this comment.
We've been careful other places to set fill based on our known matches, and I think that's the right approach. I wouldn't want to blindly accept the server's word on anything.
There was a problem hiding this comment.
Well, the server is also the entity that provides the match info we need to set the fill client-side currently. As long as we have the server signing these messages, shouldn't we be safe? We're also relying on / blindly accepting the order status from the server, if the server wants to play games with the client, the server can do that with the status returned alone, i.e. if we decide to not return the fill.
Although I do have a concern with the client potentially not having details for some matches relating to the order that would have made this fill amount update necessary. If the client has all the matches for the order (even in wrong statuses, which can be corrected with the coming match_status work), the client can calculate and set the fill amount appropriately without requiring this info from the server.
An example to illustrate my above concern is an Epoch limit order getting partially matched while the client is away, client misses the match request, the match gets revoked while client is away say due to maker (the other user) inaction, client's order gets booked, and on reconnect, we're setting the fill to 30% but without any match info to back it up.
There was a problem hiding this comment.
It's more just about having a single definition for the fill value. If the definition is "the sum value of all known matches", then that's what it should be. It shouldn't be "Either the sum of all known matches, or whatever the server told us, depending on what happened last".
There was a problem hiding this comment.
I see the fill value as the amount we know to be filled; and we typically gather this value from match requests sent by the server. If there are other ways to determine the value, I have no objection to it. Unless, like you say, if it is the sum value of all known matches, then we only set fill based on known matches. I think I'm okay either direction. Any preference?
There was a problem hiding this comment.
Simpler is better. 1 fewer field and 1 fewer definition to track is my preference. Should also avoid accepting the server as a source of truth. It wouldn't be terrible to check the server's reported fill value against our own just for verification and logging purposes, but it's hard to justify the extra field just for logging. I really think we should just remove the field from msgjson.OrderStatus until we find a compelling reason to include it.
|
A couple of races: |
- Log error and issue notification for active orders reported by DEX that are unknown to the client. - Update order statuses where server-reported statuses are different from statuses recorded by client. - Set statuses to Executed, Canceled or Revoked for orders considered active by the client but not returned by the DEX in the connect response. TODO: implement an `order_status` route to accurately determine current statuses for such orders. Also, set OrderProof.PreimageRevealed when client responds to preimage requests.
Also modify trade simnet test cases to run distinctly, wtih new clients created for each test case, to prevent spillages across test cases.
434ebb0 to
c7c9841
Compare
c7c9841 to
7342b4f
Compare
I'm getting this again, and I know why. I reduced the wait-before-reconnect time to just |
|
Still the failure for simnet test. |
|
@JoeGruffins, I think it might be a timing issue for your tests. Can you check if your dcrdex logs show the order getting revoked after the tests fail? If so, try increasing the wait-before-reconnect timeout here and let's see if that gets the tests passing for you. I'm cutting it a little close there with 2*bTimeout but I expect that should be enough time for the server to detect and revoke orders for at-fault matches. Also a good idea to restart the dcrdex harness between tests to prevent previous orders on the book messing up the test. Btw, I've recently only ran the |
chappjc
left a comment
There was a problem hiding this comment.
My review items are addressed.
But the core's harness tests still fail for me:
trade_simnet_test.go:650: status not updated for client 2 order 6109169027aa12cbebf71c815727613b4649639407a94cca70196d5f04b081ff, expected revoked, got epoch
...
--- FAIL: TestOrderStatusReconciliation (162.28s)
@JoeGruffins and I both consistently have trouble with the tests, but we'll have to continue investigating on the status-integ branch when this is merged. To merge status-integ with master, we will have another PR for that, on which we can test again.
|
Going to merge since code looks good and |






server/auth: return list of active orders with
connectresponse (will follow up with spec update)client/core:
unknown to the client.
recorded by client.
the client but not returned by the DEX in the connect response.
response.
Resolves #597.