From 69bbac5e1e834da41fea5c4702f314846604385c Mon Sep 17 00:00:00 2001 From: luckysori Date: Tue, 7 Dec 2021 16:06:24 +1100 Subject: [PATCH] Allow maker to control lock and commit transaction fee rate --- Cargo.lock | 12 +- Cargo.toml | 3 +- .../20211207035936_add-fee-to-order.sql | 2 + daemon/sqlx-data.json | 104 +++++++++++------- daemon/src/db.rs | 26 ++++- daemon/src/maker_cfd.rs | 4 + daemon/src/model/cfd.rs | 4 + daemon/src/rollover_taker.rs | 1 + daemon/src/routes_maker.rs | 2 + daemon/src/setup_contract.rs | 16 ++- daemon/src/setup_maker.rs | 1 + daemon/src/setup_taker.rs | 1 + daemon/src/wallet.rs | 24 +++- daemon/tests/harness/mod.rs | 1 + 14 files changed, 143 insertions(+), 58 deletions(-) create mode 100644 daemon/migrations/20211207035936_add-fee-to-order.sql diff --git a/Cargo.lock b/Cargo.lock index c9d0f1c..9418fa3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1426,7 +1426,7 @@ dependencies = [ [[package]] name = "maia" version = "0.1.0" -source = "git+https://github.com/comit-network/maia?branch=temp-bdk-dependency#45e886ef9e04ce37c26b628abe143fd98e967fdd" +source = "git+https://github.com/comit-network/maia#baaad94a10291d4e55c3d2cd30f3736035ee10ea" dependencies = [ "anyhow", "bdk", @@ -2618,8 +2618,9 @@ dependencies = [ [[package]] name = "secp256k1-zkp" -version = "0.4.0" -source = "git+https://github.com/ElementsProject/rust-secp256k1-zkp#c8ff901516c9c299c9cc7331b15a7a14a05ced89" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e2709b09561dfb584b366bd418ee5549a858873baa707ed83d3eb986e34abf" dependencies = [ "rand 0.6.5", "secp256k1", @@ -2629,8 +2630,9 @@ dependencies = [ [[package]] name = "secp256k1-zkp-sys" -version = "0.4.0" -source = "git+https://github.com/ElementsProject/rust-secp256k1-zkp#c8ff901516c9c299c9cc7331b15a7a14a05ced89" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90c48e70d04fdd871498db6ac3b35eeae0a339ab1cd06af483fe8a6835d36def" dependencies = [ "cc", "secp256k1-sys", diff --git a/Cargo.toml b/Cargo.toml index 2f79d03..9432fe9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,6 @@ resolver = "2" [patch.crates-io] rocket = { git = "https://github.com/SergioBenitez/Rocket" } # Need to patch rocket dependency of `rocket_basicauth` until there is an official release. xtra = { git = "https://github.com/Restioson/xtra" } # We need to use unreleased patches. -secp256k1-zkp = { git = "https://github.com/ElementsProject/rust-secp256k1-zkp" } # We need to use unreleased patches. -maia = { git = "https://github.com/comit-network/maia", branch = "temp-bdk-dependency" } # Unreleased +maia = { git = "https://github.com/comit-network/maia" } # Unreleased xtra_productivity = { git = "https://github.com/comit-network/xtra-productivity" } # Unreleased bdk = { git = "https://github.com/bitcoindevkit/bdk" } # Unreleased diff --git a/daemon/migrations/20211207035936_add-fee-to-order.sql b/daemon/migrations/20211207035936_add-fee-to-order.sql new file mode 100644 index 0000000..c5c4114 --- /dev/null +++ b/daemon/migrations/20211207035936_add-fee-to-order.sql @@ -0,0 +1,2 @@ +-- Add migration script here +ALTER TABLE orders ADD COLUMN fee_rate not null default 1; diff --git a/daemon/sqlx-data.json b/daemon/sqlx-data.json index 84a8edf..1218a6e 100644 --- a/daemon/sqlx-data.json +++ b/daemon/sqlx-data.json @@ -1,25 +1,7 @@ { "db": "SQLite", - "221a6283db798bacaba99e7e85130f9a8bbea1299d8cb99d272b1d478dc19775": { - "query": "\n select\n state\n from cfd_states\n where cfd_id = $1\n order by id desc\n limit 1;\n ", - "describe": { - "columns": [ - { - "name": "state", - "ordinal": 0, - "type_info": "Text" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - false - ] - } - }, - "3d41b8a81df84252dae228d8512b7491416520a6ad89561f67cdfb673f864a5a": { - "query": "\n with ord as (\n select\n id as order_id,\n uuid,\n trading_pair,\n position,\n initial_price,\n min_quantity,\n max_quantity,\n leverage,\n liquidation_price,\n creation_timestamp_seconds as ts_secs,\n settlement_time_interval_seconds as settlement_time_interval_secs,\n origin,\n oracle_event_id\n from orders\n ),\n\n cfd as (\n select\n ord.order_id,\n id as cfd_id,\n quantity_usd\n from cfds\n inner join ord on ord.order_id = cfds.order_id\n ),\n\n state as (\n select\n id as state_id,\n cfd.order_id,\n cfd.quantity_usd,\n state\n from cfd_states\n inner join cfd on cfd.cfd_id = cfd_states.cfd_id\n where id in (\n select\n max(id) as id\n from cfd_states\n group by (cfd_id)\n )\n )\n\n select\n ord.uuid as \"uuid: crate::model::cfd::OrderId\",\n ord.trading_pair as \"trading_pair: crate::model::TradingPair\",\n ord.position as \"position: crate::model::Position\",\n ord.initial_price as \"initial_price: crate::model::Price\",\n ord.min_quantity as \"min_quantity: crate::model::Usd\",\n ord.max_quantity as \"max_quantity: crate::model::Usd\",\n ord.leverage as \"leverage: crate::model::Leverage\",\n ord.liquidation_price as \"liquidation_price: crate::model::Price\",\n ord.ts_secs as \"ts_secs: crate::model::Timestamp\",\n ord.settlement_time_interval_secs as \"settlement_time_interval_secs: i64\",\n ord.origin as \"origin: crate::model::cfd::Origin\",\n ord.oracle_event_id as \"oracle_event_id: crate::model::BitMexPriceEventId\",\n state.quantity_usd as \"quantity_usd: crate::model::Usd\",\n state.state\n\n from ord\n inner join state on state.order_id = ord.order_id\n ", + "047070578f79ceaa739c1b307d138ee30e3a8730c4ac357213801e23d73f2841": { + "query": "\n select\n uuid as \"uuid: crate::model::cfd::OrderId\",\n trading_pair as \"trading_pair: crate::model::TradingPair\",\n position as \"position: crate::model::Position\",\n initial_price as \"initial_price: crate::model::Price\",\n min_quantity as \"min_quantity: crate::model::Usd\",\n max_quantity as \"max_quantity: crate::model::Usd\",\n leverage as \"leverage: crate::model::Leverage\",\n liquidation_price as \"liquidation_price: crate::model::Price\",\n creation_timestamp_seconds as \"ts_secs: crate::model::Timestamp\",\n settlement_time_interval_seconds as \"settlement_time_interval_secs: i64\",\n origin as \"origin: crate::model::cfd::Origin\",\n oracle_event_id as \"oracle_event_id: crate::model::BitMexPriceEventId\",\n fee_rate as \"fee_rate: u32\"\n from\n orders\n where\n uuid = $1\n ", "describe": { "columns": [ { @@ -83,18 +65,13 @@ "type_info": "Text" }, { - "name": "quantity_usd: crate::model::Usd", + "name": "fee_rate: u32", "ordinal": 12, - "type_info": "Text" - }, - { - "name": "state", - "ordinal": 13, - "type_info": "Text" + "type_info": "Null" } ], "parameters": { - "Right": 0 + "Right": 1 }, "nullable": [ false, @@ -109,13 +86,30 @@ false, false, false, - false, false ] } }, - "414ecf7f0cfce0a1a482b1b430d960867df835aae7fe1b306aa7f22353795dcf": { - "query": "\n with ord as (\n select\n id as order_id,\n uuid,\n trading_pair,\n position,\n initial_price,\n min_quantity,\n max_quantity,\n leverage,\n liquidation_price,\n creation_timestamp_seconds as ts_secs,\n settlement_time_interval_seconds as settlement_time_interval_secs,\n origin,\n oracle_event_id\n from orders\n ),\n\n cfd as (\n select\n ord.order_id,\n id as cfd_id,\n quantity_usd\n from cfds\n inner join ord on ord.order_id = cfds.order_id\n ),\n\n state as (\n select\n id as state_id,\n cfd.order_id,\n cfd.quantity_usd,\n state\n from cfd_states\n inner join cfd on cfd.cfd_id = cfd_states.cfd_id\n where id in (\n select\n max(id) as id\n from cfd_states\n group by (cfd_id)\n )\n )\n\n select\n ord.uuid as \"uuid: crate::model::cfd::OrderId\",\n ord.trading_pair as \"trading_pair: crate::model::TradingPair\",\n ord.position as \"position: crate::model::Position\",\n ord.initial_price as \"initial_price: crate::model::Price\",\n ord.min_quantity as \"min_quantity: crate::model::Usd\",\n ord.max_quantity as \"max_quantity: crate::model::Usd\",\n ord.leverage as \"leverage: crate::model::Leverage\",\n ord.liquidation_price as \"liquidation_price: crate::model::Price\",\n ord.ts_secs as \"ts_secs: crate::model::Timestamp\",\n ord.settlement_time_interval_secs as \"settlement_time_interval_secs: i64\",\n ord.origin as \"origin: crate::model::cfd::Origin\",\n ord.oracle_event_id as \"oracle_event_id: crate::model::BitMexPriceEventId\",\n state.quantity_usd as \"quantity_usd: crate::model::Usd\",\n state.state\n\n from ord\n inner join state on state.order_id = ord.order_id\n\n where ord.uuid = $1\n ", + "221a6283db798bacaba99e7e85130f9a8bbea1299d8cb99d272b1d478dc19775": { + "query": "\n select\n state\n from cfd_states\n where cfd_id = $1\n order by id desc\n limit 1;\n ", + "describe": { + "columns": [ + { + "name": "state", + "ordinal": 0, + "type_info": "Text" + } + ], + "parameters": { + "Right": 1 + }, + "nullable": [ + false + ] + } + }, + "278833084178753ca86aa8bf9ac50fad8b6fd22dd978e2c803a8b7ba79bd5e1d": { + "query": "\n with ord as (\n select\n id as order_id,\n uuid,\n trading_pair,\n position,\n initial_price,\n min_quantity,\n max_quantity,\n leverage,\n liquidation_price,\n creation_timestamp_seconds as ts_secs,\n settlement_time_interval_seconds as settlement_time_interval_secs,\n origin,\n oracle_event_id,\n fee_rate\n from orders\n ),\n\n cfd as (\n select\n ord.order_id,\n id as cfd_id,\n quantity_usd\n from cfds\n inner join ord on ord.order_id = cfds.order_id\n ),\n\n state as (\n select\n id as state_id,\n cfd.order_id,\n cfd.quantity_usd,\n state\n from cfd_states\n inner join cfd on cfd.cfd_id = cfd_states.cfd_id\n where id in (\n select\n max(id) as id\n from cfd_states\n group by (cfd_id)\n )\n )\n\n select\n ord.uuid as \"uuid: crate::model::cfd::OrderId\",\n ord.trading_pair as \"trading_pair: crate::model::TradingPair\",\n ord.position as \"position: crate::model::Position\",\n ord.initial_price as \"initial_price: crate::model::Price\",\n ord.min_quantity as \"min_quantity: crate::model::Usd\",\n ord.max_quantity as \"max_quantity: crate::model::Usd\",\n ord.leverage as \"leverage: crate::model::Leverage\",\n ord.liquidation_price as \"liquidation_price: crate::model::Price\",\n ord.ts_secs as \"ts_secs: crate::model::Timestamp\",\n ord.settlement_time_interval_secs as \"settlement_time_interval_secs: i64\",\n ord.origin as \"origin: crate::model::cfd::Origin\",\n ord.oracle_event_id as \"oracle_event_id: crate::model::BitMexPriceEventId\",\n ord.fee_rate as \"fee_rate: u32\",\n state.quantity_usd as \"quantity_usd: crate::model::Usd\",\n state.state\n\n from ord\n inner join state on state.order_id = ord.order_id\n ", "describe": { "columns": [ { @@ -179,18 +173,23 @@ "type_info": "Text" }, { - "name": "quantity_usd: crate::model::Usd", + "name": "fee_rate: u32", "ordinal": 12, + "type_info": "Null" + }, + { + "name": "quantity_usd: crate::model::Usd", + "ordinal": 13, "type_info": "Text" }, { "name": "state", - "ordinal": 13, + "ordinal": 14, "type_info": "Text" } ], "parameters": { - "Right": 1 + "Right": 0 }, "nullable": [ false, @@ -206,12 +205,13 @@ false, false, false, + false, false ] } }, - "5569292de42c8ce5cff83beb43af1f8e6c3c12b17e740550c1303a1a6d151100": { - "query": "\n select\n uuid as \"uuid: crate::model::cfd::OrderId\",\n trading_pair as \"trading_pair: crate::model::TradingPair\",\n position as \"position: crate::model::Position\",\n initial_price as \"initial_price: crate::model::Price\",\n min_quantity as \"min_quantity: crate::model::Usd\",\n max_quantity as \"max_quantity: crate::model::Usd\",\n leverage as \"leverage: crate::model::Leverage\",\n liquidation_price as \"liquidation_price: crate::model::Price\",\n creation_timestamp_seconds as \"ts_secs: crate::model::Timestamp\",\n settlement_time_interval_seconds as \"settlement_time_interval_secs: i64\",\n origin as \"origin: crate::model::cfd::Origin\",\n oracle_event_id as \"oracle_event_id: crate::model::BitMexPriceEventId\"\n from\n orders\n where\n uuid = $1\n ", + "898c1f59733397d90d39a73e160f47ab8dc68322f5b421056ffdf38c911cac2d": { + "query": "\n with ord as (\n select\n id as order_id,\n uuid,\n trading_pair,\n position,\n initial_price,\n min_quantity,\n max_quantity,\n leverage,\n liquidation_price,\n creation_timestamp_seconds as ts_secs,\n settlement_time_interval_seconds as settlement_time_interval_secs,\n origin,\n oracle_event_id,\n fee_rate\n from orders\n ),\n\n cfd as (\n select\n ord.order_id,\n id as cfd_id,\n quantity_usd\n from cfds\n inner join ord on ord.order_id = cfds.order_id\n ),\n\n state as (\n select\n id as state_id,\n cfd.order_id,\n cfd.quantity_usd,\n state\n from cfd_states\n inner join cfd on cfd.cfd_id = cfd_states.cfd_id\n where id in (\n select\n max(id) as id\n from cfd_states\n group by (cfd_id)\n )\n )\n\n select\n ord.uuid as \"uuid: crate::model::cfd::OrderId\",\n ord.trading_pair as \"trading_pair: crate::model::TradingPair\",\n ord.position as \"position: crate::model::Position\",\n ord.initial_price as \"initial_price: crate::model::Price\",\n ord.min_quantity as \"min_quantity: crate::model::Usd\",\n ord.max_quantity as \"max_quantity: crate::model::Usd\",\n ord.leverage as \"leverage: crate::model::Leverage\",\n ord.liquidation_price as \"liquidation_price: crate::model::Price\",\n ord.ts_secs as \"ts_secs: crate::model::Timestamp\",\n ord.settlement_time_interval_secs as \"settlement_time_interval_secs: i64\",\n ord.origin as \"origin: crate::model::cfd::Origin\",\n ord.oracle_event_id as \"oracle_event_id: crate::model::BitMexPriceEventId\",\n ord.fee_rate as \"fee_rate: u32\",\n state.quantity_usd as \"quantity_usd: crate::model::Usd\",\n state.state\n\n from ord\n inner join state on state.order_id = ord.order_id\n\n where ord.oracle_event_id = $1\n ", "describe": { "columns": [ { @@ -273,6 +273,21 @@ "name": "oracle_event_id: crate::model::BitMexPriceEventId", "ordinal": 11, "type_info": "Text" + }, + { + "name": "fee_rate: u32", + "ordinal": 12, + "type_info": "Null" + }, + { + "name": "quantity_usd: crate::model::Usd", + "ordinal": 13, + "type_info": "Text" + }, + { + "name": "state", + "ordinal": 14, + "type_info": "Text" } ], "parameters": { @@ -290,6 +305,9 @@ false, false, false, + false, + false, + false, false ] } @@ -312,8 +330,8 @@ ] } }, - "f822252e3d3eb70a03300529d8de8f553e8d97b1aac72fb964cbde49d65fe153": { - "query": "\n with ord as (\n select\n id as order_id,\n uuid,\n trading_pair,\n position,\n initial_price,\n min_quantity,\n max_quantity,\n leverage,\n liquidation_price,\n creation_timestamp_seconds as ts_secs,\n settlement_time_interval_seconds as settlement_time_interval_secs,\n origin,\n oracle_event_id\n from orders\n ),\n\n cfd as (\n select\n ord.order_id,\n id as cfd_id,\n quantity_usd\n from cfds\n inner join ord on ord.order_id = cfds.order_id\n ),\n\n state as (\n select\n id as state_id,\n cfd.order_id,\n cfd.quantity_usd,\n state\n from cfd_states\n inner join cfd on cfd.cfd_id = cfd_states.cfd_id\n where id in (\n select\n max(id) as id\n from cfd_states\n group by (cfd_id)\n )\n )\n\n select\n ord.uuid as \"uuid: crate::model::cfd::OrderId\",\n ord.trading_pair as \"trading_pair: crate::model::TradingPair\",\n ord.position as \"position: crate::model::Position\",\n ord.initial_price as \"initial_price: crate::model::Price\",\n ord.min_quantity as \"min_quantity: crate::model::Usd\",\n ord.max_quantity as \"max_quantity: crate::model::Usd\",\n ord.leverage as \"leverage: crate::model::Leverage\",\n ord.liquidation_price as \"liquidation_price: crate::model::Price\",\n ord.ts_secs as \"ts_secs: crate::model::Timestamp\",\n ord.settlement_time_interval_secs as \"settlement_time_interval_secs: i64\",\n ord.origin as \"origin: crate::model::cfd::Origin\",\n ord.oracle_event_id as \"oracle_event_id: crate::model::BitMexPriceEventId\",\n state.quantity_usd as \"quantity_usd: crate::model::Usd\",\n state.state\n\n from ord\n inner join state on state.order_id = ord.order_id\n\n where ord.oracle_event_id = $1\n ", + "a6031f4720d1c6acf7043c9f9ee5035f5ffea0520220ad6b578b7ad0117ab58f": { + "query": "\n with ord as (\n select\n id as order_id,\n uuid,\n trading_pair,\n position,\n initial_price,\n min_quantity,\n max_quantity,\n leverage,\n liquidation_price,\n creation_timestamp_seconds as ts_secs,\n settlement_time_interval_seconds as settlement_time_interval_secs,\n origin,\n oracle_event_id,\n fee_rate\n from orders\n ),\n\n cfd as (\n select\n ord.order_id,\n id as cfd_id,\n quantity_usd\n from cfds\n inner join ord on ord.order_id = cfds.order_id\n ),\n\n state as (\n select\n id as state_id,\n cfd.order_id,\n cfd.quantity_usd,\n state\n from cfd_states\n inner join cfd on cfd.cfd_id = cfd_states.cfd_id\n where id in (\n select\n max(id) as id\n from cfd_states\n group by (cfd_id)\n )\n )\n\n select\n ord.uuid as \"uuid: crate::model::cfd::OrderId\",\n ord.trading_pair as \"trading_pair: crate::model::TradingPair\",\n ord.position as \"position: crate::model::Position\",\n ord.initial_price as \"initial_price: crate::model::Price\",\n ord.min_quantity as \"min_quantity: crate::model::Usd\",\n ord.max_quantity as \"max_quantity: crate::model::Usd\",\n ord.leverage as \"leverage: crate::model::Leverage\",\n ord.liquidation_price as \"liquidation_price: crate::model::Price\",\n ord.ts_secs as \"ts_secs: crate::model::Timestamp\",\n ord.settlement_time_interval_secs as \"settlement_time_interval_secs: i64\",\n ord.origin as \"origin: crate::model::cfd::Origin\",\n ord.oracle_event_id as \"oracle_event_id: crate::model::BitMexPriceEventId\",\n ord.fee_rate as \"fee_rate: u32\",\n state.quantity_usd as \"quantity_usd: crate::model::Usd\",\n state.state\n\n from ord\n inner join state on state.order_id = ord.order_id\n\n where ord.uuid = $1\n ", "describe": { "columns": [ { @@ -377,13 +395,18 @@ "type_info": "Text" }, { - "name": "quantity_usd: crate::model::Usd", + "name": "fee_rate: u32", "ordinal": 12, + "type_info": "Null" + }, + { + "name": "quantity_usd: crate::model::Usd", + "ordinal": 13, "type_info": "Text" }, { "name": "state", - "ordinal": 13, + "ordinal": 14, "type_info": "Text" } ], @@ -404,6 +427,7 @@ false, false, false, + false, false ] } diff --git a/daemon/src/db.rs b/daemon/src/db.rs index 4fe35a7..0a65cd3 100644 --- a/daemon/src/db.rs +++ b/daemon/src/db.rs @@ -25,8 +25,9 @@ pub async fn insert_order(order: &Order, conn: &mut PoolConnection) -> a creation_timestamp_seconds, settlement_time_interval_seconds, origin, - oracle_event_id - ) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)"#, + oracle_event_id, + fee_rate + ) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)"#, ) .bind(&order.id) .bind(&order.trading_pair) @@ -40,6 +41,7 @@ pub async fn insert_order(order: &Order, conn: &mut PoolConnection) -> a .bind(&order.settlement_interval.whole_seconds()) .bind(&order.origin) .bind(&order.oracle_event_id) + .bind(&order.fee_rate) .execute(conn) .await?; @@ -68,7 +70,8 @@ pub async fn load_order_by_id( creation_timestamp_seconds as "ts_secs: crate::model::Timestamp", settlement_time_interval_seconds as "settlement_time_interval_secs: i64", origin as "origin: crate::model::cfd::Origin", - oracle_event_id as "oracle_event_id: crate::model::BitMexPriceEventId" + oracle_event_id as "oracle_event_id: crate::model::BitMexPriceEventId", + fee_rate as "fee_rate: u32" from orders where @@ -92,6 +95,7 @@ pub async fn load_order_by_id( settlement_interval: Duration::new(row.settlement_time_interval_secs, 0), origin: row.origin, oracle_event_id: row.oracle_event_id, + fee_rate: row.fee_rate, }) } @@ -241,7 +245,8 @@ pub async fn load_cfd_by_order_id( creation_timestamp_seconds as ts_secs, settlement_time_interval_seconds as settlement_time_interval_secs, origin, - oracle_event_id + oracle_event_id, + fee_rate from orders ), @@ -283,6 +288,7 @@ pub async fn load_cfd_by_order_id( ord.settlement_time_interval_secs as "settlement_time_interval_secs: i64", ord.origin as "origin: crate::model::cfd::Origin", ord.oracle_event_id as "oracle_event_id: crate::model::BitMexPriceEventId", + ord.fee_rate as "fee_rate: u32", state.quantity_usd as "quantity_usd: crate::model::Usd", state.state @@ -309,6 +315,7 @@ pub async fn load_cfd_by_order_id( settlement_interval: Duration::new(row.settlement_time_interval_secs, 0), origin: row.origin, oracle_event_id: row.oracle_event_id, + fee_rate: row.fee_rate, }; // TODO: @@ -339,7 +346,8 @@ pub async fn load_all_cfds(conn: &mut PoolConnection) -> anyhow::Result< creation_timestamp_seconds as ts_secs, settlement_time_interval_seconds as settlement_time_interval_secs, origin, - oracle_event_id + oracle_event_id, + fee_rate from orders ), @@ -381,6 +389,7 @@ pub async fn load_all_cfds(conn: &mut PoolConnection) -> anyhow::Result< ord.settlement_time_interval_secs as "settlement_time_interval_secs: i64", ord.origin as "origin: crate::model::cfd::Origin", ord.oracle_event_id as "oracle_event_id: crate::model::BitMexPriceEventId", + ord.fee_rate as "fee_rate: u32", state.quantity_usd as "quantity_usd: crate::model::Usd", state.state @@ -407,6 +416,7 @@ pub async fn load_all_cfds(conn: &mut PoolConnection) -> anyhow::Result< settlement_interval: Duration::new(row.settlement_time_interval_secs, 0), origin: row.origin, oracle_event_id: row.oracle_event_id, + fee_rate: row.fee_rate, }; Ok(Cfd { @@ -442,7 +452,8 @@ pub async fn load_cfds_by_oracle_event_id( creation_timestamp_seconds as ts_secs, settlement_time_interval_seconds as settlement_time_interval_secs, origin, - oracle_event_id + oracle_event_id, + fee_rate from orders ), @@ -484,6 +495,7 @@ pub async fn load_cfds_by_oracle_event_id( ord.settlement_time_interval_secs as "settlement_time_interval_secs: i64", ord.origin as "origin: crate::model::cfd::Origin", ord.oracle_event_id as "oracle_event_id: crate::model::BitMexPriceEventId", + ord.fee_rate as "fee_rate: u32", state.quantity_usd as "quantity_usd: crate::model::Usd", state.state @@ -513,6 +525,7 @@ pub async fn load_cfds_by_oracle_event_id( settlement_interval: Duration::new(row.settlement_time_interval_secs, 0), origin: row.origin, oracle_event_id: row.oracle_event_id, + fee_rate: row.fee_rate, }; Ok(Cfd { @@ -770,6 +783,7 @@ mod tests { Origin::Theirs, BitMexPriceEventId::with_20_digits(OffsetDateTime::now_utc()), time::Duration::hours(24), + 1, ) .unwrap() } diff --git a/daemon/src/maker_cfd.rs b/daemon/src/maker_cfd.rs index 500dadb..fc5ac7a 100644 --- a/daemon/src/maker_cfd.rs +++ b/daemon/src/maker_cfd.rs @@ -58,6 +58,7 @@ pub struct NewOrder { pub price: Price, pub min_quantity: Usd, pub max_quantity: Usd, + pub fee_rate: u32, } pub struct TakerConnected { @@ -739,6 +740,7 @@ where cfd.quantity_usd, cfd.order.leverage, cfd.refund_timelock_in_blocks(), + cfd.order.fee_rate, ), Role::Maker, dlc, @@ -908,6 +910,7 @@ where price, min_quantity, max_quantity, + fee_rate, } = msg; let oracle_event_id = oracle::next_announcement_after( @@ -921,6 +924,7 @@ where Origin::Ours, oracle_event_id, self.settlement_interval, + fee_rate, )?; // 1. Save to DB diff --git a/daemon/src/model/cfd.rs b/daemon/src/model/cfd.rs index 6efa89b..67d72e9 100644 --- a/daemon/src/model/cfd.rs +++ b/daemon/src/model/cfd.rs @@ -123,6 +123,8 @@ pub struct Order { /// /// The maker includes this into the Order based on the Oracle announcement to be used. pub oracle_event_id: BitMexPriceEventId, + + pub fee_rate: u32, } impl Order { @@ -133,6 +135,7 @@ impl Order { origin: Origin, oracle_event_id: BitMexPriceEventId, settlement_interval: Duration, + fee_rate: u32, ) -> Result { let leverage = Leverage::new(2)?; let liquidation_price = calculate_long_liquidation_price(leverage, price); @@ -150,6 +153,7 @@ impl Order { settlement_interval, origin, oracle_event_id, + fee_rate, }) } } diff --git a/daemon/src/rollover_taker.rs b/daemon/src/rollover_taker.rs index 36744be..d51f5b2 100644 --- a/daemon/src/rollover_taker.rs +++ b/daemon/src/rollover_taker.rs @@ -108,6 +108,7 @@ impl Actor { self.cfd.quantity_usd, self.cfd.order.leverage, self.cfd.refund_timelock_in_blocks(), + self.cfd.order.fee_rate, ), Role::Taker, self.cfd.dlc().context("No DLC in CFD")?, diff --git a/daemon/src/routes_maker.rs b/daemon/src/routes_maker.rs index fcb1292..bcd86ff 100644 --- a/daemon/src/routes_maker.rs +++ b/daemon/src/routes_maker.rs @@ -91,6 +91,7 @@ pub struct CfdNewOrderRequest { // always 1 USD pub min_quantity: Usd, pub max_quantity: Usd, + pub fee_rate: Option, } #[rocket::post("/order/sell", data = "")] @@ -104,6 +105,7 @@ pub async fn post_sell_order( price: order.price, min_quantity: order.min_quantity, max_quantity: order.max_quantity, + fee_rate: order.fee_rate.unwrap_or(1), }) .await .unwrap_or_else(|e| anyhow::bail!(e)) diff --git a/daemon/src/setup_contract.rs b/daemon/src/setup_contract.rs index 176d57b..70c91a9 100644 --- a/daemon/src/setup_contract.rs +++ b/daemon/src/setup_contract.rs @@ -33,6 +33,7 @@ pub struct SetupParams { quantity: Usd, leverage: Leverage, refund_timelock: u32, + fee_rate: u32, } impl SetupParams { @@ -43,6 +44,7 @@ impl SetupParams { quantity: Usd, leverage: Leverage, refund_timelock: u32, + fee_rate: u32, ) -> Self { Self { margin, @@ -51,6 +53,7 @@ impl SetupParams { quantity, leverage, refund_timelock, + fee_rate, } } } @@ -76,6 +79,7 @@ pub async fn new( .send(wallet::BuildPartyParams { amount: setup_params.margin, identity_pk: pk, + fee_rate: setup_params.fee_rate, }) .await .context("Failed to send message to wallet actor")? @@ -129,6 +133,7 @@ pub async fn new( (model::cfd::Cfd::CET_TIMELOCK, setup_params.refund_timelock), payouts, sk, + setup_params.fee_rate, ) .context("Failed to create CFD transactions")?; @@ -312,15 +317,23 @@ pub struct RolloverParams { quantity: Usd, leverage: Leverage, refund_timelock: u32, + fee_rate: u32, } impl RolloverParams { - pub fn new(price: Price, quantity: Usd, leverage: Leverage, refund_timelock: u32) -> Self { + pub fn new( + price: Price, + quantity: Usd, + leverage: Leverage, + refund_timelock: u32, + fee_rate: u32, + ) -> Self { Self { price, quantity, leverage, refund_timelock, + fee_rate, } } } @@ -419,6 +432,7 @@ pub async fn roll_over( ), payouts, sk, + rollover_params.fee_rate, ) .context("Failed to create new CFD transactions")?; diff --git a/daemon/src/setup_maker.rs b/daemon/src/setup_maker.rs index b66a70e..a218e1a 100644 --- a/daemon/src/setup_maker.rs +++ b/daemon/src/setup_maker.rs @@ -94,6 +94,7 @@ impl Actor { cfd.quantity_usd, cfd.order.leverage, cfd.refund_timelock_in_blocks(), + cfd.order.fee_rate, ), self.build_party_params.clone_channel(), self.sign.clone_channel(), diff --git a/daemon/src/setup_taker.rs b/daemon/src/setup_taker.rs index 0065563..6a327e7 100644 --- a/daemon/src/setup_taker.rs +++ b/daemon/src/setup_taker.rs @@ -86,6 +86,7 @@ impl Actor { cfd.quantity_usd, cfd.order.leverage, cfd.refund_timelock_in_blocks(), + cfd.order.fee_rate, ), self.build_party_params.clone_channel(), self.sign.clone_channel(), diff --git a/daemon/src/wallet.rs b/daemon/src/wallet.rs index 13ad71c..3eb1849 100644 --- a/daemon/src/wallet.rs +++ b/daemon/src/wallet.rs @@ -152,9 +152,14 @@ impl Actor { BuildPartyParams { amount, identity_pk, + fee_rate, }: BuildPartyParams, ) -> Result { - let psbt = self.wallet.build_lock_tx(amount, &mut self.used_utxos)?; + let psbt = self.wallet.build_lock_tx( + amount, + &mut self.used_utxos, + FeeRate::from_sat_per_vb(fee_rate as f32), + )?; Ok(PartyParams { lock_psbt: psbt, @@ -265,6 +270,7 @@ impl xtra::Actor for Actor { pub struct BuildPartyParams { pub amount: Amount, pub identity_pk: PublicKey, + pub fee_rate: u32, } /// Private message to trigger a sync. @@ -325,6 +331,7 @@ trait BuildLockTx { &mut self, amount: Amount, used_utxos: &mut HashSet, + fee_rate: FeeRate, ) -> Result; } @@ -336,12 +343,13 @@ where &mut self, amount: Amount, used_utxos: &mut HashSet, + fee_rate: FeeRate, ) -> Result { let mut builder = self.build_tx(); builder .ordering(TxOrdering::Bip69Lexicographic) // TODO: I think this is pointless but we did this in maia. - .fee_rate(FeeRate::from_sat_per_vb(1.0)) + .fee_rate(fee_rate) .unspendable(used_utxos.iter().copied().collect()) .add_2of2_multisig_recipient(amount); @@ -381,10 +389,18 @@ mod tests { let mut used_utxos = HashSet::new(); let lock_tx_1 = wallet - .build_lock_tx(Amount::from_sat(2500), &mut used_utxos) + .build_lock_tx( + Amount::from_sat(2500), + &mut used_utxos, + FeeRate::default_min_relay_fee(), + ) .unwrap(); let lock_tx_2 = wallet - .build_lock_tx(Amount::from_sat(2500), &mut used_utxos) + .build_lock_tx( + Amount::from_sat(2500), + &mut used_utxos, + FeeRate::default_min_relay_fee(), + ) .unwrap(); let mut utxos_in_transaction = HashSet::new(); diff --git a/daemon/tests/harness/mod.rs b/daemon/tests/harness/mod.rs index a1cc76f..69d9334 100644 --- a/daemon/tests/harness/mod.rs +++ b/daemon/tests/harness/mod.rs @@ -403,6 +403,7 @@ pub fn dummy_new_order() -> maker_cfd::NewOrder { price: dummy_price(), min_quantity: Usd::new(dec!(5)), max_quantity: Usd::new(dec!(100)), + fee_rate: 1, } }