Skip to content

Commit

Permalink
eth-eth kickstart test
Browse files Browse the repository at this point in the history
  • Loading branch information
laruh committed Dec 26, 2024
1 parent bbe2f5c commit d48cc25
Show file tree
Hide file tree
Showing 3 changed files with 191 additions and 13 deletions.
3 changes: 1 addition & 2 deletions mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1313,8 +1313,7 @@ pub fn init_geth_node() {
thread::sleep(Duration::from_millis(100));
}

let dex_fee_addr = addr_from_raw_pubkey(&DEX_FEE_ADDR_RAW_PUBKEY).unwrap();
let dex_fee_addr = Token::Address(dex_fee_addr);
let dex_fee_addr = Token::Address(GETH_ACCOUNT);
let params = ethabi::encode(&[dex_fee_addr]);
let taker_swap_v2_data = format!("{}{}", TAKER_SWAP_V2_BYTES, hex::encode(params));

Expand Down
146 changes: 136 additions & 10 deletions mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ use coins::{CoinProtocol, CoinWithDerivationMethod, CommonSwapOpsV2, ConfirmPaym
use common::{block_on, block_on_f01, now_sec};
use crypto::Secp256k1Secret;
use ethereum_types::U256;
#[cfg(any(feature = "sepolia-maker-swap-v2-tests", feature = "sepolia-taker-swap-v2-tests"))]
use mm2_core::mm_ctx::MmArc;
use mm2_number::{BigDecimal, BigUint};
use mm2_test_helpers::for_tests::{account_balance, disable_coin, enable_erc20_token_v2, enable_eth_with_tokens_v2,
erc20_dev_conf, eth_dev_conf, get_new_address, get_token_info, nft_dev_conf,
MarketMakerIt, Mm2TestConf};
use mm2_test_helpers::for_tests::{account_balance, active_swaps, coins_needed_for_kickstart, disable_coin,
enable_erc20_token_v2, enable_eth_coin_v2, enable_eth_with_tokens_v2,
erc20_dev_conf, eth1_dev_conf, eth_dev_conf, get_locked_amount, get_new_address,
get_token_info, mm_dump, my_swap_status, nft_dev_conf, start_swaps, MarketMakerIt,
Mm2TestConf, SwapV2TestContracts, TestNode};
#[cfg(any(feature = "sepolia-maker-swap-v2-tests", feature = "sepolia-taker-swap-v2-tests"))]
use mm2_test_helpers::for_tests::{eth_sepolia_conf, sepolia_erc20_dev_conf};
use mm2_test_helpers::structs::{Bip44Chain, EnableCoinBalanceMap, EthWithTokensActivationResult, HDAccountAddressId,
Expand All @@ -43,6 +44,7 @@ use serde_json::Value as Json;
use std::str::FromStr;
use std::thread;
use std::time::Duration;
use uuid::Uuid;
use web3::contract::{Contract, Options};
use web3::ethabi::Token;
#[cfg(any(feature = "sepolia-maker-swap-v2-tests", feature = "sepolia-taker-swap-v2-tests"))]
Expand All @@ -55,6 +57,7 @@ const SEPOLIA_MAKER_PRIV: &str = "6e2f3a6223b928a05a3a3622b0c3f3573d03663b704a61
const SEPOLIA_TAKER_PRIV: &str = "e0be82dca60ff7e4c6d6db339ac9e1ae249af081dba2110bddd281e711608f16";
const NFT_ETH: &str = "NFT_ETH";
const ETH: &str = "ETH";
const ETH1: &str = "ETH1";

#[cfg(any(feature = "sepolia-maker-swap-v2-tests", feature = "sepolia-taker-swap-v2-tests"))]
const ERC20: &str = "ERC20DEV";
Expand Down Expand Up @@ -1427,15 +1430,16 @@ impl SwapAddresses {
}
}

#[allow(dead_code)]
/// Needed for eth or erc20 v2 activation in Geth tests
fn eth_coin_v2_activation_with_random_privkey(
ctx: &MmArc,
ticker: &str,
conf: &Json,
swap_addr: SwapAddresses,
erc20: bool,
) -> EthCoin {
let build_policy = EthPrivKeyBuildPolicy::IguanaPrivKey(random_secp256k1_secret());
) -> (EthCoin, Secp256k1Secret) {
let priv_key = random_secp256k1_secret();
let build_policy = EthPrivKeyBuildPolicy::IguanaPrivKey(priv_key);
let node = EthNode {
url: GETH_RPC_URL.to_string(),
komodo_proxy: false,
Expand All @@ -1455,7 +1459,7 @@ fn eth_coin_v2_activation_with_random_privkey(
gap_limit: None,
};
let coin = block_on(eth_coin_from_conf_and_request_v2(
&MM_CTX1,
ctx,
ticker,
conf,
platform_request,
Expand All @@ -1471,9 +1475,9 @@ fn eth_coin_v2_activation_with_random_privkey(
token_addr: erc20_contract(),
};
let coin = block_on(coin.set_coin_type(coin_type));
return coin;
return (coin, priv_key);
}
coin
(coin, priv_key)
}

#[cfg(feature = "sepolia-taker-swap-v2-tests")]
Expand Down Expand Up @@ -2749,3 +2753,125 @@ fn test_enable_custom_erc20_with_duplicate_contract_in_config() {
// Disable the custom token, this to check that it was enabled correctly
block_on(disable_coin(&mm_hd, &config_ticker, true));
}

#[test]
fn test_v2_eth_eth_kickstart() {
// Initialize swap addresses and configurations
let swap_addresses = SwapAddresses::init();
let contracts = SwapV2TestContracts {
maker_swap_v2_contract: eth_addr_to_hex(&swap_addresses.swap_v2_contracts.maker_swap_v2_contract),
taker_swap_v2_contract: eth_addr_to_hex(&swap_addresses.swap_v2_contracts.taker_swap_v2_contract),
nft_maker_swap_v2_contract: eth_addr_to_hex(&swap_addresses.swap_v2_contracts.nft_maker_swap_v2_contract),
};
let swap_contract_address = eth_addr_to_hex(&swap_addresses.swap_contract_address);
let node = TestNode {
url: GETH_RPC_URL.to_string(),
};

// Helper function for activating coins
let enable_coins = |mm: &MarketMakerIt, coins: &[&str]| {
for &coin in coins {
log!(
"{:?}",
block_on(enable_eth_coin_v2(
mm,
coin,
&swap_contract_address,
contracts.clone(),
None,
&[node.clone()]
))
);
}
};

// start Bob and Alice
let (_, bob_priv_key) =
eth_coin_v2_activation_with_random_privkey(&MM_CTX, ETH, &eth_dev_conf(), swap_addresses, false);
let (_, alice_priv_key) =
eth_coin_v2_activation_with_random_privkey(&MM_CTX1, ETH1, &eth1_dev_conf(), swap_addresses, false);
let coins = json!([eth_dev_conf(), eth1_dev_conf()]);

let mut bob_conf = Mm2TestConf::seednode_trade_v2(&format!("0x{}", hex::encode(bob_priv_key)), &coins);
let mut mm_bob = MarketMakerIt::start(bob_conf.conf.clone(), bob_conf.rpc_password.clone(), None).unwrap();
let (_bob_dump_log, _bob_dump_dashboard) = mm_dump(&mm_bob.log_path);
log!("Bob log path: {}", mm_bob.log_path.display());

let mut alice_conf =
Mm2TestConf::light_node_trade_v2(&format!("0x{}", hex::encode(alice_priv_key)), &coins, &[&mm_bob
.ip
.to_string()]);
let mut mm_alice = MarketMakerIt::start(alice_conf.conf.clone(), alice_conf.rpc_password.clone(), None).unwrap();
let (_alice_dump_log, _alice_dump_dashboard) = mm_dump(&mm_alice.log_path);
log!("Alice log path: {}", mm_alice.log_path.display());

// Enable ETH and ETH1 for both Bob and Alice
enable_coins(&mm_bob, &[ETH, ETH1]);
enable_coins(&mm_alice, &[ETH, ETH1]);

let uuids = block_on(start_swaps(&mut mm_bob, &mut mm_alice, &[(ETH, ETH1)], 1.0, 1.0, 77.));
log!("{:?}", uuids);
let parsed_uuids: Vec<Uuid> = uuids.iter().map(|u| u.parse().unwrap()).collect();

for uuid in uuids.iter() {
log_swap_status_before_stop(&mm_bob, uuid, "Maker");
log_swap_status_before_stop(&mm_alice, uuid, "Taker");
}

block_on(mm_bob.stop()).unwrap();
block_on(mm_alice.stop()).unwrap();

// Restart Bob and Alice
bob_conf.conf["dbdir"] = mm_bob.folder.join("DB").to_str().unwrap().into();
bob_conf.conf["log"] = mm_bob.folder.join("mm2_dup.log").to_str().unwrap().into();

let mm_bob = MarketMakerIt::start(bob_conf.conf, bob_conf.rpc_password, None).unwrap();
let (_bob_dump_log, _bob_dump_dashboard) = mm_dump(&mm_bob.log_path);
log!("Bob log path: {}", mm_bob.log_path.display());

alice_conf.conf["dbdir"] = mm_alice.folder.join("DB").to_str().unwrap().into();
alice_conf.conf["log"] = mm_alice.folder.join("mm2_dup.log").to_str().unwrap().into();
alice_conf.conf["seednodes"] = vec![mm_bob.ip.to_string()].into();

let mm_alice = MarketMakerIt::start(alice_conf.conf, alice_conf.rpc_password, None).unwrap();
let (_alice_dump_log, _alice_dump_dashboard) = mm_dump(&mm_alice.log_path);
log!("Alice log path: {}", mm_alice.log_path.display());

verify_coins_needed_for_kickstart(&mm_bob, &[ETH, ETH1]);
verify_coins_needed_for_kickstart(&mm_alice, &[ETH, ETH1]);

enable_coins(&mm_bob, &[ETH, ETH1]);
enable_coins(&mm_alice, &[ETH, ETH1]);

// give swaps 1 second to restart
thread::sleep(Duration::from_secs(1));

verify_active_swaps(&mm_bob, &parsed_uuids);
verify_active_swaps(&mm_alice, &parsed_uuids);

// coins must be virtually locked after kickstart until swap transactions are sent
verify_locked_amount(&mm_alice, "Taker", ETH1);
verify_locked_amount(&mm_bob, "Maker", ETH);
}

fn log_swap_status_before_stop(mm: &MarketMakerIt, uuid: &str, role: &str) {
let status = block_on(my_swap_status(mm, uuid));
log!("{} swap {} status before stop: {:?}", role, uuid, status);
}

fn verify_coins_needed_for_kickstart(mm: &MarketMakerIt, expected_coins: &[&str]) {
let mut coins_needed = block_on(coins_needed_for_kickstart(mm));
coins_needed.sort();
assert_eq!(coins_needed, expected_coins);
}

fn verify_active_swaps(mm: &MarketMakerIt, expected_uuids: &[Uuid]) {
let active_swaps = block_on(active_swaps(mm));
assert_eq!(active_swaps.uuids, expected_uuids);
}

fn verify_locked_amount(mm: &MarketMakerIt, role: &str, coin: &str) {
let locked = block_on(get_locked_amount(mm, coin));
log!("{} {} locked amount: {:?}", role, coin, locked.locked_amount);
assert_eq!(locked.coin, coin);
}
55 changes: 54 additions & 1 deletion mm2src/mm2_test_helpers/src/for_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -820,8 +820,16 @@ pub fn eth_testnet_conf_trezor() -> Json {

/// ETH configuration used for dockerized Geth dev node
pub fn eth_dev_conf() -> Json {
eth_conf("ETH")
}

pub fn eth1_dev_conf() -> Json {
eth_conf("ETH1")
}

fn eth_conf(coin: &str) -> Json {
json!({
"coin": "ETH",
"coin": coin,
"name": "ethereum",
"mm2": 1,
"chain_id": 1337,
Expand Down Expand Up @@ -2041,6 +2049,51 @@ pub async fn enable_eth_coin(
json::from_str(&enable.1).unwrap()
}

#[derive(Clone)]
pub struct SwapV2TestContracts {
pub maker_swap_v2_contract: String,
pub taker_swap_v2_contract: String,
pub nft_maker_swap_v2_contract: String,
}

#[derive(Clone)]
pub struct TestNode {
pub url: String,
}

pub async fn enable_eth_coin_v2(
mm: &MarketMakerIt,
ticker: &str,
swap_contract_address: &str,
swap_v2_contracts: SwapV2TestContracts,
fallback_swap_contract: Option<&str>,
nodes: &[TestNode],
) -> Json {
let enable = mm
.rpc(&json!({
"userpass": mm.userpass,
"method": "enable_eth_with_tokens",
"mmrpc": "2.0",
"params": {
"ticker": ticker,
"mm2": 1,
"swap_contract_address": swap_contract_address,
"swap_v2_contracts": {
"maker_swap_v2_contract": swap_v2_contracts.maker_swap_v2_contract,
"taker_swap_v2_contract": swap_v2_contracts.taker_swap_v2_contract,
"nft_maker_swap_v2_contract": swap_v2_contracts.nft_maker_swap_v2_contract
},
"fallback_swap_contract": fallback_swap_contract,
"nodes": nodes.iter().map(|node| json!({ "url": node.url })).collect::<Vec<_>>(),
"erc20_tokens_requests": []
}
}))
.await
.unwrap();
assert_eq!(enable.0, StatusCode::OK, "'enable_eth_with_tokens' failed: {}", enable.1);
json::from_str(&enable.1).unwrap()
}

pub async fn enable_slp(mm: &MarketMakerIt, coin: &str) -> Json {
let enable = mm
.rpc(&json!({
Expand Down

0 comments on commit d48cc25

Please sign in to comment.