From 2888654d8d1dfeec9162a26ae63c1c5096b243c3 Mon Sep 17 00:00:00 2001 From: shamardy Date: Wed, 11 Jan 2023 17:30:30 +0200 Subject: [PATCH 1/2] use avg_blocktime from platform coin for l2/lightning --- mm2src/coins/lightning.rs | 5 +++- mm2src/coins/lightning/ln_conf.rs | 1 - mm2src/coins/lightning/ln_platform.rs | 13 +++++++--- mm2src/coins/lp_coins.rs | 1 - mm2src/coins/utxo.rs | 2 ++ .../utxo/utxo_builder/utxo_conf_builder.rs | 4 +++ mm2src/coins/utxo/utxo_common_tests.rs | 1 + .../coins_activation/src/l2/init_l2_error.rs | 6 +++++ .../src/lightning_activation.rs | 25 ++++++++++++++++--- .../tests/mm2_tests/lightning_tests.rs | 6 ++--- 10 files changed, 51 insertions(+), 13 deletions(-) diff --git a/mm2src/coins/lightning.rs b/mm2src/coins/lightning.rs index 33b4419dd0..1161232d0f 100644 --- a/mm2src/coins/lightning.rs +++ b/mm2src/coins/lightning.rs @@ -153,6 +153,9 @@ impl Transaction for PaymentHash { impl LightningCoin { pub fn platform_coin(&self) -> &UtxoStandardCoin { &self.platform.coin } + #[inline] + fn avg_blocktime(&self) -> u64 { self.platform.avg_blocktime } + #[inline] fn my_node_id(&self) -> String { self.channel_manager.get_our_node_id().to_string() } @@ -479,7 +482,7 @@ impl LightningCoin { } } - fn estimate_blocks_from_duration(&self, duration: u64) -> u64 { duration / self.platform.avg_block_time } + fn estimate_blocks_from_duration(&self, duration: u64) -> u64 { duration / self.avg_blocktime() } async fn swap_payment_instructions( &self, diff --git a/mm2src/coins/lightning/ln_conf.rs b/mm2src/coins/lightning/ln_conf.rs index 7800dcb43c..dd58946969 100644 --- a/mm2src/coins/lightning/ln_conf.rs +++ b/mm2src/coins/lightning/ln_conf.rs @@ -12,7 +12,6 @@ pub struct PlatformCoinConfirmationTargets { pub struct LightningProtocolConf { pub platform_coin_ticker: String, pub network: BlockchainNetwork, - pub avg_block_time: u64, pub confirmation_targets: PlatformCoinConfirmationTargets, } diff --git a/mm2src/coins/lightning/ln_platform.rs b/mm2src/coins/lightning/ln_platform.rs index 0d8a55f1c6..8023138863 100644 --- a/mm2src/coins/lightning/ln_platform.rs +++ b/mm2src/coins/lightning/ln_platform.rs @@ -156,7 +156,7 @@ pub struct Platform { /// Main/testnet/signet/regtest Needed for lightning node to know which network to connect to pub network: BlockchainNetwork, /// The average time in seconds needed to mine a new block for the blockchain network. - pub avg_block_time: u64, + pub avg_blocktime: u64, /// The best block height. pub best_block_height: AtomicU64, /// Number of blocks for every Confirmation target. This is used in the FeeEstimator. @@ -179,9 +179,16 @@ impl Platform { pub fn new( coin: UtxoStandardCoin, network: BlockchainNetwork, - avg_block_time: u64, confirmations_targets: PlatformCoinConfirmationTargets, ) -> EnableLightningResult { + // This should never return an error since it's validated that avg_blocktime is in platform coin config in a previous step of lightning activation. + // But an error is returned here just in case. + let avg_blocktime = coin + .as_ref() + .conf + .avg_blocktime + .ok_or_else(|| EnableLightningError::Internal("`avg_blocktime` can't be None!".into()))?; + // Create an abortable system linked to the base `coin` so if the base coin is disabled, // all spawned futures related to `LightCoin` will be aborted as well. let abortable_system = coin.as_ref().abortable_system.create_subsystem()?; @@ -189,7 +196,7 @@ impl Platform { Ok(Platform { coin, network, - avg_block_time, + avg_blocktime, best_block_height: AtomicU64::new(0), confirmations_targets, latest_fees: LatestFees { diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index dde804ae7b..883c828dc2 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -2473,7 +2473,6 @@ pub enum CoinProtocol { LIGHTNING { platform: String, network: BlockchainNetwork, - avg_block_time: u64, confirmation_targets: PlatformCoinConfirmationTargets, }, #[cfg(not(target_arch = "wasm32"))] diff --git a/mm2src/coins/utxo.rs b/mm2src/coins/utxo.rs index 5354af3977..d47af611ad 100644 --- a/mm2src/coins/utxo.rs +++ b/mm2src/coins/utxo.rs @@ -562,6 +562,8 @@ pub struct UtxoCoinConf { /// where the full `BIP44` address has the following structure: /// `m/purpose'/coin_type'/account'/change/address_index`. pub derivation_path: Option, + /// The average time in seconds needed to mine a new block for this coin. + pub avg_blocktime: Option, } pub struct UtxoCoinFields { diff --git a/mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs b/mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs index f341b8df74..cab1b72948 100644 --- a/mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs +++ b/mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs @@ -89,6 +89,7 @@ impl<'a> UtxoConfBuilder<'a> { let enable_spv_proof = self.enable_spv_proof(); let block_headers_verification_params = self.block_headers_verification_params(); let derivation_path = self.derivation_path()?; + let avg_blocktime = self.avg_blocktime(); Ok(UtxoCoinConf { ticker: self.ticker.to_owned(), @@ -123,6 +124,7 @@ impl<'a> UtxoConfBuilder<'a> { enable_spv_proof, block_headers_verification_params, derivation_path, + avg_blocktime, }) } @@ -293,4 +295,6 @@ impl<'a> UtxoConfBuilder<'a> { json::from_value(self.conf["derivation_path"].clone()) .map_to_mm(|e| UtxoConfError::ErrorDeserializingDerivationPath(e.to_string())) } + + fn avg_blocktime(&self) -> Option { self.conf["avg_blocktime"].as_u64() } } diff --git a/mm2src/coins/utxo/utxo_common_tests.rs b/mm2src/coins/utxo/utxo_common_tests.rs index dc2783fd58..7144d378a6 100644 --- a/mm2src/coins/utxo/utxo_common_tests.rs +++ b/mm2src/coins/utxo/utxo_common_tests.rs @@ -123,6 +123,7 @@ pub(super) fn utxo_coin_fields_for_test( enable_spv_proof: false, block_headers_verification_params: None, derivation_path: None, + avg_blocktime: None, }, decimals: TEST_COIN_DECIMALS, dust_amount: UTXO_DUST_AMOUNT, diff --git a/mm2src/coins_activation/src/l2/init_l2_error.rs b/mm2src/coins_activation/src/l2/init_l2_error.rs index f39f333377..d23fd73078 100644 --- a/mm2src/coins_activation/src/l2/init_l2_error.rs +++ b/mm2src/coins_activation/src/l2/init_l2_error.rs @@ -36,6 +36,11 @@ pub enum InitL2Error { platform_coin_ticker: String, l2_ticker: String, }, + #[display(fmt = "Invalid config for platform coin: {}, error: {}", platform_coin_ticker, err)] + InvalidPlatformConfiguration { + platform_coin_ticker: String, + err: String, + }, #[display(fmt = "Layer 2 configuration parsing failed: {}", _0)] L2ConfigParseError(String), #[display(fmt = "Initialization task has timed out {:?}", duration)] @@ -80,6 +85,7 @@ impl HttpStatusCode for InitL2Error { InitL2Error::TaskTimedOut { .. } => StatusCode::REQUEST_TIMEOUT, InitL2Error::L2ProtocolParseError { .. } | InitL2Error::UnsupportedPlatformCoin { .. } + | InitL2Error::InvalidPlatformConfiguration { .. } | InitL2Error::L2ConfigParseError(_) | InitL2Error::Transport(_) | InitL2Error::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR, diff --git a/mm2src/coins_activation/src/lightning_activation.rs b/mm2src/coins_activation/src/lightning_activation.rs index 20fd4bc3a7..80f3ec41b8 100644 --- a/mm2src/coins_activation/src/lightning_activation.rs +++ b/mm2src/coins_activation/src/lightning_activation.rs @@ -83,12 +83,10 @@ impl TryFromCoinProtocol for LightningProtocolConf { CoinProtocol::LIGHTNING { platform, network, - avg_block_time, confirmation_targets, } => Ok(LightningProtocolConf { platform_coin_ticker: platform, network, - avg_block_time, confirmation_targets, }), proto => MmError::err(proto), @@ -153,8 +151,15 @@ pub struct LightningActivationResult { #[derive(Clone, Debug, Display, Serialize, SerializeErrorType)] #[serde(tag = "error_type", content = "error_data")] pub enum LightningInitError { - CoinIsAlreadyActivated { ticker: String }, + CoinIsAlreadyActivated { + ticker: String, + }, InvalidConfiguration(String), + #[display(fmt = "Error while validating {} configuration: {}", platform_coin_ticker, err)] + InvalidPlatformConfiguration { + platform_coin_ticker: String, + err: String, + }, EnableLightningError(EnableLightningError), LightningValidationErr(LightningValidationErr), MyBalanceError(BalanceError), @@ -171,6 +176,13 @@ impl From for InitL2Error { match err { LightningInitError::CoinIsAlreadyActivated { ticker } => InitL2Error::L2IsAlreadyActivated(ticker), LightningInitError::InvalidConfiguration(err) => InitL2Error::L2ConfigParseError(err), + LightningInitError::InvalidPlatformConfiguration { + platform_coin_ticker, + err, + } => InitL2Error::InvalidPlatformConfiguration { + platform_coin_ticker, + err, + }, LightningInitError::EnableLightningError(enable_err) => match enable_err { EnableLightningError::RpcError(rpc_err) => InitL2Error::Transport(rpc_err), enable_error => InitL2Error::Internal(enable_error.to_string()), @@ -238,6 +250,12 @@ impl InitL2ActivationOps for LightningCoin { LightningValidationErr::UnsupportedMode("Lightning network".into(), "segwit".into()).into(), ); } + if platform_coin.as_ref().conf.avg_blocktime.is_none() { + return MmError::err(LightningInitError::InvalidPlatformConfiguration { + platform_coin_ticker: platform_coin.ticker().to_string(), + err: "'avg_blocktime' field is not found in platform coin config".into(), + }); + } Ok(()) } @@ -323,7 +341,6 @@ async fn start_lightning( let platform = Arc::new(Platform::new( platform_coin.clone(), protocol_conf.network.clone(), - protocol_conf.avg_block_time, protocol_conf.confirmation_targets, )?); task_handle.update_in_progress_status(LightningInProgressStatus::GettingFeesFromRPC)?; diff --git a/mm2src/mm2_main/tests/mm2_tests/lightning_tests.rs b/mm2src/mm2_main/tests/mm2_tests/lightning_tests.rs index 4e7feab605..65eaedad14 100644 --- a/mm2src/mm2_main/tests/mm2_tests/lightning_tests.rs +++ b/mm2src/mm2_main/tests/mm2_tests/lightning_tests.rs @@ -61,6 +61,7 @@ fn start_lightning_nodes(enable_0_confs: bool) -> (MarketMakerIt, MarketMakerIt, "estimate_fee_mode": "ECONOMICAL", "mm2": 1, "required_confirmations": 0, + "avg_blocktime": 600, "protocol": { "type": "UTXO" } @@ -84,7 +85,6 @@ fn start_lightning_nodes(enable_0_confs: bool) -> (MarketMakerIt, MarketMakerIt, "protocol_data":{ "platform": "tBTC-TEST-segwit", "network": "testnet", - "avg_block_time": 600, "confirmation_targets": { "background": 12, "normal": 6, @@ -170,6 +170,7 @@ fn test_enable_lightning() { "estimate_fee_mode": "ECONOMICAL", "mm2": 1, "required_confirmations": 0, + "avg_blocktime": 600, "protocol": { "type": "UTXO" } @@ -183,7 +184,6 @@ fn test_enable_lightning() { "protocol_data":{ "platform": "tBTC-TEST-segwit", "network": "testnet", - "avg_block_time": 600, "confirmation_targets": { "background": 12, "normal": 6, @@ -744,6 +744,7 @@ fn test_sign_verify_message_lightning() { "estimate_fee_mode": "ECONOMICAL", "mm2": 1, "required_confirmations": 0, + "avg_blocktime": 600, "protocol": { "type": "UTXO" } @@ -758,7 +759,6 @@ fn test_sign_verify_message_lightning() { "protocol_data":{ "platform": "tBTC-TEST-segwit", "network": "testnet", - "avg_block_time": 600, "confirmation_targets": { "background": 12, "normal": 6, From 9fd1d4559106cb9b3c26fa34882fef6d2522c5b6 Mon Sep 17 00:00:00 2001 From: shamardy Date: Wed, 11 Jan 2023 18:29:30 +0200 Subject: [PATCH 2/2] make avg_blocktime a const in lightning_tests --- mm2src/mm2_main/tests/mm2_tests/lightning_tests.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mm2src/mm2_main/tests/mm2_tests/lightning_tests.rs b/mm2src/mm2_main/tests/mm2_tests/lightning_tests.rs index 65eaedad14..37267133b3 100644 --- a/mm2src/mm2_main/tests/mm2_tests/lightning_tests.rs +++ b/mm2src/mm2_main/tests/mm2_tests/lightning_tests.rs @@ -13,6 +13,7 @@ use serde_json::{self as json, json, Value as Json}; use std::env; use std::str::FromStr; +const BTC_AVG_BLOCKTIME: u64 = 600; const T_BTC_ELECTRUMS: &[&str] = &[ "electrum1.cipig.net:10068", "electrum2.cipig.net:10068", @@ -61,7 +62,7 @@ fn start_lightning_nodes(enable_0_confs: bool) -> (MarketMakerIt, MarketMakerIt, "estimate_fee_mode": "ECONOMICAL", "mm2": 1, "required_confirmations": 0, - "avg_blocktime": 600, + "avg_blocktime": BTC_AVG_BLOCKTIME, "protocol": { "type": "UTXO" } @@ -170,7 +171,7 @@ fn test_enable_lightning() { "estimate_fee_mode": "ECONOMICAL", "mm2": 1, "required_confirmations": 0, - "avg_blocktime": 600, + "avg_blocktime": BTC_AVG_BLOCKTIME, "protocol": { "type": "UTXO" } @@ -744,7 +745,7 @@ fn test_sign_verify_message_lightning() { "estimate_fee_mode": "ECONOMICAL", "mm2": 1, "required_confirmations": 0, - "avg_blocktime": 600, + "avg_blocktime": BTC_AVG_BLOCKTIME, "protocol": { "type": "UTXO" }