-
Notifications
You must be signed in to change notification settings - Fork 113
feat(swap): cancel maker order for offline coins #2357
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
b704ba0 to
98f53cc
Compare
onur-ozkan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 nits, LGTM otherwise
|
@borngraced We need to also broadcast cancellation message when electrum is down and broadcast order created/updated message when the electrum is back again but the fix here #2232 will make this process complicated. So I'm proposing a simpler and probably safer solution. The proposed solution differs from what @cipig suggested in #2281 (comment). I think it makes more sense to just cancel the orders when electrums are down and the maker can place them again themselves, if electrums are down similar to what happened in a recent swap, it's not safe for the order to go back online automatically leading to a swap with an unstable electrum. |
mariocynicys
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
| /// Checks if there are no live server connections available. | ||
| pub fn is_completely_offline(&self) -> bool { | ||
| for server in self.read_maintained_connections().iter() { | ||
| if self.get_connection(server.1).is_some() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will always return Some. the maintained_connections set is always a subset of all_connection.
u wanna get such a connection and check connection.is_connected() (here)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@smk762 could u explain what was the test scenario in here: #2357 (comment)
i might be missing something here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ahaaa, i didn't formulate this correctly in my head. thought this will always return false (so never offline).
but if read_maintained_connections() returns an empty list, then this will return true (all electrums offline). and in fact, checking that read_maintained_connections() is not empty is enough to know that we are connected, i.e. u don't have to check connection.is_connected(), as any maintained connection must be connected (when it disconnects it gets removed from the maintained connections set).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@smk762 could u explain what was the test scenario in here: #2357 (comment)
i might be missing something here
- Launch kdf,
- activate coins as usual.
- Create a setprice order as maker with an unattractive price so it stays on book.
- Check my_orders and confirm presence of the order.
- Add node/electrum url to pihole blocklist (temporarily) to mimic a lost connection. Turning off wifi for a bit would likely also work if not using pihole.
- Re-check my_orders, and confirm order was auto-cancelled.
- Repeat steps 1-5 for other coin types.
|
|
||
| /// Checks if there are no live server connections available. | ||
| pub fn is_completely_offline(&self) -> bool { | ||
| for server in self.read_maintained_connections().iter() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
for (_id, server_address) in maintained_connections { ... }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or:
for server_address in maintained_connections.values() { ... }
| async fn save_order_in_history(&self, order: &Order) -> MyOrdersResult<()> { | ||
| let path = my_order_history_file_path(&self.ctx, &order.uuid()); | ||
| write_json(order, &path, USE_TMP_FILE).await?; | ||
| write_json(&order, &path, USE_TMP_FILE).await?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redundant ref on order.
| MmCoinEnum::SiaCoin(c) => c.is_offline().await, | ||
| #[cfg(not(target_arch = "wasm32"))] | ||
| MmCoinEnum::LightningCoin(c) => c.platform_coin().as_ref().rpc_client.is_offline(), | ||
| MmCoinEnum::Test(_) => false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be annotated/cfg-ed for tests only. this breaks cargo check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done thanks.
| base_orderbook_ticker: None, | ||
| rel_orderbook_ticker: None, | ||
| p2p_privkey: None, | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
an extra line break;
also present in the rest of the file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks done.
| let mut current_dir = std::env::current_dir().unwrap(); | ||
| current_dir.pop(); | ||
| current_dir.pop(); | ||
| current_dir |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could u write in comments where such current_dir() is.
like:
// this should be: DB_ROOT/x/y/zcash_db/etc..
let mut current_dir = std::env::current_dir().unwrap();
// this is: DB_ROOT/x/y/zcash_db
current_dir.pop();
...also doesn't this depend on where from these tests are ran?
like, running the tests from the root of the komodo-defi-framework will result in a different current dir than when running from komodo-defi-framework/mm2src/mm2_main or mm2_tests? which would break the .join below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like a failed merge conflict.
reverted
mm2src/mm2_main/src/lp_ordermatch.rs
Outdated
| if order.available_amount() >= order.min_base_vol || order.has_ongoing_matches() { | ||
| if order.has_ongoing_matches() { | ||
| continue; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
has_ongoing_matches is OR-ed in the first if clause and then checked alone in the second.
we could move it out before the available_amount() check.
| ordermatch_ctx: &OrdermatchContext, | ||
| order: &MakerOrder, | ||
| ) -> bool { | ||
| if let Ok(Some(coin)) = lp_coinfind(ctx, &order.base).await { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think we should also cancel the order if it's not found (tho we also handle it else where i presume). and also cancel it if lp_coinfind errors (just for code simplicity, since we know it shouldn't really error).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmmm. I believe lp_ordermatch loop will wait till a coin is active before matching etc.
and also cancel it if lp_coinfind errors (just for code simplicity, since we know it shouldn't really error).
And I do not think we want to do this since coin not found seems very different from when it is offline.
|
if somebody is using a couple of many unreliable electrums they might lose coin connection for a couple of seconds every now and then. same for when they themselves have unreliable connections. i would be for just stopping order rebroadcasting and rejecting any taker requests till the coin is back online. removing the orders completely will be some pain in the butt for a maker that went offline for a split second. |
On the taker side, it is a pain in the butt for a user to match with an order which fails at the negotiation stage. From a guilt/punishment perspective:
Based on this, IMO auto-cancel on connection loss is justified, though a brief (< 2 sec) window to recheck could be included as a compromise to cover smaller things causing an interruption |
Totally agree to this. Takers order cancelling is no big deal at all as they can place it again straight away and is common even in AMM dexes. For makers, they don't just place orders, they use scripts/tools/bots so auto cancellation is also fine but they should be notified (they probably check order statuses automatically by the script instead) and they will place the orders again later when electrums are back online. |
I can add retry with sleep which should solve this. cc @shamardy |
|
We've been merging dev into this one for a while, and with the current conflict requiring resolution in lp_ordermatch.rs, another one is on the horizon. Is it still on track to be in 2.6.0? |
Yes, still on track, will give it a look and fix anything myself when I start the finalization of 2.6.0-beta. For now, there will be 2.5.1-beta first for the private key export. |
fix: #2281
handle maker order matching by checking coin connection status and cancel orders it all coin servers are down.