Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into taker-failed-swaps-mar…
Browse files Browse the repository at this point in the history
…ked-successful
  • Loading branch information
laruh committed Sep 26, 2024
2 parents b50b2a3 + 7ef08e4 commit 6fa527a
Show file tree
Hide file tree
Showing 44 changed files with 1,984 additions and 1,869 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ opt-level = 3
strip = true
codegen-units = 1
# lto = true
panic = "abort"
panic = 'unwind'

[profile.dev]
opt-level = 0
Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@

## What is the Komodo DeFi Framework?

The Komodo DeFi Framework is open-source [atomic-swap](https://komodoplatform.com/en/academy/atomic-swaps/) software for seamless, decentralised, peer to peer trading between almost every blockchain asset in existence. This software works with propagation of orderbooks and swap states through the [libp2p](https://libp2p.io/) protocol and uses [Hash Time Lock Contracts (HTLCs)](https://en.bitcoinwiki.org/wiki/Hashed_Timelock_Contracts) for ensuring that the two parties in a swap either mutually complete a trade, or funds return to thier original owner.
The Komodo DeFi Framework is open-source [atomic-swap](https://komodoplatform.com/en/academy/atomic-swaps/) software for seamless, decentralized, peer to peer trading between almost every blockchain asset in existence. This software works with propagation of orderbooks and swap states through the [libp2p](https://libp2p.io/) protocol and uses [Hash Time Lock Contracts (HTLCs)](https://en.bitcoinwiki.org/wiki/Hashed_Timelock_Contracts) for ensuring that the two parties in a swap either mutually complete a trade, or funds return to thier original owner.

There is no 3rd party intermediary, no proxy tokens, and at all times users remain in sole possession of their private keys.

Expand Down Expand Up @@ -172,7 +172,7 @@ Refer to the [Komodo Developer Docs](https://developers.komodoplatform.com/basic

## Project structure

[mm2src](mm2src) - Rust code, contains some parts ported from C `as is` (e.g. `lp_ordermatch`) to reach the most essential/error prone code. Some other modules/crates are reimplemented from scratch.
[mm2src](mm2src) - Rust code, contains some parts ported from C `as is` (e.g. `lp_ordermatch`) to reach the most essential/error-prone code. Some other modules/crates are reimplemented from scratch.


## Additional docs for developers
Expand All @@ -185,12 +185,13 @@ Refer to the [Komodo Developer Docs](https://developers.komodoplatform.com/basic

## Disclaimer

This repository contains the `work in progress` code of the brand new Komodo DeFi Framework (kdf) built mainly on Rust.
The current state can be considered as a alpha version.
This repository contains the `work in progress` code of the brand-new Komodo DeFi Framework (kdf) built mainly on Rust.
The current state can be considered as an alpha version.

**<b>WARNING: Use with test coins only or with assets which value does not exceed an amount you are willing to lose. This is alpha stage software! </b>**


## Help and troubleshooting

If you have any question/want to report a bug/suggest an improvement feel free to [open an issue](https://github.com/artemii235/SuperNET/issues/new) or join the [Komodo Platform Discord](https://discord.gg/PGxVm2y) `dev-marketmaker` channel.
If you have any question/want to report a bug/suggest an improvement feel free to [open an issue](https://github.com/KomodoPlatform/komodo-defi-framework/issues/new/choose) or join the [Komodo Platform Discord](https://discord.gg/PGxVm2y) `dev-marketmaker` channel.

4 changes: 4 additions & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[[disallowed-methods]]
path = "futures::future::Future::wait"
replacement = "common::block_on_f01"
reason = "Use the default KDF async executor."
110 changes: 67 additions & 43 deletions mm2src/coins/eth/eth_tests.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
use super::*;
use crate::eth::for_tests::{eth_coin_for_test, eth_coin_from_keypair};
use crate::{DexFee, IguanaPrivKey};
use common::{block_on, now_sec};
#[cfg(not(target_arch = "wasm32"))]
use ethkey::{Generator, Random};
use crate::IguanaPrivKey;
use common::{block_on, block_on_f01};
use mm2_core::mm_ctx::MmCtxBuilder;
use mm2_test_helpers::for_tests::{ETH_MAINNET_CHAIN_ID, ETH_MAINNET_NODE, ETH_SEPOLIA_CHAIN_ID, ETH_SEPOLIA_NODES,

cfg_native!(
use crate::eth::for_tests::{eth_coin_for_test, eth_coin_from_keypair};
use crate::DexFee;

use common::now_sec;
use ethkey::{Generator, Random};
use mm2_test_helpers::for_tests::{ETH_MAINNET_CHAIN_ID, ETH_MAINNET_NODE, ETH_SEPOLIA_CHAIN_ID, ETH_SEPOLIA_NODES,
ETH_SEPOLIA_TOKEN_CONTRACT};
use mocktopus::mocking::*;

/// The gas price for the tests
const GAS_PRICE: u64 = 50_000_000_000;
// `GAS_PRICE` increased by 3%
const GAS_PRICE_APPROXIMATION_ON_START_SWAP: u64 = 51_500_000_000;
// `GAS_PRICE` increased by 5%
const GAS_PRICE_APPROXIMATION_ON_ORDER_ISSUE: u64 = 52_500_000_000;
// `GAS_PRICE` increased by 7%
const GAS_PRICE_APPROXIMATION_ON_TRADE_PREIMAGE: u64 = 53_500_000_000;
use mocktopus::mocking::*;

/// The gas price for the tests
const GAS_PRICE: u64 = 50_000_000_000;
/// `GAS_PRICE` increased by 3%
const GAS_PRICE_APPROXIMATION_ON_START_SWAP: u64 = 51_500_000_000;
/// `GAS_PRICE` increased by 5%
const GAS_PRICE_APPROXIMATION_ON_ORDER_ISSUE: u64 = 52_500_000_000;
/// `GAS_PRICE` increased by 7%
const GAS_PRICE_APPROXIMATION_ON_TRADE_PREIMAGE: u64 = 53_500_000_000;
);

// old way to add some extra gas to the returned value from gas station (non-existent now), still used in tests
const GAS_PRICE_PERCENT: u64 = 10;

const TAKER_PAYMENT_SPEND_SEARCH_INTERVAL: f64 = 1.;

fn check_sum(addr: &str, expected: &str) {
let actual = checksum_address(addr);
assert_eq!(expected, actual);
Expand Down Expand Up @@ -154,8 +158,11 @@ fn test_wei_from_big_decimal() {
assert_eq!(expected_wei, wei);
}

#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_wait_for_payment_spend_timeout() {
const TAKER_PAYMENT_SPEND_SEARCH_INTERVAL: f64 = 1.;

EthCoin::spend_events.mock_safe(|_, _, _, _| MockResult::Return(Box::new(futures01::future::ok(vec![]))));
EthCoin::current_block.mock_safe(|_| MockResult::Return(Box::new(futures01::future::ok(900))));

Expand Down Expand Up @@ -184,18 +191,16 @@ fn test_wait_for_payment_spend_timeout() {
184, 42, 106,
];

assert!(coin
.wait_for_htlc_tx_spend(WaitForHTLCTxSpendArgs {
tx_bytes: &tx_bytes,
secret_hash: &[],
wait_until,
from_block,
swap_contract_address: &coin.swap_contract_address(),
check_every: TAKER_PAYMENT_SPEND_SEARCH_INTERVAL,
watcher_reward: false
})
.wait()
.is_err());
assert!(block_on_f01(coin.wait_for_htlc_tx_spend(WaitForHTLCTxSpendArgs {
tx_bytes: &tx_bytes,
secret_hash: &[],
wait_until,
from_block,
swap_contract_address: &coin.swap_contract_address(),
check_every: TAKER_PAYMENT_SPEND_SEARCH_INTERVAL,
watcher_reward: false
}))
.is_err());
}

#[cfg(not(target_arch = "wasm32"))]
Expand All @@ -222,7 +227,7 @@ fn test_withdraw_impl_manual_fee() {
memo: None,
ibc_source_channel: None,
};
coin.get_balance().wait().unwrap();
block_on_f01(coin.get_balance()).unwrap();

let tx_details = block_on(withdraw_impl(coin, withdraw_req)).unwrap();
let expected = Some(
Expand Down Expand Up @@ -271,7 +276,7 @@ fn test_withdraw_impl_fee_details() {
memo: None,
ibc_source_channel: None,
};
coin.get_balance().wait().unwrap();
block_on_f01(coin.get_balance()).unwrap();

let tx_details = block_on(withdraw_impl(coin, withdraw_req)).unwrap();
let expected = Some(
Expand Down Expand Up @@ -306,6 +311,7 @@ fn test_add_ten_pct_one_gwei() {
assert_eq!(expected, actual);
}

#[cfg(not(target_arch = "wasm32"))]
#[test]
fn get_sender_trade_preimage() {
/// Trade fee for the ETH coin is `2 * 150_000 * gas_price` always.
Expand Down Expand Up @@ -361,6 +367,7 @@ fn get_sender_trade_preimage() {
assert_eq!(actual, expected);
}

#[cfg(not(target_arch = "wasm32"))]
#[test]
fn get_erc20_sender_trade_preimage() {
const APPROVE_GAS_LIMIT: u64 = 60_000;
Expand Down Expand Up @@ -463,6 +470,7 @@ fn get_erc20_sender_trade_preimage() {
);
}

#[cfg(not(target_arch = "wasm32"))]
#[test]
fn get_receiver_trade_preimage() {
EthCoin::get_gas_price.mock_safe(|_| MockResult::Return(Box::pin(futures::future::ok(GAS_PRICE.into()))));
Expand All @@ -476,13 +484,12 @@ fn get_receiver_trade_preimage() {
paid_from_trading_vol: false,
};

let actual = coin
.get_receiver_trade_fee(FeeApproxStage::WithoutApprox)
.wait()
.expect("!get_sender_trade_fee");
let actual =
block_on_f01(coin.get_receiver_trade_fee(FeeApproxStage::WithoutApprox)).expect("!get_sender_trade_fee");
assert_eq!(actual, expected_fee);
}

#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_get_fee_to_send_taker_fee() {
const DEX_FEE_AMOUNT: u64 = 100_000;
Expand Down Expand Up @@ -533,6 +540,7 @@ fn test_get_fee_to_send_taker_fee() {
///
/// Please note this test doesn't work correctly now,
/// because as of now [`EthCoin::get_fee_to_send_taker_fee`] doesn't process the `Exception` web3 error correctly.
#[cfg(not(target_arch = "wasm32"))]
#[test]
#[ignore]
fn test_get_fee_to_send_taker_fee_insufficient_balance() {
Expand Down Expand Up @@ -562,6 +570,7 @@ fn test_get_fee_to_send_taker_fee_insufficient_balance() {
);
}

#[cfg(not(target_arch = "wasm32"))]
#[test]
fn validate_dex_fee_invalid_sender_eth() {
let (_ctx, coin) = eth_coin_for_test(EthCoinType::Eth, &[ETH_MAINNET_NODE], None, ETH_MAINNET_CHAIN_ID);
Expand All @@ -582,13 +591,16 @@ fn validate_dex_fee_invalid_sender_eth() {
min_block_number: 0,
uuid: &[],
};
let error = coin.validate_fee(validate_fee_args).wait().unwrap_err().into_inner();
let error = block_on_f01(coin.validate_fee(validate_fee_args))
.unwrap_err()
.into_inner();
match error {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("was sent from wrong address")),
_ => panic!("Expected `WrongPaymentTx` wrong sender address, found {:?}", error),
}
}

#[cfg(not(target_arch = "wasm32"))]
#[test]
fn validate_dex_fee_invalid_sender_erc() {
let (_ctx, coin) = eth_coin_for_test(
Expand Down Expand Up @@ -617,13 +629,16 @@ fn validate_dex_fee_invalid_sender_erc() {
min_block_number: 0,
uuid: &[],
};
let error = coin.validate_fee(validate_fee_args).wait().unwrap_err().into_inner();
let error = block_on_f01(coin.validate_fee(validate_fee_args))
.unwrap_err()
.into_inner();
match error {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("was sent from wrong address")),
_ => panic!("Expected `WrongPaymentTx` wrong sender address, found {:?}", error),
}
}

#[cfg(not(target_arch = "wasm32"))]
fn sender_compressed_pub(tx: &SignedEthTx) -> [u8; 33] {
let tx_pubkey = tx.public.unwrap();
let mut raw_pubkey = [0; 65];
Expand All @@ -633,6 +648,7 @@ fn sender_compressed_pub(tx: &SignedEthTx) -> [u8; 33] {
secp_public.serialize()
}

#[cfg(not(target_arch = "wasm32"))]
#[test]
fn validate_dex_fee_eth_confirmed_before_min_block() {
let (_ctx, coin) = eth_coin_for_test(EthCoinType::Eth, &[ETH_MAINNET_NODE], None, ETH_MAINNET_CHAIN_ID);
Expand All @@ -655,13 +671,16 @@ fn validate_dex_fee_eth_confirmed_before_min_block() {
min_block_number: 11784793,
uuid: &[],
};
let error = coin.validate_fee(validate_fee_args).wait().unwrap_err().into_inner();
let error = block_on_f01(coin.validate_fee(validate_fee_args))
.unwrap_err()
.into_inner();
match error {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("confirmed before min_block")),
_ => panic!("Expected `WrongPaymentTx` early confirmation, found {:?}", error),
}
}

#[cfg(not(target_arch = "wasm32"))]
#[test]
fn validate_dex_fee_erc_confirmed_before_min_block() {
let (_ctx, coin) = eth_coin_for_test(
Expand Down Expand Up @@ -693,13 +712,16 @@ fn validate_dex_fee_erc_confirmed_before_min_block() {
min_block_number: 11823975,
uuid: &[],
};
let error = coin.validate_fee(validate_fee_args).wait().unwrap_err().into_inner();
let error = block_on_f01(coin.validate_fee(validate_fee_args))
.unwrap_err()
.into_inner();
match error {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("confirmed before min_block")),
_ => panic!("Expected `WrongPaymentTx` early confirmation, found {:?}", error),
}
}

#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_negotiate_swap_contract_addr_no_fallback() {
let (_, coin) = eth_coin_for_test(EthCoinType::Eth, &[ETH_MAINNET_NODE], None, ETH_MAINNET_CHAIN_ID);
Expand Down Expand Up @@ -727,6 +749,7 @@ fn test_negotiate_swap_contract_addr_no_fallback() {
assert_eq!(Some(slice.to_vec().into()), result);
}

#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_negotiate_swap_contract_addr_has_fallback() {
let fallback = Address::from_str("0x8500AFc0bc5214728082163326C2FF0C73f4a871").unwrap();
Expand Down Expand Up @@ -815,15 +838,14 @@ fn polygon_check_if_my_payment_sent() {
amount: &BigDecimal::default(),
payment_instructions: &None,
};
let my_payment = coin
.check_if_my_payment_sent(if_my_payment_sent_args)
.wait()
let my_payment = block_on_f01(coin.check_if_my_payment_sent(if_my_payment_sent_args))
.unwrap()
.unwrap();
let expected_hash = BytesJson::from("69a20008cea0c15ee483b5bbdff942752634aa072dfd2ff715fe87eec302de11");
assert_eq!(expected_hash, my_payment.tx_hash_as_bytes());
}

#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_message_hash() {
let key_pair = Random.generate().unwrap();
Expand All @@ -842,6 +864,7 @@ fn test_message_hash() {
);
}

#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_sign_verify_message() {
let key_pair = KeyPair::from_secret_slice(
Expand All @@ -866,6 +889,7 @@ fn test_sign_verify_message() {
assert!(is_valid);
}

#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_eth_extract_secret() {
let key_pair = Random.generate().unwrap();
Expand Down
22 changes: 10 additions & 12 deletions mm2src/coins/lightning/ln_platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use bitcoin::hash_types::{BlockHash, TxMerkleNode, Txid};
use bitcoin_hashes::{sha256d, Hash};
use common::executor::{abortable_queue::AbortableQueue, AbortableSystem, SpawnFuture, Timer};
use common::log::{debug, error, info};
use common::wait_until_sec;
use common::{block_on_f01, wait_until_sec};
use futures::compat::Future01CompatExt;
use futures::future::join_all;
use keys::hash::H256;
Expand Down Expand Up @@ -570,17 +570,15 @@ impl FeeEstimator for Platform {
ConfirmationTarget::HighPriority => self.confirmations_targets.high_priority,
};
let fee_per_kb = tokio::task::block_in_place(move || {
self.rpc_client()
.estimate_fee_sat(
platform_coin.decimals(),
// Todo: when implementing Native client detect_fee_method should be used for Native and
// EstimateFeeMethod::Standard for Electrum
&EstimateFeeMethod::Standard,
&conf.estimate_fee_mode,
n_blocks,
)
.wait()
.unwrap_or(latest_fees)
block_on_f01(self.rpc_client().estimate_fee_sat(
platform_coin.decimals(),
// Todo: when implementing Native client detect_fee_method should be used for Native and
// EstimateFeeMethod::Standard for Electrum
&EstimateFeeMethod::Standard,
&conf.estimate_fee_mode,
n_blocks,
))
.unwrap_or(latest_fees)
});

// Set default fee to last known fee for the corresponding confirmation target
Expand Down
4 changes: 2 additions & 2 deletions mm2src/coins/lp_coins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ macro_rules! try_f {
};
}

#[cfg(feature = "enable-solana")]
#[cfg(all(feature = "enable-solana", not(target_arch = "wasm32")))]
macro_rules! try_tx_fus_err {
($err: expr) => {
return Box::new(futures01::future::err(crate::TransactionErr::Plain(ERRL!(
Expand All @@ -133,7 +133,7 @@ macro_rules! try_tx_fus_err {
};
}

#[cfg(feature = "enable-solana")]
#[cfg(all(feature = "enable-solana", not(target_arch = "wasm32")))]
macro_rules! try_tx_fus_opt {
($e: expr, $err: expr) => {
match $e {
Expand Down
Loading

0 comments on commit 6fa527a

Please sign in to comment.