Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hotfix MTP retrieval in electrum mode for QTUM and ZER coins. #975

Merged
merged 2 commits into from
Jun 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions mm2src/coins/qrc20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ use rpc::v1::types::{Bytes as BytesJson, Transaction as RpcTransaction, H160 as
use script::{Builder as ScriptBuilder, Opcode, Script, TransactionInputSigner};
use script_pubkey::generate_contract_call_script_pubkey;
use serde_json::{self as json, Value as Json};
use serialization::deserialize;
use serialization::serialize;
use serialization::{deserialize, serialize, CoinVariant};
use std::ops::{Deref, Neg};
#[cfg(not(target_arch = "wasm32"))] use std::path::PathBuf;
use std::str::FromStr;
Expand Down Expand Up @@ -480,7 +479,9 @@ impl UtxoCommonOps for Qrc20Coin {
utxo_common::address_from_str(&self.utxo.conf, address)
}

async fn get_current_mtp(&self) -> UtxoRpcResult<u32> { utxo_common::get_current_mtp(&self.utxo).await }
async fn get_current_mtp(&self) -> UtxoRpcResult<u32> {
utxo_common::get_current_mtp(&self.utxo, CoinVariant::Qtum).await
}

fn is_unspent_mature(&self, output: &RpcTransaction) -> bool { self.is_qtum_unspent_mature(output) }

Expand Down
5 changes: 4 additions & 1 deletion mm2src/coins/utxo/qtum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use common::mm_metrics::MetricsArc;
use common::mm_number::MmNumber;
use ethereum_types::H160;
use futures::{FutureExt, TryFutureExt};
use serialization::CoinVariant;

pub const QTUM_STANDARD_DUST: u64 = 1000;

Expand Down Expand Up @@ -166,7 +167,9 @@ impl UtxoCommonOps for QtumCoin {
utxo_common::address_from_str(&self.utxo_arc.conf, address)
}

async fn get_current_mtp(&self) -> UtxoRpcResult<u32> { utxo_common::get_current_mtp(&self.utxo_arc).await }
async fn get_current_mtp(&self) -> UtxoRpcResult<u32> {
utxo_common::get_current_mtp(&self.utxo_arc, CoinVariant::Qtum).await
}

fn is_unspent_mature(&self, output: &RpcTransaction) -> bool { self.is_qtum_unspent_mature(output) }

Expand Down
25 changes: 20 additions & 5 deletions mm2src/coins/utxo/rpc_clients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use keys::Address;
use rpc::v1::types::{Bytes as BytesJson, Transaction as RpcTransaction, H256 as H256Json};
use script::Builder;
use serde_json::{self as json, Value as Json};
use serialization::{deserialize, serialize, CompactInteger, Reader};
use serialization::{deserialize, serialize, CoinVariant, CompactInteger, Reader};
use sha2::{Digest, Sha256};
use std::collections::hash_map::{Entry, HashMap};
use std::fmt;
Expand Down Expand Up @@ -245,7 +245,12 @@ pub trait UtxoRpcClientOps: fmt::Debug + Send + Sync + 'static {
) -> Box<dyn Future<Item = Option<UtxoTx>, Error = String> + Send>;

/// Get median time past for `count` blocks in the past including `starting_block`
fn get_median_time_past(&self, starting_block: u64, count: NonZeroU64) -> UtxoRpcFut<u32>;
fn get_median_time_past(
&self,
starting_block: u64,
count: NonZeroU64,
coin_variant: CoinVariant,
) -> UtxoRpcFut<u32>;
}

#[derive(Clone, Deserialize, Debug)]
Expand Down Expand Up @@ -660,7 +665,12 @@ impl UtxoRpcClientOps for NativeClient {
Box::new(fut.boxed().compat())
}

