-
Notifications
You must be signed in to change notification settings - Fork 114
feat(tpu-stats): send and store tpu swap status #2645
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
also add a couple of columns for new data in stats table. we will be using the same stats table as before with these extra optional columns. also the events list is sent over but not stored as json like with legacy swaps. will decide later what do to with them (if they are supposed to be stored)
this also wraps the structs found in SwapStatusData inside a box because they are very different in size (i.e. for perf purposes)
we don't do so in aborted states though. we might wanna change that
this is prepared for tests rather than real usage, but could ofc be amended later. for now it only exposes a couple of fields just to make sure the swap persisted in the db correctly
adb32e8 to
8149faa
Compare
e482531 to
f3d9247
Compare
| // NULL = unknown, 0 = not a bot, 1 = bot | ||
| "ALTER TABLE stats_swaps ADD COLUMN is_maker_bot INTEGER;", |
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 wonder if making it maker_type with backing it Rust enum would be any good. 🤔 Just for the extensibility.
So it would look something like this:
enum MakerType {
Unknown,
WebUser,
DesktopUser,
Bot,
.
.
.
}
and can be extended to anything without changing things on the DB side.
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 wonder if making it maker_type with backing it Rust enum would be any good.
like the idea. we can have a new issue about that to harvest such data (cc/ @shamardy)
we can ofc do a migration to change the table to the appropriate format later.
| common::async_blocking(move || { | ||
| if let Some(conn) = ctx.sqlite_conn_opt() { | ||
| crate::database::stats_swaps::add_v2swap_to_index(&conn, &swap) |
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.
Why not making add_v2swap_to_index and spawning the task inside of it? If it's a heavy blocking task, then it should do this in a self-contained way as the caller may not always remember to wrap it with a spawning task.
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.
crate::database::stats_swaps::add_v2swap_to_index is only used by one method which is lp_swap::add_v2swap_to_stats_db_index (the latter is a simple wrapper around the former)
same for crate::database::stats_swaps::add_swap_to_index and lp_swap::add_swap_to_db_index
so having the async_blocking at either level is the doable. i went for adding the async_blocking to the top level as the db-level functions take &Connection which isn't gonna play nice with the requirements of async_blocking (we can ofc pass the whole MmArc to the db-level functions but i think them taking a &Connection is more intuitive).
also other db methods follow the same sync interface, so that aligns with them (except our &AsyncConnection-based code)
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 other db functions should do the same but I don't want to block this PR with other tech debts. It's fine if you don't want to do it that way.
| common::async_blocking(move || { | ||
| if let Some(conn) = ctx.sqlite_conn_opt() { | ||
| crate::database::stats_swaps::add_swap_to_index(&conn, &swap) |
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.
Same here.
| self: Box<Self>, | ||
| state_machine: &mut Self::StateMachine, | ||
| ) -> <Self::StateMachine as StateMachineTrait>::Result { | ||
| // FIXME: Do we want to broadcast the swap status 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.
Why not?
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 covers other cases like (e.g.) a maker who didn't see the funding transaction for some reason and aborted the swap, or a taker that failed to send the funding transaction and aborted the swap. idk if we want statistics about failures like these.
though a swap finished via a refund is accounted for and sent for stats.
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.
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.
Swap stat is collected on seed nodes right?
As far as I can see we only store if the swap status is success or not, in the stat db.
So even if one party aborts the swap its status still will be updated by other party when it gets to the last state (and broadcasts the final state)
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.
Reasons for failure could be good intel for future works to mitigate.
Correct, seednodes do collect, in stats_swaps table column is_success.
https://dev.komodo-docs.pages.dev/en/docs/komodo-defi-framework/tutorials/query-the-mm2-database/#stats-swaps
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.
LGTM other than #2645 (comment), which is awaiting others responses.
| Ok(()) | ||
| } | ||
|
|
||
| async fn broadcast_my_v2swap_status(ctx: &MmArc, status: TPUSwapStatusForStats) -> Result<(), String> { |
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 this function not be called save_and_broadcast_my_v2swap_status?
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.
hmm save is done only for native, maybe no need to rename then
| if let Some(conn) = ctx.sqlite_conn_opt() { | ||
| crate::database::stats_swaps::add_swap_to_index(&conn, swap) | ||
| } | ||
| pub async fn add_v2swap_to_stats_db_index(ctx: &MmArc, swap: TPUSwapStatusForStats) -> Result<(), String> { |
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.
why do we have _index in add_v2swap_to_stats_db_index and add_v2swap_to_index fn names?
I think this mattered for the legacy swaps as there is indeed an index over json files with stat data.
For TPU we have only a db, no jsons, so could we name them, like: save_swap_v2_stat and add_swap_v2_stat_to_db?
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 was more or less following the names we have for legacy swaps. that being said, i think of index as tables/sqls.
db used to mean a sqldb to me, but it's used in a different way in our codebase. we treat json files as db (file/directory DB basically), see for example load_from_maker_stats_db.
that's why i find the _index distinction helpful in this case as to denote that such db storage is a table format rather than file dump. but i can remove it too if u find it way off.
|
@shamardy |
|
@shamardy |
|
@shamardy |
|
@shamardy |
|
@shamardy |
8 similar comments
|
@shamardy |
|
@shamardy |
|
@shamardy |
|
@shamardy |
|
@shamardy |
|
@shamardy |
|
@shamardy |
|
@shamardy |
|
@shamardy |
1 similar comment
|
@shamardy |
This PR adds support for broadcasting and persisting finished (either successfully or refundinly) swaps' status for v2 swaps.
Here there are no JSON files or so. We only store the status in the stats DB.
The stats DB has been exteded to account for new optional fields (
market_margin&is_maker_bot) and alsoswap_versionthat is set to 0 for old persisted swaps.SwapStatusp2p message was modefied in a backward compatible manner allow the new tpu-status to be sent as it couldn't fit to the existingSavedSwapstructure (esp. regardingMakerSavedEvent/TakerSavedEvents).The
FIXMEs should be resolved via discussion here.