Skip to content

Commit

Permalink
Fix Zhtlc orders is_mine bug #1461 (#1489)
Browse files Browse the repository at this point in the history
* WIP rough implementation

* WIP orderbook_rpc

* WIP orderbook_rpc_v2

* WIP tests

* WIP CoinActivationResult

* WIP

* WIP add target_arch for protocol matching

* WIP check_point_block added

* WIP fix a typo

* WIP

* WIP valid check_point_block for zombie

* notes added

* fix is_mine_zhtlc

* remove mutex

* wip add_pubkey

* added my_p2p_pubkeys for wasm

* added remove_pubkey function

* r2r

* use one is_mine func

* little fix

* remove unnecessary code

* little fix

* add check_point_block 290_000 for test

* is_my_order remove pub

* move my_p2p_pubkeys in Orderbook

* remove my_p2p_pubkeys.insert from orders_kick_start
  • Loading branch information
laruh authored Oct 18, 2022
1 parent 28280d7 commit 62b1653
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 20 deletions.
23 changes: 18 additions & 5 deletions mm2src/mm2_main/src/lp_ordermatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,9 +388,18 @@ fn insert_or_update_order(ctx: &MmArc, item: OrderbookItem) {
orderbook.insert_or_update_order_update_trie(item)
}

fn delete_order(ctx: &MmArc, pubkey: &str, uuid: Uuid) {
// use this function when notify maker order created
fn insert_or_update_my_order(ctx: &MmArc, item: OrderbookItem, my_order: &MakerOrder) {
let ordermatch_ctx = OrdermatchContext::from_ctx(ctx).expect("from_ctx failed");
let mut orderbook = ordermatch_ctx.orderbook.lock();
orderbook.insert_or_update_order_update_trie(item);
if let Some(key) = my_order.p2p_privkey {
orderbook.my_p2p_pubkeys.insert(hex::encode(key.public_slice()));
}
}

fn delete_order(ctx: &MmArc, pubkey: &str, uuid: Uuid) {
let ordermatch_ctx = OrdermatchContext::from_ctx(ctx).expect("from_ctx failed");
let mut orderbook = ordermatch_ctx.orderbook.lock();
if let Some(order) = orderbook.order_set.get(&uuid) {
if order.pubkey == pubkey {
Expand All @@ -399,10 +408,13 @@ fn delete_order(ctx: &MmArc, pubkey: &str, uuid: Uuid) {
}
}

fn delete_my_order(ctx: &MmArc, uuid: Uuid) {
fn delete_my_order(ctx: &MmArc, uuid: Uuid, p2p_privkey: Option<SerializableSecp256k1Keypair>) {
let ordermatch_ctx: Arc<OrdermatchContext> = OrdermatchContext::from_ctx(ctx).expect("from_ctx failed");
let mut orderbook = ordermatch_ctx.orderbook.lock();
orderbook.remove_order_trie_update(uuid);
if let Some(key) = p2p_privkey {
orderbook.my_p2p_pubkeys.remove(&hex::encode(key.public_slice()));
}
}

fn remove_pubkey_pair_orders(orderbook: &mut Orderbook, pubkey: &str, alb_pair: &str) {
Expand Down Expand Up @@ -952,8 +964,8 @@ fn maker_order_created_p2p_notify(
};

let encoded_msg = encode_and_sign(&to_broadcast, key_pair.private_ref()).unwrap();
let order: OrderbookItem = (message, hex::encode(key_pair.public_slice())).into();
insert_or_update_order(&ctx, order);
let item: OrderbookItem = (message, hex::encode(key_pair.public_slice())).into();
insert_or_update_my_order(&ctx, item, order);
broadcast_p2p_msg(&ctx, vec![topic], encoded_msg, peer_id);
}

Expand Down Expand Up @@ -990,7 +1002,7 @@ fn maker_order_cancelled_p2p_notify(ctx: MmArc, order: &MakerOrder) {
timestamp: now_ms() / 1000,
pair_trie_root: H64::default(),
});
delete_my_order(&ctx, order.uuid);
delete_my_order(&ctx, order.uuid, order.p2p_privkey);
log::debug!("maker_order_cancelled_p2p_notify called, message {:?}", message);
broadcast_ordermatch_message(&ctx, vec![order.orderbook_topic()], message, order.p2p_keypair());
}
Expand Down Expand Up @@ -2409,6 +2421,7 @@ struct Orderbook {
topics_subscribed_to: HashMap<String, OrderbookRequestingState>,
/// MemoryDB instance to store Patricia Tries data
memory_db: MemoryDB<Blake2Hasher64>,
my_p2p_pubkeys: HashSet<String>,
}

fn hashed_null_node<T: TrieConfiguration>() -> TrieHash<T> { <T::Codec as NodeCodecT>::hashed_null_node() }
Expand Down
17 changes: 11 additions & 6 deletions mm2src/mm2_main/src/lp_ordermatch/orderbook_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use mm2_err_handle::prelude::*;
use mm2_number::{construct_detailed, BigRational, MmNumber, MmNumberMultiRepr};
use num_traits::Zero;
use serde_json::{self as json, Value as Json};
use std::collections::HashSet;

#[derive(Deserialize)]
pub struct OrderbookReq {
Expand Down Expand Up @@ -107,8 +108,12 @@ fn build_aggregated_entries_v2(
(aggregated, total_base.into(), total_rel.into())
}

pub fn is_my_order(my_pub: &Option<String>, order_pubkey: &str) -> bool {
my_pub.as_ref().map(|my| my == order_pubkey).unwrap_or(false)
// ZHTLC protocol coin uses random keypair to sign P2P messages per every order.
// So, each ZHTLC order has unique «pubkey» field that doesn’t match node persistent pubkey derived from passphrase.
// We can compare pubkeys from maker_orders and from asks or bids, to find our order.
#[inline(always)]
fn is_my_order(my_orders_pubkeys: &HashSet<String>, my_pub: &Option<String>, order_pubkey: &str) -> bool {
my_pub.as_deref() == Some(order_pubkey) || my_orders_pubkeys.contains(order_pubkey)
}

pub async fn orderbook_rpc(ctx: MmArc, req: Json) -> Result<Response<Vec<u8>>, String> {
Expand Down Expand Up @@ -162,7 +167,7 @@ pub async fn orderbook_rpc(ctx: MmArc, req: Json) -> Result<Response<Vec<u8>>, S
&ask.pubkey,
address_format,
));
let is_mine = is_my_order(&my_pubsecp, &ask.pubkey);
let is_mine = is_my_order(&orderbook.my_p2p_pubkeys, &my_pubsecp, &ask.pubkey);
orderbook_entries.push(ask.as_rpc_entry_ask(address, is_mine));
}
orderbook_entries
Expand All @@ -189,7 +194,7 @@ pub async fn orderbook_rpc(ctx: MmArc, req: Json) -> Result<Response<Vec<u8>>, S
&bid.pubkey,
address_format,
));
let is_mine = is_my_order(&my_pubsecp, &bid.pubkey);
let is_mine = is_my_order(&orderbook.my_p2p_pubkeys, &my_pubsecp, &bid.pubkey);
orderbook_entries.push(bid.as_rpc_entry_bid(address, is_mine));
}
orderbook_entries
Expand Down Expand Up @@ -331,7 +336,7 @@ pub async fn orderbook_rpc_v2(
continue;
},
};
let is_mine = is_my_order(&my_pubsecp, &ask.pubkey);
let is_mine = is_my_order(&orderbook.my_p2p_pubkeys, &my_pubsecp, &ask.pubkey);
orderbook_entries.push(ask.as_rpc_v2_entry_ask(address, is_mine));
}
orderbook_entries
Expand Down Expand Up @@ -361,7 +366,7 @@ pub async fn orderbook_rpc_v2(
continue;
},
};
let is_mine = is_my_order(&my_pubsecp, &bid.pubkey);
let is_mine = is_my_order(&orderbook.my_p2p_pubkeys, &my_pubsecp, &bid.pubkey);
orderbook_entries.push(bid.as_rpc_v2_entry_bid(address, is_mine));
}
orderbook_entries
Expand Down
8 changes: 4 additions & 4 deletions mm2src/mm2_main/src/mm2_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use uuid::Uuid;
use mm2_test_helpers::for_tests::init_z_coin_native;

