From 59ec60edc63be4c824d454a71c6e8a48b97635b5 Mon Sep 17 00:00:00 2001 From: Richard Holzeis Date: Wed, 6 Mar 2024 14:13:38 +0100 Subject: [PATCH 1/6] feat(user): Save app version on user login I opted to use the Cargo.toml version instead of the pubspec.yaml version as it is easier to access from rust and should probably anyways be bumped with every release. A minor downside of this is now that we have to different sources for the version. However, both versions are bumped by the same ci pipeline during `draft_new_release` - so eventually the source is the same. --- .../down.sql | 1 + .../2024-03-06-1135500_add_version_to_user/up.sql | 1 + coordinator/src/db/user.rs | 14 +++++++++++++- .../src/orderbook/tests/registration_test.rs | 5 ++++- coordinator/src/orderbook/websocket.rs | 3 ++- coordinator/src/routes.rs | 1 + coordinator/src/schema.rs | 1 + crates/commons/src/lib.rs | 1 + crates/commons/src/message.rs | 1 + crates/orderbook-client/examples/authenticated.rs | 2 +- crates/orderbook-client/src/lib.rs | 7 +++++-- mobile/native/src/api.rs | 5 ++++- mobile/native/src/orderbook.rs | 3 ++- mobile/native/src/trade/users/mod.rs | 4 +++- 14 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 coordinator/migrations/2024-03-06-1135500_add_version_to_user/down.sql create mode 100644 coordinator/migrations/2024-03-06-1135500_add_version_to_user/up.sql diff --git a/coordinator/migrations/2024-03-06-1135500_add_version_to_user/down.sql b/coordinator/migrations/2024-03-06-1135500_add_version_to_user/down.sql new file mode 100644 index 000000000..d2b80c079 --- /dev/null +++ b/coordinator/migrations/2024-03-06-1135500_add_version_to_user/down.sql @@ -0,0 +1 @@ +ALTER TABLE users DROP COLUMN IF EXISTS "version"; diff --git a/coordinator/migrations/2024-03-06-1135500_add_version_to_user/up.sql b/coordinator/migrations/2024-03-06-1135500_add_version_to_user/up.sql new file mode 100644 index 000000000..bc5afa06c --- /dev/null +++ b/coordinator/migrations/2024-03-06-1135500_add_version_to_user/up.sql @@ -0,0 +1 @@ +ALTER TABLE users ADD COLUMN "version" TEXT; diff --git a/coordinator/src/db/user.rs b/coordinator/src/db/user.rs index 0502b7189..e1b8b5b03 100644 --- a/coordinator/src/db/user.rs +++ b/coordinator/src/db/user.rs @@ -20,6 +20,7 @@ pub struct User { pub fcm_token: String, pub last_login: OffsetDateTime, pub nickname: Option, + pub version: Option, } impl From for User { @@ -32,6 +33,7 @@ impl From for User { timestamp: OffsetDateTime::now_utc(), fcm_token: "".to_owned(), last_login: OffsetDateTime::now_utc(), + version: value.version, } } } @@ -53,6 +55,7 @@ pub fn upsert_user( trader_id: PublicKey, contact: Option, nickname: Option, + version: Option, ) -> QueryResult { // If no name or contact has been provided we default to empty string let contact = contact.unwrap_or_default(); @@ -68,6 +71,7 @@ pub fn upsert_user( timestamp, fcm_token: "".to_owned(), last_login: timestamp, + version: version.clone(), }) .on_conflict(schema::users::pubkey) .do_update() @@ -75,6 +79,7 @@ pub fn upsert_user( users::contact.eq(&contact), users::nickname.eq(&nickname), users::last_login.eq(timestamp), + users::version.eq(version), )) .get_result(conn)?; Ok(user) @@ -103,7 +108,12 @@ pub fn update_nickname( Ok(()) } -pub fn login_user(conn: &mut PgConnection, trader_id: PublicKey, token: String) -> Result<()> { +pub fn login_user( + conn: &mut PgConnection, + trader_id: PublicKey, + token: String, + version: Option, +) -> Result<()> { tracing::debug!(%trader_id, token, "Updating token for client."); let last_login = OffsetDateTime::now_utc(); let affected_rows = diesel::insert_into(users::table) @@ -114,6 +124,7 @@ pub fn login_user(conn: &mut PgConnection, trader_id: PublicKey, token: String) nickname: None, timestamp: OffsetDateTime::now_utc(), fcm_token: token.clone(), + version: version.clone(), last_login, }) .on_conflict(schema::users::pubkey) @@ -121,6 +132,7 @@ pub fn login_user(conn: &mut PgConnection, trader_id: PublicKey, token: String) .set(( users::fcm_token.eq(&token), users::last_login.eq(last_login), + users::version.eq(version), )) .execute(conn)?; diff --git a/coordinator/src/orderbook/tests/registration_test.rs b/coordinator/src/orderbook/tests/registration_test.rs index dc8fefc96..f15de5b0e 100644 --- a/coordinator/src/orderbook/tests/registration_test.rs +++ b/coordinator/src/orderbook/tests/registration_test.rs @@ -22,16 +22,18 @@ async fn registered_user_is_stored_in_db() { let dummy_email = "dummy@user.com".to_string(); let nickname = Some("dummy_user".to_string()); let fcm_token = "just_a_token".to_string(); + let version = Some("1.9.0".to_string()); let user = user::upsert_user( &mut conn, dummy_pubkey, Some(dummy_email.clone()), nickname.clone(), + version.clone(), ) .unwrap(); assert!(user.id.is_some(), "Id should be filled in by diesel"); - user::login_user(&mut conn, dummy_pubkey, fcm_token.clone()).unwrap(); + user::login_user(&mut conn, dummy_pubkey, fcm_token.clone(), version.clone()).unwrap(); let users = user::all(&mut conn).unwrap(); assert_eq!(users.len(), 1); @@ -40,6 +42,7 @@ async fn registered_user_is_stored_in_db() { assert_eq!(users.first().unwrap().contact, dummy_email); assert_eq!(users.first().unwrap().nickname, nickname); assert_eq!(users.first().unwrap().fcm_token, fcm_token); + assert_eq!(users.first().unwrap().version, version); } fn dummy_public_key() -> PublicKey { diff --git a/coordinator/src/orderbook/websocket.rs b/coordinator/src/orderbook/websocket.rs index 81b586a2e..b0711b98d 100644 --- a/coordinator/src/orderbook/websocket.rs +++ b/coordinator/src/orderbook/websocket.rs @@ -119,6 +119,7 @@ pub async fn websocket_connection(stream: WebSocket, state: Arc) { } Ok(OrderbookRequest::Authenticate { fcm_token, + version, signature, }) => { let msg = create_sign_message(AUTH_SIGN_MESSAGE.to_vec()); @@ -160,7 +161,7 @@ pub async fn websocket_connection(stream: WebSocket, state: Arc) { } let token = fcm_token.unwrap_or("unavailable".to_string()); - if let Err(e) = user::login_user(&mut conn, trader_id, token) { + if let Err(e) = user::login_user(&mut conn, trader_id, token, version) { tracing::error!(%trader_id, "Failed to update logged in user. Error: {e:#}") } diff --git a/coordinator/src/routes.rs b/coordinator/src/routes.rs index 49a52c641..f84c9edd0 100644 --- a/coordinator/src/routes.rs +++ b/coordinator/src/routes.rs @@ -337,6 +337,7 @@ pub async fn post_register( register_params.pubkey, register_params.contact.clone(), register_params.nickname.clone(), + register_params.version.clone(), ) .map_err(|e| AppError::InternalServerError(format!("Could not upsert user: {e:#}")))?; diff --git a/coordinator/src/schema.rs b/coordinator/src/schema.rs index e5d15b3a5..368be7d6d 100644 --- a/coordinator/src/schema.rs +++ b/coordinator/src/schema.rs @@ -374,6 +374,7 @@ diesel::table! { fcm_token -> Text, last_login -> Timestamptz, nickname -> Nullable, + version -> Nullable, } } diff --git a/crates/commons/src/lib.rs b/crates/commons/src/lib.rs index ed48ac7f1..39d28eb40 100644 --- a/crates/commons/src/lib.rs +++ b/crates/commons/src/lib.rs @@ -38,6 +38,7 @@ pub struct RegisterParams { pub pubkey: PublicKey, pub contact: Option, pub nickname: Option, + pub version: Option, } /// Registration details for enrolling into the beta program diff --git a/crates/commons/src/message.rs b/crates/commons/src/message.rs index 21fddba30..43f494638 100644 --- a/crates/commons/src/message.rs +++ b/crates/commons/src/message.rs @@ -64,6 +64,7 @@ pub struct LspConfig { pub enum OrderbookRequest { Authenticate { fcm_token: Option, + version: Option, signature: Signature, }, LimitOrderFilledMatches { diff --git a/crates/orderbook-client/examples/authenticated.rs b/crates/orderbook-client/examples/authenticated.rs index 36769dbfa..3a2381229 100644 --- a/crates/orderbook-client/examples/authenticated.rs +++ b/crates/orderbook-client/examples/authenticated.rs @@ -26,7 +26,7 @@ async fn main() -> Result { loop { let (_, mut stream) = - orderbook_client::subscribe_with_authentication(url.clone(), &authenticate, None) + orderbook_client::subscribe_with_authentication(url.clone(), &authenticate, None, None) .await?; loop { diff --git a/crates/orderbook-client/src/lib.rs b/crates/orderbook-client/src/lib.rs index 57b6c7585..240a4875f 100644 --- a/crates/orderbook-client/src/lib.rs +++ b/crates/orderbook-client/src/lib.rs @@ -23,7 +23,7 @@ pub async fn subscribe( SplitSink, impl Stream> + Unpin, )> { - subscribe_impl(None, url, None).await + subscribe_impl(None, url, None, None).await } /// Connects to the orderbook WebSocket API with authentication. @@ -33,12 +33,13 @@ pub async fn subscribe_with_authentication( url: String, authenticate: impl Fn(Message) -> Signature, fcm_token: Option, + version: Option, ) -> Result<( SplitSink, impl Stream> + Unpin, )> { let signature = create_auth_message_signature(authenticate); - subscribe_impl(Some(signature), url, fcm_token).await + subscribe_impl(Some(signature), url, fcm_token, version).await } pub fn create_auth_message_signature(authenticate: impl Fn(Message) -> Signature) -> Signature { @@ -50,6 +51,7 @@ async fn subscribe_impl( signature: Option, url: String, fcm_token: Option, + version: Option, ) -> Result<( SplitSink, impl Stream> + Unpin, @@ -67,6 +69,7 @@ async fn subscribe_impl( .send(tungstenite::Message::try_from( OrderbookRequest::Authenticate { fcm_token, + version, signature, }, )?) diff --git a/mobile/native/src/api.rs b/mobile/native/src/api.rs index 7149d5f0c..e09058e56 100644 --- a/mobile/native/src/api.rs +++ b/mobile/native/src/api.rs @@ -431,10 +431,12 @@ pub fn run_in_flutter(seed_dir: String, fcm_token: String) -> Result<()> { signature: ln_dlc::get_node_key().sign_ecdsa(msg), }); + let version = env!("CARGO_PKG_VERSION").to_string(); let runtime = crate::state::get_or_create_tokio_runtime()?; runtime.block_on(async { tx_websocket.send(OrderbookRequest::Authenticate { fcm_token: Some(fcm_token), + version: Some(version), signature, }) })?; @@ -724,7 +726,8 @@ pub fn init_new_mnemonic(target_seed_file_path: String) -> Result<()> { /// Enroll or update a user in the beta program #[tokio::main(flavor = "current_thread")] pub async fn register_beta(contact: String) -> Result<()> { - users::register_beta(contact).await + let version = env!("CARGO_PKG_VERSION").to_string(); + users::register_beta(contact, version).await } #[derive(Debug)] diff --git a/mobile/native/src/orderbook.rs b/mobile/native/src/orderbook.rs index 0d6c698a7..107ac4a71 100644 --- a/mobile/native/src/orderbook.rs +++ b/mobile/native/src/orderbook.rs @@ -114,7 +114,8 @@ pub fn subscribe( loop { let url = url.clone(); let fcm_token = fcm_token.clone(); - match orderbook_client::subscribe_with_authentication(url, authenticate, fcm_token) + let version = env!("CARGO_PKG_VERSION").to_string(); + match orderbook_client::subscribe_with_authentication(url, authenticate, fcm_token, Some(version)) .await { Ok((mut sink, mut stream)) => { diff --git a/mobile/native/src/trade/users/mod.rs b/mobile/native/src/trade/users/mod.rs index eddd6945f..79516911c 100644 --- a/mobile/native/src/trade/users/mod.rs +++ b/mobile/native/src/trade/users/mod.rs @@ -9,17 +9,19 @@ use commons::UpdateUsernameParams; use commons::User; /// Enroll the user in the beta program -pub async fn register_beta(contact: String) -> Result<()> { +pub async fn register_beta(contact: String, version: String) -> Result<()> { let name = crate::names::get_new_name(); let register = RegisterParams { pubkey: ln_dlc::get_node_pubkey(), contact: Some(contact), nickname: Some(name), + version: Some(version.clone()), }; tracing::debug!( pubkey = register.pubkey.to_string(), contact = register.contact, + version, "Registering user" ); From 226ddd0226aa0e7748215cc41597978bce94045d Mon Sep 17 00:00:00 2001 From: Richard Holzeis Date: Wed, 6 Mar 2024 15:04:05 +0100 Subject: [PATCH 2/6] chore(ci): Bump mobile/native Cargo.toml version We might want to consider simply bumping the versions of all crates instead of selectively bumping some. --- .github/workflows/draft_new_release.yml | 14 ++++++++++++-- Cargo.lock | 2 +- mobile/native/Cargo.toml | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.github/workflows/draft_new_release.yml b/.github/workflows/draft_new_release.yml index 24e87c2ef..9b6c48e00 100644 --- a/.github/workflows/draft_new_release.yml +++ b/.github/workflows/draft_new_release.yml @@ -63,12 +63,22 @@ jobs: run: | cargo set-version --package webapp ${{ github.event.inputs.version }} - - name: Commit changelog and manifest files + - name: Bump mobile/native Cargo.toml version + uses: stellar/binaries@v13 + with: + name: cargo-edit + version: 0.11.6 + - id: set-mobile-version + continue-on-error: true + run: | + cargo set-version --package mobile/native ${{ github.event.inputs.version }} + + - name: Commit manifest files id: make-commit run: | /home/runner/.dprint/bin/dprint fmt - git add mobile/pubspec.yaml coordinator/Cargo.toml webapp/Cargo.toml + git add mobile/native/Cargo.toml mobile/pubspec.yaml coordinator/Cargo.toml webapp/Cargo.toml git commit --message "Prepare release ${{ github.event.inputs.version }}" echo "::set-output name=commit::$(git rev-parse HEAD)" diff --git a/Cargo.lock b/Cargo.lock index 02638af88..4791d4577 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2611,7 +2611,7 @@ dependencies = [ [[package]] name = "native" -version = "0.1.0" +version = "1.9.0" dependencies = [ "aes-gcm-siv", "anyhow", diff --git a/mobile/native/Cargo.toml b/mobile/native/Cargo.toml index 9c84a6722..be92eb2f3 100644 --- a/mobile/native/Cargo.toml +++ b/mobile/native/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "native" -version = "0.1.0" +version = "1.9.0" edition = "2021" [lib] From cd8a7701f8900caedbd34453f634e22dbe3e323f Mon Sep 17 00:00:00 2001 From: Richard Holzeis Date: Wed, 6 Mar 2024 15:09:43 +0100 Subject: [PATCH 3/6] chore(ci): Commit cargo.lock --- .github/workflows/draft_new_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/draft_new_release.yml b/.github/workflows/draft_new_release.yml index 9b6c48e00..be345be50 100644 --- a/.github/workflows/draft_new_release.yml +++ b/.github/workflows/draft_new_release.yml @@ -78,7 +78,7 @@ jobs: run: | /home/runner/.dprint/bin/dprint fmt - git add mobile/native/Cargo.toml mobile/pubspec.yaml coordinator/Cargo.toml webapp/Cargo.toml + git add mobile/native/Cargo.toml mobile/pubspec.yaml coordinator/Cargo.toml webapp/Cargo.toml Cargo.lock git commit --message "Prepare release ${{ github.event.inputs.version }}" echo "::set-output name=commit::$(git rev-parse HEAD)" From c6d1836b1ec3d9282b3721190d496cccc7506b38 Mon Sep 17 00:00:00 2001 From: Richard Holzeis Date: Wed, 6 Mar 2024 15:40:18 +0100 Subject: [PATCH 4/6] chore(user): Expect trader id as reference --- coordinator/src/db/user.rs | 2 +- coordinator/src/leaderboard.rs | 2 +- coordinator/src/routes.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/coordinator/src/db/user.rs b/coordinator/src/db/user.rs index e1b8b5b03..87456fafa 100644 --- a/coordinator/src/db/user.rs +++ b/coordinator/src/db/user.rs @@ -144,7 +144,7 @@ pub fn login_user( Ok(()) } -pub fn get_user(conn: &mut PgConnection, trader_id: PublicKey) -> Result> { +pub fn get_user(conn: &mut PgConnection, trader_id: &PublicKey) -> Result> { let maybe_user = users::table .filter(users::pubkey.eq(trader_id.to_string())) .first(conn) diff --git a/coordinator/src/leaderboard.rs b/coordinator/src/leaderboard.rs index 862de2fcf..d829292fc 100644 --- a/coordinator/src/leaderboard.rs +++ b/coordinator/src/leaderboard.rs @@ -61,7 +61,7 @@ pub(crate) fn generate_leader_board( let leader_board = leader_board .into_iter() .map(|entry| { - let nickname = db::user::get_user(conn, entry.trader).unwrap_or_default(); + let nickname = db::user::get_user(conn, &entry.trader).unwrap_or_default(); LeaderBoardEntry { nickname: nickname.and_then(|user| user.nickname).unwrap_or_default(), ..entry diff --git a/coordinator/src/routes.rs b/coordinator/src/routes.rs index f84c9edd0..d220c3b51 100644 --- a/coordinator/src/routes.rs +++ b/coordinator/src/routes.rs @@ -389,7 +389,7 @@ pub async fn get_user( let trader_pubkey = PublicKey::from_str(trader_pubkey.as_str()) .map_err(|_| AppError::BadRequest("Invalid trader id provided".to_string()))?; - let option = user::get_user(&mut conn, trader_pubkey) + let option = user::get_user(&mut conn, &trader_pubkey) .map_err(|e| AppError::InternalServerError(format!("Could not load users: {e:#}")))?; match option { From 7a54139e1f597c118fc1fe10c9750f1c117ca5cf Mon Sep 17 00:00:00 2001 From: Richard Holzeis Date: Wed, 6 Mar 2024 15:41:35 +0100 Subject: [PATCH 5/6] feat(trade): Block user from trading if not on latest version --- coordinator/src/check_version.rs | 21 +++++++++++++++++++++ coordinator/src/db/user.rs | 2 ++ coordinator/src/lib.rs | 1 + coordinator/src/node/rollover.rs | 7 +++++++ coordinator/src/orderbook/async_match.rs | 6 ++++++ coordinator/src/orderbook/routes.rs | 11 +++++++++++ coordinator/src/routes.rs | 8 ++++++++ 7 files changed, 56 insertions(+) create mode 100644 coordinator/src/check_version.rs diff --git a/coordinator/src/check_version.rs b/coordinator/src/check_version.rs new file mode 100644 index 000000000..b6e31873e --- /dev/null +++ b/coordinator/src/check_version.rs @@ -0,0 +1,21 @@ +use crate::db; +use crate::db::user::User; +use anyhow::ensure; +use anyhow::Context; +use anyhow::Result; +use bitcoin::secp256k1::PublicKey; +use diesel::PgConnection; + +pub fn check_version(conn: &mut PgConnection, trader_id: &PublicKey) -> Result<()> { + let user: User = db::user::get_user(conn, trader_id)?.context("Couldn't find user")?; + + let app_version = user.version.context("No version found")?; + + let coordinator_version = env!("CARGO_PKG_VERSION").to_string(); + ensure!( + app_version == coordinator_version, + format!("Please upgrade to the latest version: {coordinator_version}") + ); + + Ok(()) +} diff --git a/coordinator/src/db/user.rs b/coordinator/src/db/user.rs index 87456fafa..a62c9d230 100644 --- a/coordinator/src/db/user.rs +++ b/coordinator/src/db/user.rs @@ -20,6 +20,8 @@ pub struct User { pub fcm_token: String, pub last_login: OffsetDateTime, pub nickname: Option, + // TODO(holzeis): Version is only optional for the first upgrade. Afterwards we should make it + // mandatory. pub version: Option, } diff --git a/coordinator/src/lib.rs b/coordinator/src/lib.rs index 14a70a13d..8a16326fa 100644 --- a/coordinator/src/lib.rs +++ b/coordinator/src/lib.rs @@ -22,6 +22,7 @@ mod payout_curve; pub mod admin; pub mod backup; pub mod campaign; +pub mod check_version; pub mod cli; pub mod db; pub mod dlc_handler; diff --git a/coordinator/src/node/rollover.rs b/coordinator/src/node/rollover.rs index 30cab2d3e..434fb7749 100644 --- a/coordinator/src/node/rollover.rs +++ b/coordinator/src/node/rollover.rs @@ -1,3 +1,4 @@ +use crate::check_version::check_version; use crate::db; use crate::db::positions; use crate::dlc_protocol; @@ -168,6 +169,12 @@ impl Node { .expect("task to complete")?; tracing::debug!(%trader_id, "Checking if the users positions is eligible for rollover"); + + if check_version(&mut conn, &trader_id).is_err() { + tracing::info!(%trader_id, "User is not on the latest version. Skipping check if users position is eligible for rollover"); + return Ok(()); + } + if let Some(position) = positions::Position::get_position_by_trader( &mut conn, trader_id, diff --git a/coordinator/src/orderbook/async_match.rs b/coordinator/src/orderbook/async_match.rs index ada032010..4e4ae517a 100644 --- a/coordinator/src/orderbook/async_match.rs +++ b/coordinator/src/orderbook/async_match.rs @@ -1,3 +1,4 @@ +use crate::check_version::check_version; use crate::message::NewUserMessage; use crate::message::OrderbookMessage; use crate::orderbook::db::matches; @@ -90,6 +91,11 @@ async fn process_pending_match( .await .expect("task to complete")?; + if check_version(&mut conn, &trader_id).is_err() { + tracing::info!(%trader_id, "User is not on the latest version. Skipping check if user needs to be informed about pending matches."); + return Ok(()); + } + if let Some(order) = orders::get_by_trader_id_and_state(&mut conn, trader_id, OrderState::Matched)? { diff --git a/coordinator/src/orderbook/routes.rs b/coordinator/src/orderbook/routes.rs index 78c5da4e6..af21d8d58 100644 --- a/coordinator/src/orderbook/routes.rs +++ b/coordinator/src/orderbook/routes.rs @@ -1,3 +1,4 @@ +use crate::check_version::check_version; use crate::orderbook; use crate::orderbook::trading::NewOrderMessage; use crate::orderbook::trading::TradingError; @@ -74,6 +75,16 @@ pub async fn post_order( let new_order = new_order_request.value; + // TODO(holzeis): We should add a similar check eventually for limit orders (makers). + if new_order.order_type == OrderType::Market { + let mut conn = state + .pool + .get() + .map_err(|e| AppError::InternalServerError(e.to_string()))?; + check_version(&mut conn, &new_order.trader_id) + .map_err(|e| AppError::BadRequest(e.to_string()))?; + } + let settings = state.settings.read().await; if new_order.order_type == OrderType::Limit && settings.whitelist_enabled diff --git a/coordinator/src/routes.rs b/coordinator/src/routes.rs index d220c3b51..27c5e109b 100644 --- a/coordinator/src/routes.rs +++ b/coordinator/src/routes.rs @@ -13,6 +13,7 @@ use crate::admin::roll_back_dlc_channel; use crate::admin::sign_message; use crate::backup::SledBackup; use crate::campaign::post_push_campaign; +use crate::check_version::check_version; use crate::collaborative_revert::confirm_collaborative_revert; use crate::db; use crate::db::user; @@ -263,6 +264,13 @@ pub async fn post_trade( State(state): State>, params: Json, ) -> Result<(), AppError> { + let mut conn = state + .pool + .get() + .map_err(|e| AppError::InternalServerError(e.to_string()))?; + check_version(&mut conn, ¶ms.trade_params.pubkey) + .map_err(|e| AppError::BadRequest(e.to_string()))?; + state .node .trade(state.auth_users_notifier.clone(), params.0) From bb70acba513ba9b0023e4abf3433d2a66c82935b Mon Sep 17 00:00:00 2001 From: Richard Holzeis Date: Wed, 6 Mar 2024 16:23:40 +0100 Subject: [PATCH 6/6] chore(error handling): Add reason to order rejected failure type --- mobile/lib/features/trade/domain/order.dart | 5 ++--- mobile/native/src/db/models.rs | 10 +++++++--- mobile/native/src/trade/order/api.rs | 4 ++-- mobile/native/src/trade/order/handler.rs | 2 +- mobile/native/src/trade/order/mod.rs | 2 +- mobile/native/src/trade/order/orderbook_client.rs | 4 ++-- webapp/src/api.rs | 2 +- 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/mobile/lib/features/trade/domain/order.dart b/mobile/lib/features/trade/domain/order.dart index 65f494bdf..f0f7fda5e 100644 --- a/mobile/lib/features/trade/domain/order.dart +++ b/mobile/lib/features/trade/domain/order.dart @@ -66,8 +66,6 @@ class FailureReason { static const FailureReason timeout = FailureReason._( failureType: FailureReasonType.timeout, details: "The order timed out before finding a match"); - static const FailureReason rejected = - FailureReason._(failureType: FailureReasonType.rejected, details: "The order was rejected."); static const FailureReason unknown = FailureReason._( failureType: FailureReasonType.unknown, details: "An unknown error occurred."); @@ -90,7 +88,8 @@ class FailureReason { case bridge.FailureReason_TimedOut(): return timeout; case bridge.FailureReason_OrderRejected(): - return rejected; + return FailureReason._( + failureType: FailureReasonType.rejected, details: failureReason.field0); case bridge.FailureReason_Unknown(): return unknown; } diff --git a/mobile/native/src/db/models.rs b/mobile/native/src/db/models.rs index f48459e6f..279ba0f00 100644 --- a/mobile/native/src/db/models.rs +++ b/mobile/native/src/db/models.rs @@ -660,7 +660,7 @@ pub enum FailureReason { SubchannelOfferOutdated, SubchannelOfferDateUndetermined, SubchannelOfferUnacceptable, - OrderRejected, + OrderRejected(String), Unknown, } @@ -694,7 +694,9 @@ impl From for crate::trade::order::FailureReason { InvalidSubchannelOffer::Unacceptable, ) } - FailureReason::OrderRejected => crate::trade::order::FailureReason::OrderRejected, + FailureReason::OrderRejected(reason) => { + crate::trade::order::FailureReason::OrderRejected(reason) + } FailureReason::Unknown => crate::trade::order::FailureReason::Unknown, } } @@ -722,7 +724,9 @@ impl From for FailureReason { } InvalidSubchannelOffer::Unacceptable => FailureReason::SubchannelOfferUnacceptable, }, - crate::trade::order::FailureReason::OrderRejected => FailureReason::OrderRejected, + crate::trade::order::FailureReason::OrderRejected(reason) => { + FailureReason::OrderRejected(reason) + } crate::trade::order::FailureReason::Unknown => FailureReason::Unknown, } } diff --git a/mobile/native/src/trade/order/api.rs b/mobile/native/src/trade/order/api.rs index 847968072..7ae7db285 100644 --- a/mobile/native/src/trade/order/api.rs +++ b/mobile/native/src/trade/order/api.rs @@ -44,7 +44,7 @@ pub enum FailureReason { OrderNotAcceptable, TimedOut, InvalidDlcOffer, - OrderRejected, + OrderRejected(String), Unknown, } @@ -144,7 +144,7 @@ impl From for FailureReason { order::FailureReason::OrderNotAcceptable => FailureReason::OrderNotAcceptable, order::FailureReason::TimedOut => FailureReason::TimedOut, order::FailureReason::InvalidDlcOffer(_) => FailureReason::InvalidDlcOffer, - order::FailureReason::OrderRejected => FailureReason::OrderRejected, + order::FailureReason::OrderRejected(reason) => FailureReason::OrderRejected(reason), order::FailureReason::CollabRevert => FailureReason::CollabRevert, order::FailureReason::Unknown => FailureReason::Unknown, } diff --git a/mobile/native/src/trade/order/handler.rs b/mobile/native/src/trade/order/handler.rs index 967e33774..a68a82e8f 100644 --- a/mobile/native/src/trade/order/handler.rs +++ b/mobile/native/src/trade/order/handler.rs @@ -116,7 +116,7 @@ pub async fn submit_order( update_order_state_in_db_and_ui( order.id, OrderState::Failed { - reason: FailureReason::OrderRejected, + reason: FailureReason::OrderRejected(err.to_string()), }, ) .map_err(SubmitOrderError::Storage)?; diff --git a/mobile/native/src/trade/order/mod.rs b/mobile/native/src/trade/order/mod.rs index 53986f60a..d65f1e778 100644 --- a/mobile/native/src/trade/order/mod.rs +++ b/mobile/native/src/trade/order/mod.rs @@ -38,7 +38,7 @@ pub enum FailureReason { TimedOut, InvalidDlcOffer(InvalidSubchannelOffer), /// The order has been rejected by the orderbook - OrderRejected, + OrderRejected(String), Unknown, } diff --git a/mobile/native/src/trade/order/orderbook_client.rs b/mobile/native/src/trade/order/orderbook_client.rs index d1ee58dbf..10bb0f5b9 100644 --- a/mobile/native/src/trade/order/orderbook_client.rs +++ b/mobile/native/src/trade/order/orderbook_client.rs @@ -34,8 +34,8 @@ impl OrderbookClient { let response = response.json().await?; Ok(response) } else { - tracing::error!("Could not create new order"); - bail!("Could not create new order: {response:?}") + let error = response.text().await?; + bail!("Could not create new order: {error}") } } } diff --git a/webapp/src/api.rs b/webapp/src/api.rs index 451b0431f..6781eb166 100644 --- a/webapp/src/api.rs +++ b/webapp/src/api.rs @@ -417,7 +417,7 @@ impl From<&native::trade::order::Order> for Order { } InvalidSubchannelOffer::Unacceptable => "OfferUnacceptable", }, - FailureReason::OrderRejected => "OrderRejected", + FailureReason::OrderRejected(_) => "OrderRejected", FailureReason::Unknown => "Unknown", } .to_string();