From 22869f5cb14cc72d52770415f9f25cd1b03db05c Mon Sep 17 00:00:00 2001 From: Vova Lando Date: Tue, 8 Oct 2024 15:50:23 +0300 Subject: [PATCH 1/4] fix: server_status returns instance_id --- src/database.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++---- src/error.rs | 6 ++++++ src/main.rs | 4 ++-- 3 files changed, 58 insertions(+), 6 deletions(-) diff --git a/src/database.rs b/src/database.rs index 254c16c..954f06c 100644 --- a/src/database.rs +++ b/src/database.rs @@ -4,6 +4,7 @@ //! commercial offers and contracts, hence causality is a must. Care must be taken that no threads //! are spawned here other than main database server thread that does everything in series. +use crate::definitions::api_v2::ServerInfo; use crate::{ definitions::{ api_v2::{ @@ -15,6 +16,7 @@ use crate::{ error::{DbError, Error}, task_tracker::TaskTracker, }; +use names::Generator; use parity_scale_codec::{Decode, Encode}; use std::time::SystemTime; use substrate_crypto_light::common::AccountId32; @@ -51,9 +53,10 @@ const HIT_LIST: &str = "hit_list"; // The database version must be stored in a separate slot to be used by the not implemented yet // database migration logic. const DB_VERSION_KEY: &str = "db_version"; -const DAEMON_INFO: &str = "daemon_info"; +const SERVER_INFO_ID: &str = "instance_id"; -const ORDERS: &[u8] = b"orders"; +const ORDERS_TABLE: &[u8] = b"orders"; +const SERVER_INFO_TABLE: &[u8] = b"server_info"; // Slots @@ -174,7 +177,7 @@ impl Database { path_option: Option, task_tracker: TaskTracker, account_lifetime: Timestamp, - ) -> Result { + ) -> Result { let (tx, mut rx) = tokio::sync::mpsc::channel(1024); let database = if let Some(path) = path_option { tracing::info!("Creating/Opening the database at {path:?}."); @@ -188,7 +191,9 @@ impl Database { );*/ sled::open("temp.db").map_err(DbError::DbStartError)? }; - let orders = database.open_tree(ORDERS).map_err(DbError::DbStartError)?; + let orders = database + .open_tree(ORDERS_TABLE) + .map_err(DbError::DbStartError)?; task_tracker.spawn("Database server", async move { // No process forking beyond this point! @@ -230,6 +235,40 @@ impl Database { DbRequest::MarkStuck(request) => { let _unused = request.res.send(mark_stuck(request.order, &orders)); } + DbRequest::InitializeServerInfo(res) => { + let server_info_tree = database + .open_tree(SERVER_INFO_TABLE) + .map_err(DbError::DbStartError); + let result = server_info_tree.and_then(|tree| { + if let Some(server_info_data) = + tree.get(SERVER_INFO_ID).map_err(DbError::DbInternalError)? + { + let server_info: ServerInfo = + serde_json::from_slice(&server_info_data).map_err(|e| { + DbError::DeserializationError(e.to_string()) + })?; + Ok(server_info.instance_id) + } else { + let mut generator = Generator::default(); + let new_instance_id = generator + .next() + .unwrap_or_else(|| "unknown-instance".to_string()); + let server_info_data = ServerInfo { + version: env!("CARGO_PKG_VERSION").to_string(), + instance_id: new_instance_id.clone(), + debug: false, + kalatori_remark: None, + }; + tree.insert( + SERVER_INFO_ID, + serde_json::to_vec(&server_info_data) + .map_err(|e| DbError::SerializationError(e.to_string()))?, + )?; + Ok(new_instance_id) + } + }); + let _unused = res.send(result); + } DbRequest::Shutdown(res) => { let _ = res.send(()); break; @@ -245,6 +284,12 @@ impl Database { Ok(Self { tx }) } + pub async fn initialize_server_info(&self) -> Result { + let (res, rx) = oneshot::channel(); + let _unused = self.tx.send(DbRequest::InitializeServerInfo(res)).await; + rx.await.map_err(|_| DbError::DbEngineDown)? + } + pub async fn order_list(&self) -> Result, DbError> { let (res, rx) = oneshot::channel(); let _unused = self.tx.send(DbRequest::ActiveOrderList(res)).await; @@ -322,6 +367,7 @@ enum DbRequest { MarkPaid(MarkPaid), MarkWithdrawn(ModifyOrder), MarkStuck(ModifyOrder), + InitializeServerInfo(oneshot::Sender>), Shutdown(oneshot::Sender<()>), } diff --git a/src/error.rs b/src/error.rs index b38ef4b..004689e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -318,6 +318,12 @@ pub enum DbError { #[error("there was already an attempt to withdraw order {0:?}")] WithdrawalWasAttempted(String), + + #[error("wasn't able to serialize {0:?} field")] + SerializationError(String), + + #[error("wasn't able to deserialize {0:?} table")] + DeserializationError(String), } #[derive(Debug, Error)] diff --git a/src/main.rs b/src/main.rs index 516e9e9..100d9c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -101,8 +101,6 @@ async fn async_try_main( Some(config.database.unwrap_or_else(|| DATABASE_DEFAULT.into())) }; - let instance_id = String::from("TODO: add unique ID and save it in db"); - // Start services tracing::info!( @@ -126,6 +124,8 @@ async fn async_try_main( config.account_lifetime, )?; + let instance_id = db.initialize_server_info().await?; + let (cm_tx, cm_rx) = oneshot::channel(); let state = State::initialise( From feac239917b39c39ca260de55c379365e5139550 Mon Sep 17 00:00:00 2001 From: Vova Lando Date: Wed, 9 Oct 2024 14:00:50 +0300 Subject: [PATCH 2/4] fix: mark_paid will get order correctly now --- src/database.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/database.rs b/src/database.rs index 954f06c..6eabe71 100644 --- a/src/database.rs +++ b/src/database.rs @@ -16,7 +16,7 @@ use crate::{ error::{DbError, Error}, task_tracker::TaskTracker, }; -use names::Generator; +use names::{Generator, Name}; use parity_scale_codec::{Decode, Encode}; use std::time::SystemTime; use substrate_crypto_light::common::AccountId32; @@ -446,7 +446,8 @@ fn read_order(order: String, orders: &sled::Tree) -> Result, D } fn mark_paid(order: String, orders: &sled::Tree) -> Result { - if let Some(order_info) = orders.get(order.clone())? { + let order_key = order.encode(); + if let Some(order_info) = orders.get(order_key)? { let mut order_info = OrderInfo::decode(&mut &order_info[..])?; if order_info.payment_status == PaymentStatus::Pending { order_info.payment_status = PaymentStatus::Paid; From 729e3d285da851d60362a44c9b9b074393fb3a2b Mon Sep 17 00:00:00 2001 From: Vova Lando Date: Wed, 9 Oct 2024 17:46:57 +0300 Subject: [PATCH 3/4] feat: doccker environment for chopsticks and compose to spawn 4 chopsticks instances in parallel looking at different RPCs --- chopsticks/Dockerfile | 14 +++++++++++ chopsticks/docker-compose.yml | 46 +++++++++++++++++++++++++++++++++++ chopsticks/pd-2.yml | 11 +++++++++ chopsticks/pd-ah-2.yml | 15 ++++++++++++ chopsticks/pd-ah.yml | 2 +- configs/chopsticks.toml | 16 +++++++++--- 6 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 chopsticks/Dockerfile create mode 100644 chopsticks/docker-compose.yml create mode 100644 chopsticks/pd-2.yml create mode 100644 chopsticks/pd-ah-2.yml diff --git a/chopsticks/Dockerfile b/chopsticks/Dockerfile new file mode 100644 index 0000000..195588b --- /dev/null +++ b/chopsticks/Dockerfile @@ -0,0 +1,14 @@ +# Dockerfile +FROM node:16-alpine + +# Set the working directory +WORKDIR /app + +# Install Chopsticks +RUN npm install -g @acala-network/chopsticks + +# Expose ports for both instances +EXPOSE 8000 8500 9000 9500 + +# Default command (this will be overridden by docker-compose) +CMD ["chopsticks", "-c", "/app/config.yml", "-p", "9000"] diff --git a/chopsticks/docker-compose.yml b/chopsticks/docker-compose.yml new file mode 100644 index 0000000..4d6db64 --- /dev/null +++ b/chopsticks/docker-compose.yml @@ -0,0 +1,46 @@ +version: '3.8' + +services: + chopsticks-polkadot: + build: + context: . + dockerfile: Dockerfile + container_name: chopsticks-polkadot + ports: + - "8000:8000" + volumes: + - ./pd.yml:/app/config.yml + command: ["chopsticks", "-c", "/app/config.yml", "-p", "8000", "--addr", "0.0.0.0"] + + chopsticks-polkadot-2: + build: + context: . + dockerfile: Dockerfile + container_name: chopsticks-polkadot-2 + ports: + - "8500:8500" + volumes: + - ./pd-2.yml:/app/config.yml + command: [ "chopsticks", "-c", "/app/config.yml", "-p", "8500", "--addr", "0.0.0.0" ] + + chopsticks-statemint: + build: + context: . + dockerfile: Dockerfile + container_name: chopsticks-statemint + ports: + - "9000:9000" + volumes: + - ./pd-ah.yml:/app/config.yml + command: ["chopsticks", "-c", "/app/config.yml", "-p", "9000", "--addr", "0.0.0.0"] + + chopsticks-statemint-2: + build: + context: . + dockerfile: Dockerfile + container_name: chopsticks-statemint-2 + ports: + - "9500:9500" + volumes: + - ./pd-ah-2.yml:/app/config.yml + command: [ "chopsticks", "-c", "/app/config.yml", "-p", "9500", "--addr", "0.0.0.0" ] diff --git a/chopsticks/pd-2.yml b/chopsticks/pd-2.yml new file mode 100644 index 0000000..4422480 --- /dev/null +++ b/chopsticks/pd-2.yml @@ -0,0 +1,11 @@ +endpoint: wss://1rpc.io/dot + +import-storage: + System: + Account: + - + - + - 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + - providers: 1 + data: + free: 1000000000000000 diff --git a/chopsticks/pd-ah-2.yml b/chopsticks/pd-ah-2.yml new file mode 100644 index 0000000..4471dcd --- /dev/null +++ b/chopsticks/pd-ah-2.yml @@ -0,0 +1,15 @@ +endpoint: wss://statemint-rpc.dwellir.com + +import-storage: + System: + Account: + - + - + - 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + - providers: 1 + data: + free: 1000000000000000 + Assets: + Account: + - [[1984, 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY], { balance: 1000000000 }] + - [[1337, 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY], { balance: 1000000000 }] diff --git a/chopsticks/pd-ah.yml b/chopsticks/pd-ah.yml index bbdb482..8e28c18 100644 --- a/chopsticks/pd-ah.yml +++ b/chopsticks/pd-ah.yml @@ -1,4 +1,4 @@ -endpoint: wss://statemint.api.onfinality.io/public-ws +endpoint: wss://polkadot-asset-hub-rpc.polkadot.io import-storage: System: diff --git a/configs/chopsticks.toml b/configs/chopsticks.toml index e832b2b..d4f540c 100644 --- a/configs/chopsticks.toml +++ b/configs/chopsticks.toml @@ -1,12 +1,22 @@ account-lifetime = 86400000 # 1 day. depth = 3600000 # 1 hour. debug = true -in-memory-db = true + +[[chain]] +name = "polkadot" +native-token = "DOT" +decimals = 10 +endpoints = [ + "ws://localhost:8000", + "ws://localhost:8500", +] [[chain]] name = "statemint" +decimals = 6 endpoints = [ - "ws://localhost:8000" + "ws://localhost:9000", + "ws://localhost:9500", ] [[chain.asset]] @@ -14,5 +24,5 @@ name = "USDC" id = 1337 [[chain.asset]] -name = "USDT" +name = "USDt" id = 1984 From fe0425f211d858ecb1426efb35afe8460c04bf90 Mon Sep 17 00:00:00 2001 From: Vova Lando Date: Thu, 10 Oct 2024 10:57:40 +0300 Subject: [PATCH 4/4] chore: release 0.2.2 --- CHANGELOG.md | 13 ++++++++++++- CONTRIBUTING.md | 12 +++++++++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9744da4..0629fe5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,18 @@ All notable changes to this project will be documented in this file. -## [2.1.2] - 2024-10-07 +## [0.2.2] - 2024-10-10 + +### 🚀 Features + +- Docker environment for chopsticks and compose to spawn 4 chopsticks instances in parallel looking at different RPCs + +### 🐛 Bug Fixes + +- Server_status API request returns instance_id instead of placeholder +- Mark_paid function will mark order correctly now + +## [0.2.1] - 2024-10-07 Making the order request work according to specs in the [specs](https://alzymologist.github.io/kalatori-api/#/). Using the tests from [kalatori-api-test-suite]() in order to validate. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 94b72dd..10ddf6a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,13 @@ +## Preparing development environment + +It's possible to mimic to spawn chopsticks instances in parallel for development purposes. +Chopsticks Dockerfile exposes 4 ports (8000, 8500, 9000, 9500), so you can spawn 4 instances of chopsticks and each one of them will look at different RPC. +Note that the RPCs are not real, so the changes made on one chopsticks instance will not affect the others. + +1. `cd chopsticks` +2. `docker compose up`, in case you want to just 2 instances edit the docker-compose.yml file +3. start the app with `KALATORI_CONFIG` environment variable pointing to `configs/chopsticks.toml` + ## Version Bumping and Release Process When you make changes that require a new version of the project, follow these steps to bump the version: @@ -22,7 +32,7 @@ When you make changes that require a new version of the project, follow these st git push origin ``` -4. **Tag the version**: +4. **Tag the version at main branch**: ```bash git tag -a v2.1.2 -m "Release version 2.1.2" git push origin v2.1.2 diff --git a/Cargo.lock b/Cargo.lock index 9782db2..f1c10d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1427,7 +1427,7 @@ dependencies = [ [[package]] name = "kalatori" -version = "0.2.1" +version = "0.2.2" dependencies = [ "ahash", "axum", diff --git a/Cargo.toml b/Cargo.toml index c30dd6e..05312fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kalatori" authors = ["Alzymologist Oy "] -version = "0.2.1" +version = "0.2.2" edition = "2021" description = "A gateway daemon for Kalatori." license = "GPL-3.0-or-later"