#[cfg(all(feature = "zhtlc-native-tests", not(target_arch = "wasm32")))]
async fn enable_z_coin(mm: &MarketMakerIt, coin: &str) -> ZcoinActivationResult {
async fn enable_z_coin(mm: &MarketMakerIt, coin: &str) -> CoinActivationResult {
let init = init_z_coin_native(mm, coin).await;
let init: RpcV2Response<InitTaskResult> = json::from_value(init).unwrap();
let timeout = now_ms() + 120000;
Expand All @@ -43,7 +43,7 @@ async fn enable_z_coin(mm: &MarketMakerIt, coin: &str) -> ZcoinActivationResult

let status = init_z_coin_status(mm, init.result.task_id).await;
let status: RpcV2Response<InitZcoinStatus> = json::from_value(status).unwrap();
if let InitZcoinStatus::Ready(rpc_result) = status.result {
if let InitZcoinStatus::Ok(rpc_result) = status.result {
match rpc_result {
MmRpcResult::Ok { result } => break result,
MmRpcResult::Err(e) => panic!("{} initialization error {:?}", coin, e),
Expand Down Expand Up @@ -183,7 +183,7 @@ async fn enable_z_coin_light(
coin: &str,
electrums: &[&str],
lightwalletd_urls: &[&str],
) -> ZcoinActivationResult {
) -> CoinActivationResult {
let init = init_z_coin_light(mm, coin, electrums, lightwalletd_urls).await;
let init: RpcV2Response<InitTaskResult> = json::from_value(init).unwrap();
let timeout = now_ms() + 12000000;
Expand All @@ -196,7 +196,7 @@ async fn enable_z_coin_light(
let status = init_z_coin_status(mm, init.result.task_id).await;
println!("Status {}", json::to_string(&status).unwrap());
let status: RpcV2Response<InitZcoinStatus> = json::from_value(status).unwrap();
if let InitZcoinStatus::Ready(rpc_result) = status.result {
if let InitZcoinStatus::Ok(rpc_result) = status.result {
match rpc_result {
MmRpcResult::Ok { result } => {
break result;
Expand Down
4 changes: 2 additions & 2 deletions mm2src/mm2_main/src/mm2_tests/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ pub enum EnableCoinBalance {

#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ZcoinActivationResult {
pub struct CoinActivationResult {
pub ticker: String,
pub current_block: u64,
pub wallet_balance: EnableCoinBalance,
Expand Down Expand Up @@ -652,7 +652,7 @@ pub enum MmRpcResult<T> {
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields, tag = "status", content = "details")]
pub enum InitZcoinStatus {
Ready(MmRpcResult<ZcoinActivationResult>),
Ok(MmRpcResult<CoinActivationResult>),
InProgress(Json),
UserActionRequired(Json),
}
Expand Down
12 changes: 9 additions & 3 deletions mm2src/mm2_test_helpers/src/for_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,13 @@ pub fn zombie_conf() -> Json {
"hrp_sapling_payment_address": "zs",
"b58_pubkey_address_prefix": [ 28, 184 ],
"b58_script_address_prefix": [ 28, 189 ]
}
},
"check_point_block": {
"height": 290000,
"time": 1664200629,
"hash": "106BAA72C53E7FA52E30E6D3D15B37001207E3CF3B9FCE9BAB6C6D4AF9ED9200",
"sapling_tree": "017797D05B070D29A47EFEBE3FAD3F29345D31BE608C46A5131CD55D201A631C13000D000119CE6220D0CB0F82AD6466B677828A0B4C2983662DAB181A86F913F7E9FB9C28000139C4399E4CA741CBABBDDAEB6DCC3541BA902343E394160EEECCDF20C289BA65011823D28B592E9612A6C3CF4778F174E10B1B714B4FF85E6E58EE19DD4A0D5734016FA4682B0007E61B63A0442B85E0B8C0CE2409E665F219013B5E24E385F6066B00000001A325043E11CD6A431A0BD99141C4C6E9632A156185EB9B0DBEF665EEC803DD6F00000103C11FCCC90C2EC1A126635F708311EDEF9B93D3E752E053D3AA9EFA0AF9D526"
},
}
},
"required_confirmations":0
Expand Down Expand Up @@ -1679,7 +1685,7 @@ pub async fn init_z_coin_light(mm: &MarketMakerIt, coin: &str, electrums: &[&str
let request = mm
.rpc(&json! ({
"userpass": mm.userpass,
"method": "init_z_coin",
"method": "task::enable_z_coin::init",
"mmrpc": "2.0",
"params": {
"ticker": coin,
Expand All @@ -1704,7 +1710,7 @@ pub async fn init_z_coin_status(mm: &MarketMakerIt, task_id: u64) -> Json {
let request = mm
.rpc(&json! ({
"userpass": mm.userpass,
"method": "init_z_coin_status",
"method": "task::enable_z_coin::status",
"mmrpc": "2.0",
"params": {
"task_id": task_id,
Expand Down

0 comments on commit 62b1653

Please sign in to comment.