diff --git a/Cargo.lock b/Cargo.lock index 99227202a5..f0cef862ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -882,6 +882,7 @@ dependencies = [ "mm2_metrics", "mm2_net", "mm2_number", + "mm2_p2p", "mm2_rpc", "mm2_state_machine", "mm2_test_helpers", @@ -3876,10 +3877,10 @@ dependencies = [ "hex", "instant", "lazy_static", + "libp2p", "mm2_err_handle", "mm2_event_stream", "mm2_metrics", - "mm2_p2p", "mm2_rpc", "primitives", "rand 0.7.3", @@ -4183,10 +4184,8 @@ dependencies = [ "lazy_static", "mm2_core", "mm2_err_handle", - "mm2_event_stream", - "mm2_p2p", + "mm2_number", "mm2_state_machine", - "parking_lot", "pin-project", "prost", "rand 0.7.3", @@ -4235,12 +4234,17 @@ dependencies = [ "lazy_static", "libp2p", "log", + "mm2_core", + "mm2_event_stream", + "mm2_number", + "parking_lot", "rand 0.7.3", "regex", "rmp-serde", "secp256k1 0.20.3", "serde", "serde_bytes", + "serde_json", "sha2 0.10.7", "smallvec 1.6.1", "syn 2.0.38", diff --git a/mm2src/coins/Cargo.toml b/mm2src/coins/Cargo.toml index 8fa02034c1..30192cd0db 100644 --- a/mm2src/coins/Cargo.toml +++ b/mm2src/coins/Cargo.toml @@ -67,8 +67,9 @@ mm2_event_stream = { path = "../mm2_event_stream" } mm2_git = { path = "../mm2_git" } mm2_io = { path = "../mm2_io" } mm2_metrics = { path = "../mm2_metrics" } -mm2_net = { path = "../mm2_net", features = ["p2p"] } +mm2_net = { path = "../mm2_net" } mm2_number = { path = "../mm2_number"} +mm2_p2p = { path = "../mm2_p2p" } mm2_rpc = { path = "../mm2_rpc" } mm2_state_machine = { path = "../mm2_state_machine" } mocktopus = "0.8.0" diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 15af41b3c2..576920b030 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -13,7 +13,7 @@ use instant::Instant; use mm2_err_handle::common_errors::WithInternal; #[cfg(target_arch = "wasm32")] use mm2_metamask::{from_metamask_error, MetamaskError, MetamaskRpcError, WithMetamaskRpcError}; -use mm2_net::p2p::P2PContext; +use mm2_p2p::p2p_ctx::P2PContext; use proxy_signature::RawMessage; use rpc_task::RpcTaskError; use std::sync::atomic::Ordering; diff --git a/mm2src/coins/eth/web3_transport/http_transport.rs b/mm2src/coins/eth/web3_transport/http_transport.rs index 5d6ad98a26..5d8da5f859 100644 --- a/mm2src/coins/eth/web3_transport/http_transport.rs +++ b/mm2src/coins/eth/web3_transport/http_transport.rs @@ -3,7 +3,7 @@ use common::APPLICATION_JSON; use common::X_AUTH_PAYLOAD; use http::header::CONTENT_TYPE; use jsonrpc_core::{Call, Response}; -use mm2_net::p2p::Keypair; +use mm2_p2p::Keypair; use proxy_signature::RawMessage; use serde_json::Value as Json; use std::ops::Deref; diff --git a/mm2src/coins/eth/web3_transport/websocket_transport.rs b/mm2src/coins/eth/web3_transport/websocket_transport.rs index fd1220e92e..38590b72fd 100644 --- a/mm2src/coins/eth/web3_transport/websocket_transport.rs +++ b/mm2src/coins/eth/web3_transport/websocket_transport.rs @@ -20,7 +20,7 @@ use futures_ticker::Ticker; use futures_util::{FutureExt, SinkExt, StreamExt}; use instant::{Duration, Instant}; use jsonrpc_core::Call; -use mm2_net::p2p::Keypair; +use mm2_p2p::Keypair; use proxy_signature::{ProxySign, RawMessage}; use std::sync::atomic::AtomicBool; use std::sync::{atomic::{AtomicUsize, Ordering}, diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index 2298ae9648..2dc85e67dc 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -1,7 +1,7 @@ use http::Uri; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::{MmError, MmResult}; -use mm2_net::p2p::P2PContext; +use mm2_p2p::p2p_ctx::P2PContext; use proxy_signature::{ProxySign, RawMessage}; use url::Url; diff --git a/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs b/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs index 6b4dfb9ca4..5da40d622d 100644 --- a/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs +++ b/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs @@ -6,7 +6,7 @@ use cosmrs::tendermint::evidence::Evidence; use cosmrs::tendermint::Genesis; use cosmrs::tendermint::Hash; use http::Uri; -use mm2_net::p2p::Keypair; +use mm2_p2p::Keypair; use serde::{de::DeserializeOwned, Serialize}; use std::fmt; use std::time::Duration; @@ -382,7 +382,7 @@ mod sealed { use hyper::client::HttpConnector; use hyper::{header, Uri}; use hyper_rustls::{HttpsConnector, HttpsConnectorBuilder}; - use mm2_net::p2p::Keypair; + use mm2_p2p::Keypair; use proxy_signature::RawMessage; use std::io::Read; use tendermint_rpc::{Error, Response, SimpleRequest}; diff --git a/mm2src/coins/tendermint/rpc/tendermint_wasm_rpc.rs b/mm2src/coins/tendermint/rpc/tendermint_wasm_rpc.rs index 4b5d6a0652..9224ea997f 100644 --- a/mm2src/coins/tendermint/rpc/tendermint_wasm_rpc.rs +++ b/mm2src/coins/tendermint/rpc/tendermint_wasm_rpc.rs @@ -4,9 +4,9 @@ use derive_more::Display; use http::header::{ACCEPT, CONTENT_TYPE}; use http::uri::InvalidUri; use http::{StatusCode, Uri}; -use mm2_net::p2p::Keypair; use mm2_net::transport::SlurpError; use mm2_net::wasm::http::FetchRequest; +use mm2_p2p::Keypair; use proxy_signature::RawMessage; use std::str::FromStr; use tendermint_rpc::endpoint::{abci_info, broadcast}; diff --git a/mm2src/coins/tendermint/tendermint_balance_events.rs b/mm2src/coins/tendermint/tendermint_balance_events.rs index a7a5fd94cf..c512cf8277 100644 --- a/mm2src/coins/tendermint/tendermint_balance_events.rs +++ b/mm2src/coins/tendermint/tendermint_balance_events.rs @@ -7,7 +7,6 @@ use jsonrpc_core::{Id as RpcId, Params as RpcParams, Value as RpcValue, Version use mm2_core::mm_ctx::MmArc; use mm2_event_stream::{behaviour::{EventBehaviour, EventInitStatus}, ErrorEventName, Event, EventName, EventStreamConfiguration}; -use mm2_net::p2p::Keypair; use mm2_number::BigDecimal; use proxy_signature::RawMessage; use std::collections::{HashMap, HashSet}; @@ -24,7 +23,7 @@ impl EventBehaviour for TendermintCoin { async fn handle(self, _interval: f64, tx: oneshot::Sender) { fn generate_subscription_query( query_filter: String, - proxy_sign_keypair: &Option, + proxy_sign_keypair: &Option, uri: &http::Uri, ) -> String { let mut params = serde_json::Map::with_capacity(1); diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index de1753cffe..e04b3509e9 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -65,8 +65,8 @@ use keys::{KeyPair, Public}; use mm2_core::mm_ctx::{MmArc, MmWeak}; use mm2_err_handle::prelude::*; use mm2_git::{FileMetadata, GitController, GithubClient, RepositoryOperations, GITHUB_API_URI}; -use mm2_net::p2p::P2PContext; use mm2_number::MmNumber; +use mm2_p2p::p2p_ctx::P2PContext; use parking_lot::Mutex as PaMutex; use primitives::hash::H256; use regex::Regex; diff --git a/mm2src/mm2_core/Cargo.toml b/mm2src/mm2_core/Cargo.toml index a9d308be9a..d0df9dbe7c 100644 --- a/mm2src/mm2_core/Cargo.toml +++ b/mm2src/mm2_core/Cargo.toml @@ -17,10 +17,10 @@ derive_more = "0.99" futures = { version = "0.3", package = "futures", features = ["compat", "async-await", "thread-pool"] } hex = "0.4.2" lazy_static = "1.4" +libp2p = { git = "https://github.com/KomodoPlatform/rust-libp2p.git", tag = "k-0.52.4", default-features = false, features = ["identify"] } mm2_err_handle = { path = "../mm2_err_handle" } mm2_event_stream = { path = "../mm2_event_stream" } mm2_metrics = { path = "../mm2_metrics" } -mm2_libp2p = { path = "../mm2_p2p", package = "mm2_p2p" } primitives = { path = "../mm2_bitcoin/primitives" } rand = { version = "0.7", features = ["std", "small_rng", "wasm-bindgen"] } serde = "1" diff --git a/mm2src/mm2_core/src/mm_ctx.rs b/mm2src/mm2_core/src/mm_ctx.rs index 3f56970f3c..8c417f2ce1 100644 --- a/mm2src/mm2_core/src/mm_ctx.rs +++ b/mm2src/mm2_core/src/mm_ctx.rs @@ -9,8 +9,8 @@ use futures::channel::oneshot; use futures::lock::Mutex as AsyncMutex; use gstuff::{try_s, Constructible, ERR, ERRL}; use lazy_static::lazy_static; +use libp2p::PeerId; use mm2_event_stream::{controller::Controller, Event, EventStreamConfiguration}; -use mm2_libp2p::PeerAddress; use mm2_metrics::{MetricsArc, MetricsOps}; use primitives::hash::H160; use rand::Rng; @@ -146,7 +146,7 @@ pub struct MmCtx { #[cfg(not(target_arch = "wasm32"))] pub async_sqlite_connection: Constructible>>, /// Links the RPC context to the P2P context to handle health check responses. - pub healthcheck_response_handler: AsyncMutex>>, + pub healthcheck_response_handler: AsyncMutex>>, } impl MmCtx { diff --git a/mm2src/mm2_main/Cargo.toml b/mm2src/mm2_main/Cargo.toml index 259d3fc934..4fa36b0f82 100644 --- a/mm2src/mm2_main/Cargo.toml +++ b/mm2src/mm2_main/Cargo.toml @@ -63,9 +63,9 @@ mm2_err_handle = { path = "../mm2_err_handle" } mm2_event_stream = { path = "../mm2_event_stream" } mm2_gui_storage = { path = "../mm2_gui_storage" } mm2_io = { path = "../mm2_io" } -mm2_libp2p = { path = "../mm2_p2p", package = "mm2_p2p" } +mm2_libp2p = { path = "../mm2_p2p", package = "mm2_p2p", features = ["application"] } mm2_metrics = { path = "../mm2_metrics" } -mm2_net = { path = "../mm2_net", features = ["event-stream", "p2p"] } +mm2_net = { path = "../mm2_net" } mm2_number = { path = "../mm2_number" } mm2_rpc = { path = "../mm2_rpc", features = ["rpc_facilities"]} mm2_state_machine = { path = "../mm2_state_machine" } diff --git a/mm2src/mm2_main/src/lp_healthcheck.rs b/mm2src/mm2_main/src/lp_healthcheck.rs index 849f478d5f..5e9db51111 100644 --- a/mm2src/mm2_main/src/lp_healthcheck.rs +++ b/mm2src/mm2_main/src/lp_healthcheck.rs @@ -9,8 +9,8 @@ use instant::{Duration, Instant}; use lazy_static::lazy_static; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::MmError; +use mm2_libp2p::p2p_ctx::P2PContext; use mm2_libp2p::{decode_message, encode_message, pub_sub_topic, Libp2pPublic, PeerAddress, TopicPrefix}; -use mm2_net::p2p::P2PContext; use ser_error_derive::SerializeErrorType; use serde::{Deserialize, Serialize}; use std::convert::TryFrom; @@ -265,7 +265,7 @@ pub async fn peer_connection_healthcheck_rpc( { let mut book = ctx.healthcheck_response_handler.lock().await; - book.insert(target_peer_address, tx, address_record_exp); + book.insert(target_peer_address.into(), tx, address_record_exp); } broadcast_p2p_msg( @@ -328,7 +328,7 @@ pub(crate) async fn process_p2p_healthcheck_message(ctx: &MmArc, message: mm2_li } else { // The requested peer is healthy; signal the response channel. let mut response_handler = ctx.healthcheck_response_handler.lock().await; - if let Some(tx) = response_handler.remove(&sender_peer) { + if let Some(tx) = response_handler.remove(&sender_peer.into()) { if tx.send(()).is_err() { log::error!("Result channel isn't present for peer '{sender_peer}'."); }; diff --git a/mm2src/mm2_main/src/lp_native_dex.rs b/mm2src/mm2_main/src/lp_native_dex.rs index cd055132a5..8e1e91ec13 100644 --- a/mm2src/mm2_main/src/lp_native_dex.rs +++ b/mm2src/mm2_main/src/lp_native_dex.rs @@ -29,12 +29,12 @@ use mm2_core::mm_ctx::{MmArc, MmCtx}; use mm2_err_handle::common_errors::InternalError; use mm2_err_handle::prelude::*; use mm2_event_stream::behaviour::{EventBehaviour, EventInitStatus}; +use mm2_libp2p::application::network_event::NetworkEvent; use mm2_libp2p::behaviours::atomicdex::{generate_ed25519_keypair, GossipsubConfig, DEPRECATED_NETID_LIST}; +use mm2_libp2p::p2p_ctx::P2PContext; use mm2_libp2p::{spawn_gossipsub, AdexBehaviourError, NodeType, RelayAddress, RelayAddressError, SeedNodeInfo, SwarmRuntime, WssCerts}; use mm2_metrics::mm_gauge; -use mm2_net::network_event::NetworkEvent; -use mm2_net::p2p::P2PContext; use rpc_task::RpcTaskError; use serde_json as json; use std::convert::TryInto; diff --git a/mm2src/mm2_main/src/lp_network.rs b/mm2src/mm2_main/src/lp_network.rs index 8e5195e93a..08ae5f8b3e 100644 --- a/mm2src/mm2_main/src/lp_network.rs +++ b/mm2src/mm2_main/src/lp_network.rs @@ -29,12 +29,13 @@ use instant::Instant; use keys::KeyPair; use mm2_core::mm_ctx::{MmArc, MmWeak}; use mm2_err_handle::prelude::*; +use mm2_libp2p::application::request_response::P2PRequest; +use mm2_libp2p::p2p_ctx::P2PContext; use mm2_libp2p::{decode_message, encode_message, DecodingError, GossipsubEvent, GossipsubMessage, Libp2pPublic, Libp2pSecpPublic, MessageId, NetworkPorts, PeerId, TOPIC_SEPARATOR}; use mm2_libp2p::{AdexBehaviourCmd, AdexBehaviourEvent, AdexEventRx, AdexResponse}; use mm2_libp2p::{PeerAddresses, RequestResponseBehaviourEvent}; use mm2_metrics::{mm_label, mm_timing}; -use mm2_net::p2p::P2PContext; use serde::de; use std::net::ToSocketAddrs; @@ -87,12 +88,6 @@ impl From for P2PRequestError { fn from(e: rmp_serde::decode::Error) -> Self { P2PRequestError::DecodeError(e.to_string()) } } -#[derive(Eq, Debug, Deserialize, PartialEq, Serialize)] -pub enum P2PRequest { - Ordermatch(lp_ordermatch::OrdermatchRequest), - NetworkInfo(lp_stats::NetworkInfoRequest), -} - pub async fn p2p_event_process_loop(ctx: MmWeak, mut rx: AdexEventRx, i_am_relay: bool) { loop { let adex_event = rx.next().await; diff --git a/mm2src/mm2_main/src/lp_ordermatch.rs b/mm2src/mm2_main/src/lp_ordermatch.rs index df1a35d946..60f8a32aa6 100644 --- a/mm2src/mm2_main/src/lp_ordermatch.rs +++ b/mm2src/mm2_main/src/lp_ordermatch.rs @@ -21,7 +21,6 @@ // use async_trait::async_trait; -use best_orders::BestOrdersAction; use blake2::digest::{Update, VariableOutput}; use blake2::Blake2bVar; use coins::utxo::{compressed_pub_key_from_priv_raw, ChecksumType, UtxoAddressFormat}; @@ -42,6 +41,8 @@ use http::Response; use keys::{AddressFormat, KeyPair}; use mm2_core::mm_ctx::{from_ctx, MmArc, MmWeak}; use mm2_err_handle::prelude::*; +use mm2_libp2p::application::request_response::ordermatch::OrdermatchRequest; +use mm2_libp2p::application::request_response::P2PRequest; use mm2_libp2p::{decode_signed, encode_and_sign, encode_message, pub_sub_topic, PublicKey, TopicHash, TopicPrefix, TOPIC_SEPARATOR}; use mm2_metrics::mm_gauge; @@ -69,8 +70,7 @@ use std::time::Duration; use trie_db::NodeCodec as NodeCodecT; use uuid::Uuid; -use crate::lp_network::{broadcast_p2p_msg, request_any_relay, request_one_peer, subscribe_to_topic, P2PRequest, - P2PRequestError}; +use crate::lp_network::{broadcast_p2p_msg, request_any_relay, request_one_peer, subscribe_to_topic, P2PRequestError}; use crate::lp_swap::maker_swap_v2::{self, MakerSwapStateMachine, MakerSwapStorage}; use crate::lp_swap::taker_swap_v2::{self, TakerSwapStateMachine, TakerSwapStorage}; use crate::lp_swap::{calc_max_maker_vol, check_balance_for_maker_swap, check_balance_for_taker_swap, @@ -600,34 +600,6 @@ pub async fn process_msg(ctx: MmArc, from_peer: String, msg: &[u8], i_am_relay: } } -#[derive(Debug, Deserialize, Eq, PartialEq, Serialize)] -pub enum OrdermatchRequest { - /// Get an orderbook for the given pair. - GetOrderbook { - base: String, - rel: String, - }, - /// Sync specific pubkey orderbook state if our known Patricia trie state doesn't match the latest keep alive message - SyncPubkeyOrderbookState { - pubkey: String, - /// Request using this condition - trie_roots: HashMap, - }, - BestOrders { - coin: String, - action: BestOrdersAction, - volume: BigRational, - }, - OrderbookDepth { - pairs: Vec<(String, String)>, - }, - BestOrdersByNumber { - coin: String, - action: BestOrdersAction, - number: usize, - }, -} - #[derive(Debug)] struct TryFromBytesError(String); diff --git a/mm2src/mm2_main/src/lp_ordermatch/best_orders.rs b/mm2src/mm2_main/src/lp_ordermatch/best_orders.rs index 121a444e29..3bf684b66c 100644 --- a/mm2src/mm2_main/src/lp_ordermatch/best_orders.rs +++ b/mm2src/mm2_main/src/lp_ordermatch/best_orders.rs @@ -4,6 +4,8 @@ use derive_more::Display; use http::{Response, StatusCode}; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; +use mm2_libp2p::application::request_response::{ordermatch::{BestOrdersAction, OrdermatchRequest}, + P2PRequest}; use mm2_number::{BigRational, MmNumber}; use mm2_rpc::data::legacy::OrderConfirmationsSettings; use num_traits::Zero; @@ -12,15 +14,8 @@ use std::collections::{HashMap, HashSet}; use uuid::Uuid; use super::{addr_format_from_protocol_info, is_my_order, mm2_internal_pubkey_hex, orderbook_address, - BaseRelProtocolInfo, OrderbookP2PItemWithProof, OrdermatchContext, OrdermatchRequest, RpcOrderbookEntryV2}; -use crate::lp_network::{request_any_relay, P2PRequest}; - -#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] -#[serde(rename_all = "lowercase")] -pub enum BestOrdersAction { - Buy, - Sell, -} + BaseRelProtocolInfo, OrderbookP2PItemWithProof, OrdermatchContext, RpcOrderbookEntryV2}; +use crate::lp_network::request_any_relay; #[derive(Debug, Deserialize)] pub struct BestOrdersRequest { diff --git a/mm2src/mm2_main/src/lp_ordermatch/orderbook_depth.rs b/mm2src/mm2_main/src/lp_ordermatch/orderbook_depth.rs index c335ac75ef..1772acbe61 100644 --- a/mm2src/mm2_main/src/lp_ordermatch/orderbook_depth.rs +++ b/mm2src/mm2_main/src/lp_ordermatch/orderbook_depth.rs @@ -1,9 +1,10 @@ -use super::{orderbook_topic_from_base_rel, OrdermatchContext, OrdermatchRequest}; -use crate::lp_network::{request_any_relay, P2PRequest}; +use super::{orderbook_topic_from_base_rel, OrdermatchContext}; +use crate::lp_network::request_any_relay; use coins::is_wallet_only_ticker; use common::log; use http::Response; use mm2_core::mm_ctx::MmArc; +use mm2_libp2p::application::request_response::{ordermatch::OrdermatchRequest, P2PRequest}; use serde_json::{self as json, Value as Json}; use std::collections::HashMap; diff --git a/mm2src/mm2_main/src/lp_stats.rs b/mm2src/mm2_main/src/lp_stats.rs index e86e742457..185996ecd1 100644 --- a/mm2src/mm2_main/src/lp_stats.rs +++ b/mm2src/mm2_main/src/lp_stats.rs @@ -7,13 +7,14 @@ use futures::lock::Mutex as AsyncMutex; use http::StatusCode; use mm2_core::mm_ctx::{from_ctx, MmArc}; use mm2_err_handle::prelude::*; +use mm2_libp2p::application::request_response::network_info::NetworkInfoRequest; use mm2_libp2p::{encode_message, NetworkInfo, PeerId, RelayAddress, RelayAddressError}; use serde_json::{self as json, Value as Json}; use std::collections::{HashMap, HashSet}; use std::sync::Arc; -use crate::lp_network::{add_reserved_peer_addresses, lp_network_ports, request_peers, NetIdError, P2PRequest, - ParseAddressError, PeerDecodedResponse}; +use crate::lp_network::{add_reserved_peer_addresses, lp_network_ports, request_peers, NetIdError, ParseAddressError, + PeerDecodedResponse}; use std::str::FromStr; pub type NodeVersionResult = Result>; @@ -169,12 +170,6 @@ struct Mm2VersionRes { nodes: HashMap, } -#[derive(Debug, Deserialize, Eq, PartialEq, Serialize)] -pub enum NetworkInfoRequest { - /// Get MM2 version of nodes added to stats collection - GetMm2Version, -} - fn process_get_version_request(ctx: MmArc) -> Result>, String> { let response = ctx.mm_version().to_string(); let encoded = try_s!(encode_message(&response)); @@ -264,6 +259,7 @@ pub async fn start_version_stat_collection(ctx: MmArc, req: Json) -> NodeVersion #[cfg(not(target_arch = "wasm32"))] async fn stat_collection_loop(ctx: MmArc, interval: f64) { use common::now_sec; + use mm2_libp2p::application::request_response::P2PRequest; use crate::database::stats_nodes::select_peers_names; diff --git a/mm2src/mm2_main/src/ordermatch_tests.rs b/mm2src/mm2_main/src/ordermatch_tests.rs index 38d17af4ed..1ac83697af 100644 --- a/mm2src/mm2_main/src/ordermatch_tests.rs +++ b/mm2src/mm2_main/src/ordermatch_tests.rs @@ -6,10 +6,12 @@ use crypto::privkey::key_pair_from_seed; use db_common::sqlite::rusqlite::Connection; use futures::{channel::mpsc, StreamExt}; use mm2_core::mm_ctx::{MmArc, MmCtx}; +use mm2_libp2p::application::request_response::ordermatch::OrdermatchRequest; +use mm2_libp2p::application::request_response::P2PRequest; use mm2_libp2p::behaviours::atomicdex::generate_ed25519_keypair; +use mm2_libp2p::p2p_ctx::P2PContext; use mm2_libp2p::AdexBehaviourCmd; use mm2_libp2p::{decode_message, PeerId}; -use mm2_net::p2p::P2PContext; use mm2_test_helpers::for_tests::mm_ctx_with_iguana; use mocktopus::mocking::*; use rand::{seq::SliceRandom, thread_rng, Rng}; diff --git a/mm2src/mm2_main/src/rpc/lp_commands/lp_commands_legacy.rs b/mm2src/mm2_main/src/rpc/lp_commands/lp_commands_legacy.rs index 5ef386942c..686e9d5281 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/lp_commands_legacy.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/lp_commands_legacy.rs @@ -25,8 +25,8 @@ use common::{rpc_err_response, rpc_response, HyRes}; use futures::compat::Future01CompatExt; use http::Response; use mm2_core::mm_ctx::MmArc; +use mm2_libp2p::p2p_ctx::P2PContext; use mm2_metrics::MetricsOps; -use mm2_net::p2p::P2PContext; use mm2_number::construct_detailed; use mm2_rpc::data::legacy::{BalanceResponse, CoinInitResponse, Mm2RpcResult, MmVersionResponse, Status}; use serde_json::{self as json, Value as Json}; diff --git a/mm2src/mm2_net/Cargo.toml b/mm2src/mm2_net/Cargo.toml index 3962bf1136..a720327d96 100644 --- a/mm2src/mm2_net/Cargo.toml +++ b/mm2src/mm2_net/Cargo.toml @@ -7,11 +7,9 @@ edition = "2018" doctest = false [features] -event-stream = ["mm2_event_stream", "async-stream" , "p2p"] -p2p = ["mm2-libp2p", "parking_lot"] [dependencies] -async-stream = { version = "0.3", optional = true } +async-stream = { version = "0.3" } async-trait = "0.1" bytes = "1.1" cfg-if = "1.0" @@ -24,9 +22,7 @@ http = "0.2" lazy_static = "1.4" mm2_core = { path = "../mm2_core" } mm2_err_handle = { path = "../mm2_err_handle" } -mm2_event_stream = { path = "../mm2_event_stream", optional = true } -mm2-libp2p = { path = "../mm2_p2p", package = "mm2_p2p", optional = true } -parking_lot = { version = "0.12.0", features = ["nightly"], optional = true } +mm2_number = { path = "../mm2_number" } prost = "0.12" rand = { version = "0.7", features = ["std", "small_rng", "wasm-bindgen"] } serde = "1" diff --git a/mm2src/mm2_net/src/lib.rs b/mm2src/mm2_net/src/lib.rs index 954e25c5a0..4ae26ca182 100644 --- a/mm2src/mm2_net/src/lib.rs +++ b/mm2src/mm2_net/src/lib.rs @@ -1,13 +1,9 @@ pub mod grpc_web; -#[cfg(feature = "event-stream")] pub mod network_event; -#[cfg(feature = "p2p")] pub mod p2p; pub mod transport; #[cfg(not(target_arch = "wasm32"))] pub mod ip_addr; #[cfg(not(target_arch = "wasm32"))] pub mod native_http; #[cfg(not(target_arch = "wasm32"))] pub mod native_tls; -#[cfg(all(feature = "event-stream", not(target_arch = "wasm32")))] -pub mod sse_handler; +#[cfg(not(target_arch = "wasm32"))] pub mod sse_handler; #[cfg(target_arch = "wasm32")] pub mod wasm; -#[cfg(all(feature = "event-stream", target_arch = "wasm32"))] -pub mod wasm_event_stream; +#[cfg(target_arch = "wasm32")] pub mod wasm_event_stream; diff --git a/mm2src/mm2_p2p/Cargo.toml b/mm2src/mm2_p2p/Cargo.toml index 7001ebeabf..6b7f43e7f4 100644 --- a/mm2src/mm2_p2p/Cargo.toml +++ b/mm2src/mm2_p2p/Cargo.toml @@ -3,6 +3,10 @@ name = "mm2_p2p" version = "0.1.0" edition = "2021" +[features] +default = [] +application = ["dep:mm2_number"] + [lib] doctest = false @@ -15,12 +19,17 @@ futures-ticker = "0.0.3" hex = "0.4.2" lazy_static = "1.4" log = "0.4" +mm2_core = { path = "../mm2_core" } +mm2_event_stream = { path = "../mm2_event_stream" } +mm2_number = { path = "../mm2_number", optional = true } +parking_lot = { version = "0.12.0", features = ["nightly"] } rand = { version = "0.7", default-features = false, features = ["wasm-bindgen"] } regex = "1" rmp-serde = "0.14.3" secp256k1 = { version = "0.20", features = ["rand"] } serde = { version = "1.0", default-features = false } serde_bytes = "0.11.5" +serde_json = { version = "1", features = ["preserve_order", "raw_value"] } sha2 = "0.10" smallvec = "1.6.1" syn = "2.0.18" diff --git a/mm2src/mm2_p2p/src/application/mod.rs b/mm2src/mm2_p2p/src/application/mod.rs new file mode 100644 index 0000000000..bccb70ac5c --- /dev/null +++ b/mm2src/mm2_p2p/src/application/mod.rs @@ -0,0 +1,5 @@ +//! This module contains KDF application logic related to P2P network gated +//! by the "application" feature. + +pub mod network_event; +pub mod request_response; diff --git a/mm2src/mm2_net/src/network_event.rs b/mm2src/mm2_p2p/src/application/network_event.rs similarity index 79% rename from mm2src/mm2_net/src/network_event.rs rename to mm2src/mm2_p2p/src/application/network_event.rs index 9ff7ae15f7..c3c0a0eb5c 100644 --- a/mm2src/mm2_net/src/network_event.rs +++ b/mm2src/mm2_p2p/src/application/network_event.rs @@ -1,12 +1,11 @@ -use crate::p2p::P2PContext; use async_trait::async_trait; use common::{executor::{SpawnFuture, Timer}, log::info}; use futures::channel::oneshot::{self, Receiver, Sender}; + use mm2_core::mm_ctx::MmArc; pub use mm2_event_stream::behaviour::EventBehaviour; use mm2_event_stream::{behaviour::EventInitStatus, Event, EventName, EventStreamConfiguration}; -use mm2_libp2p::behaviours::atomicdex; use serde_json::json; pub struct NetworkEvent { @@ -22,7 +21,7 @@ impl EventBehaviour for NetworkEvent { fn event_name() -> EventName { EventName::NETWORK } async fn handle(self, interval: f64, tx: oneshot::Sender) { - let p2p_ctx = P2PContext::fetch_from_mm_arc(&self.ctx); + let p2p_ctx = crate::p2p_ctx::P2PContext::fetch_from_mm_arc(&self.ctx); let mut previously_sent = json!({}); tx.send(EventInitStatus::Success).unwrap(); @@ -30,11 +29,11 @@ impl EventBehaviour for NetworkEvent { loop { let p2p_cmd_tx = p2p_ctx.cmd_tx.lock().clone(); - let directly_connected_peers = atomicdex::get_directly_connected_peers(p2p_cmd_tx.clone()).await; - let gossip_mesh = atomicdex::get_gossip_mesh(p2p_cmd_tx.clone()).await; - let gossip_peer_topics = atomicdex::get_gossip_peer_topics(p2p_cmd_tx.clone()).await; - let gossip_topic_peers = atomicdex::get_gossip_topic_peers(p2p_cmd_tx.clone()).await; - let relay_mesh = atomicdex::get_relay_mesh(p2p_cmd_tx).await; + let directly_connected_peers = crate::get_directly_connected_peers(p2p_cmd_tx.clone()).await; + let gossip_mesh = crate::get_gossip_mesh(p2p_cmd_tx.clone()).await; + let gossip_peer_topics = crate::get_gossip_peer_topics(p2p_cmd_tx.clone()).await; + let gossip_topic_peers = crate::get_gossip_topic_peers(p2p_cmd_tx.clone()).await; + let relay_mesh = crate::get_relay_mesh(p2p_cmd_tx).await; let event_data = json!({ "directly_connected_peers": directly_connected_peers, diff --git a/mm2src/mm2_p2p/src/application/request_response/mod.rs b/mm2src/mm2_p2p/src/application/request_response/mod.rs new file mode 100644 index 0000000000..28da482bdc --- /dev/null +++ b/mm2src/mm2_p2p/src/application/request_response/mod.rs @@ -0,0 +1,21 @@ +//! This module defines types exclusively for the request-response P2P protocol +//! which are separate from other request types such as RPC requests or Gossipsub +//! messages. + +pub mod network_info; +pub mod ordermatch; + +use serde::{Deserialize, Serialize}; + +/// Wrapper type for handling request-response P2P requests. +#[derive(Eq, Debug, Deserialize, PartialEq, Serialize)] +pub enum P2PRequest { + /// Request for order matching. + Ordermatch(ordermatch::OrdermatchRequest), + /// Request for network information from the target peer. + /// + /// TODO: This should be called `PeerInfoRequest` instead. However, renaming it + /// will introduce a breaking change in the network and is not worth it. Do this + /// renaming when there is already a breaking change in the release. + NetworkInfo(network_info::NetworkInfoRequest), +} diff --git a/mm2src/mm2_p2p/src/application/request_response/network_info.rs b/mm2src/mm2_p2p/src/application/request_response/network_info.rs new file mode 100644 index 0000000000..c8dece2ef5 --- /dev/null +++ b/mm2src/mm2_p2p/src/application/request_response/network_info.rs @@ -0,0 +1,9 @@ +use serde::{Deserialize, Serialize}; + +/// Wraps the different types of network information requests for the P2P request-response +/// protocol. +#[derive(Debug, Deserialize, Eq, PartialEq, Serialize)] +pub enum NetworkInfoRequest { + /// Get MM2 version of nodes added to stats collection + GetMm2Version, +} diff --git a/mm2src/mm2_p2p/src/application/request_response/ordermatch.rs b/mm2src/mm2_p2p/src/application/request_response/ordermatch.rs new file mode 100644 index 0000000000..250758f594 --- /dev/null +++ b/mm2src/mm2_p2p/src/application/request_response/ordermatch.rs @@ -0,0 +1,46 @@ +use mm2_number::BigRational; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +type AlbOrderedOrderbookPair = String; +type H64 = [u8; 8]; + +#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] +#[serde(rename_all = "lowercase")] +pub enum BestOrdersAction { + Buy, + Sell, +} + +/// Wraps the different types of order matching requests for the P2P request-response protocol. +/// +/// TODO: We should use fixed sizes for dynamic fields (such as strings and maps) +/// and prefer stricter types instead of accepting `String` for nearly everything. +/// See https://github.com/KomodoPlatform/komodo-defi-framework/issues/2236 for reference. +#[derive(Debug, Deserialize, Eq, PartialEq, Serialize)] +pub enum OrdermatchRequest { + /// Get an orderbook for the given pair. + GetOrderbook { base: String, rel: String }, + /// Sync specific pubkey orderbook state if our known Patricia trie state doesn't match the latest keep alive message + SyncPubkeyOrderbookState { + pubkey: String, + /// Request using this condition + trie_roots: HashMap, + }, + /// Request best orders for a specific coin and action. + BestOrders { + coin: String, + action: BestOrdersAction, + volume: BigRational, + }, + /// Get orderbook depth for the specified pairs + OrderbookDepth { pairs: Vec<(String, String)> }, + /// Request best orders for a specific coin and action limited by the number of results. + /// + /// Q: Shouldn't we support pagination here? + BestOrdersByNumber { + coin: String, + action: BestOrdersAction, + number: usize, + }, +} diff --git a/mm2src/mm2_p2p/src/lib.rs b/mm2src/mm2_p2p/src/lib.rs index 27e26e8f06..b1d0283be0 100644 --- a/mm2src/mm2_p2p/src/lib.rs +++ b/mm2src/mm2_p2p/src/lib.rs @@ -6,6 +6,9 @@ mod network; mod relay_address; mod swarm_runtime; +#[cfg(feature = "application")] pub mod application; +pub mod p2p_ctx; + use derive_more::Display; use lazy_static::lazy_static; use secp256k1::{Message as SecpMessage, PublicKey as Secp256k1Pubkey, Secp256k1, SecretKey, SignOnly, Signature, diff --git a/mm2src/mm2_net/src/p2p.rs b/mm2src/mm2_p2p/src/p2p_ctx.rs similarity index 91% rename from mm2src/mm2_net/src/p2p.rs rename to mm2src/mm2_p2p/src/p2p_ctx.rs index 30625cbeb5..2d9d991298 100644 --- a/mm2src/mm2_net/src/p2p.rs +++ b/mm2src/mm2_p2p/src/p2p_ctx.rs @@ -1,10 +1,9 @@ +use libp2p::{identity::Keypair, PeerId}; use mm2_core::mm_ctx::MmArc; -use mm2_libp2p::behaviours::atomicdex::AdexCmdTx; -use mm2_libp2p::PeerId; use parking_lot::Mutex; use std::sync::Arc; -pub use mm2_libp2p::Keypair; +use crate::AdexCmdTx; pub struct P2PContext { /// Using Mutex helps to prevent cloning which can actually result to channel being unbounded in case of using 1 tx clone per 1 message.