fn get_median_time_past(&self, starting_block: u64, count: NonZeroU64) -> UtxoRpcFut<u32> {
fn get_median_time_past(
&self,
starting_block: u64,
count: NonZeroU64,
_coin_variant: CoinVariant,
) -> UtxoRpcFut<u32> {
let selfi = self.clone();
let fut = async move {
let starting_block_hash = selfi.get_block_hash(starting_block).compat().await?;
Expand Down Expand Up @@ -1575,7 +1585,12 @@ impl UtxoRpcClientOps for ElectrumClient {
Box::new(fut.boxed().compat())
}

fn get_median_time_past(&self, starting_block: u64, count: NonZeroU64) -> UtxoRpcFut<u32> {
fn get_median_time_past(
&self,
starting_block: u64,
count: NonZeroU64,
coin_variant: CoinVariant,
) -> UtxoRpcFut<u32> {
let from = if starting_block <= count.get() {
0
} else {
Expand All @@ -1591,7 +1606,7 @@ impl UtxoRpcClientOps for ElectrumClient {
let len = CompactInteger::from(res.count);
let mut serialized = serialize(&len).take();
serialized.extend(res.hex.0.into_iter());
let mut reader = Reader::new(serialized.as_slice());
let mut reader = Reader::new_with_coin_variant(serialized.as_slice(), coin_variant);
let headers = reader.read_list::<BlockHeader>()?;
let mut timestamps: Vec<_> = headers.into_iter().map(|block| block.time).collect();
// can unwrap because count is non zero
Expand Down
6 changes: 3 additions & 3 deletions mm2src/coins/utxo/utxo_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use script::{Builder, Opcode, Script, ScriptAddress, SignatureVersion, Transacti
UnsignedTransactionInput};
use secp256k1::{PublicKey, Signature};
use serde_json::{self as json};
use serialization::{deserialize, serialize};
use serialization::{deserialize, serialize, CoinVariant};
use std::cmp::Ordering;
use std::collections::hash_map::{Entry, HashMap};
use std::str::FromStr;
Expand Down Expand Up @@ -253,10 +253,10 @@ pub fn address_from_str(conf: &UtxoCoinConf, address: &str) -> Result<Address, S
}
}

pub async fn get_current_mtp(coin: &UtxoCoinFields) -> UtxoRpcResult<u32> {
pub async fn get_current_mtp(coin: &UtxoCoinFields, coin_variant: CoinVariant) -> UtxoRpcResult<u32> {
let current_block = coin.rpc_client.get_block_count().compat().await?;
coin.rpc_client
.get_median_time_past(current_block, coin.conf.mtp_block_count)
.get_median_time_past(current_block, coin.conf.mtp_block_count, coin_variant)
.compat()
.await
}
Expand Down
5 changes: 4 additions & 1 deletion mm2src/coins/utxo/utxo_standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{CanRefundHtlc, CoinBalance, NegotiateSwapContractAddrErr, SwapOps, T
use common::mm_metrics::MetricsArc;
use common::mm_number::MmNumber;
use futures::{FutureExt, TryFutureExt};
use serialization::CoinVariant;

#[derive(Clone, Debug)]
pub struct UtxoStandardCoin {
Expand Down Expand Up @@ -58,7 +59,9 @@ impl UtxoCommonOps for UtxoStandardCoin {
utxo_common::address_from_str(&self.utxo_arc.conf, address)
}

async fn get_current_mtp(&self) -> UtxoRpcResult<u32> { utxo_common::get_current_mtp(&self.utxo_arc).await }
async fn get_current_mtp(&self) -> UtxoRpcResult<u32> {
utxo_common::get_current_mtp(&self.utxo_arc, CoinVariant::Standard).await
}

fn is_unspent_mature(&self, output: &RpcTransaction) -> bool {
utxo_common::is_unspent_mature(self.utxo_arc.conf.mature_confirmations, output)
Expand Down
57 changes: 47 additions & 10 deletions mm2src/coins/utxo/utxo_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use futures::future::join_all;
use mocktopus::mocking::*;
use rpc::v1::types::H256 as H256Json;
use script::Opcode;
use serialization::deserialize;
use serialization::{deserialize, CoinVariant};
use std::thread;
use std::time::Duration;

Expand Down Expand Up @@ -1016,7 +1016,7 @@ fn test_get_median_time_past_from_electrum_kmd() {
]);

let mtp = client
.get_median_time_past(1773390, KMD_MTP_BLOCK_COUNT)
.get_median_time_past(1773390, KMD_MTP_BLOCK_COUNT, CoinVariant::Standard)
.wait()
.unwrap();
// the MTP is block time of 1773385 in this case
Expand All @@ -1031,7 +1031,10 @@ fn test_get_median_time_past_from_electrum_btc() {
"electrum3.cipig.net:10000",
]);

let mtp = client.get_median_time_past(632858, KMD_MTP_BLOCK_COUNT).wait().unwrap();
let mtp = client
.get_median_time_past(632858, KMD_MTP_BLOCK_COUNT, CoinVariant::Standard)
.wait()
.unwrap();
assert_eq!(1591173041, mtp);
}

Expand All @@ -1055,7 +1058,10 @@ fn test_get_median_time_past_from_native_has_median_in_get_block() {
)
});

let mtp = client.get_median_time_past(632858, KMD_MTP_BLOCK_COUNT).wait().unwrap();
let mtp = client
.get_median_time_past(632858, KMD_MTP_BLOCK_COUNT, CoinVariant::Standard)
.wait()
.unwrap();
assert_eq!(1591173041, mtp);
}

Expand Down Expand Up @@ -1098,7 +1104,10 @@ fn test_get_median_time_past_from_native_does_not_have_median_in_get_block() {
MockResult::Return(Box::new(futures01::future::ok(block)))
});

let mtp = client.get_median_time_past(632858, KMD_MTP_BLOCK_COUNT).wait().unwrap();
let mtp = client
.get_median_time_past(632858, KMD_MTP_BLOCK_COUNT, CoinVariant::Standard)
.wait()
.unwrap();
assert_eq!(1591173041, mtp);
}

Expand Down Expand Up @@ -2389,7 +2398,7 @@ fn doge_mtp() {
"electrum3.cipig.net:10060",
]);
let mtp = electrum
.get_median_time_past(3631820, NonZeroU64::new(11).unwrap())
.get_median_time_past(3631820, NonZeroU64::new(11).unwrap(), CoinVariant::Standard)
.wait()
.unwrap();
assert_eq!(mtp, 1614849084);
Expand All @@ -2403,7 +2412,7 @@ fn firo_mtp() {
"electrumx03.firo.org:50001",
]);
let mtp = electrum
.get_median_time_past(356730, NonZeroU64::new(11).unwrap())
.get_median_time_past(356730, NonZeroU64::new(11).unwrap(), CoinVariant::Standard)
.wait()
.unwrap();
assert_eq!(mtp, 1616492629);
Expand All @@ -2413,7 +2422,7 @@ fn firo_mtp() {
fn verus_mtp() {
let electrum = electrum_client_for_test(&["el0.verus.io:17485", "el1.verus.io:17485", "el2.verus.io:17485"]);
let mtp = electrum
.get_median_time_past(1480113, NonZeroU64::new(11).unwrap())
.get_median_time_past(1480113, NonZeroU64::new(11).unwrap(), CoinVariant::Standard)
.wait()
.unwrap();
assert_eq!(mtp, 1618579909);
Expand Down Expand Up @@ -2533,7 +2542,7 @@ fn sys_mtp() {
"electrum3.cipig.net:10064",
]);
let mtp = electrum
.get_median_time_past(1006678, NonZeroU64::new(11).unwrap())
.get_median_time_past(1006678, NonZeroU64::new(11).unwrap(), CoinVariant::Standard)
.wait()
.unwrap();
assert_eq!(mtp, 1620019628);
Expand All @@ -2547,12 +2556,40 @@ fn btc_mtp() {
"electrum3.cipig.net:10000",
]);
let mtp = electrum
.get_median_time_past(681659, NonZeroU64::new(11).unwrap())
.get_median_time_past(681659, NonZeroU64::new(11).unwrap(), CoinVariant::Standard)
.wait()
.unwrap();
assert_eq!(mtp, 1620019527);
}

#[test]
fn qtum_mtp() {
let electrum = electrum_client_for_test(&[
"electrum1.cipig.net:10050",
"electrum2.cipig.net:10050",
"electrum3.cipig.net:10050",
]);
let mtp = electrum
.get_median_time_past(681659, NonZeroU64::new(11).unwrap(), CoinVariant::Qtum)
.wait()
.unwrap();
assert_eq!(mtp, 1598854128);
}

#[test]
fn zer_mtp() {
let electrum = electrum_client_for_test(&[
"electrum1.cipig.net:10065",
"electrum2.cipig.net:10065",
"electrum3.cipig.net:10065",
]);
let mtp = electrum
.get_median_time_past(1130915, NonZeroU64::new(11).unwrap(), CoinVariant::Standard)
.wait()
.unwrap();
assert_eq!(mtp, 1623240214);
}

#[test]
#[ignore]
fn send_and_refund_dex_fee() {
Expand Down
Loading