Skip to content
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
daeafc8
send p2p transaction message to `txhlp/$coin.ticker` topic
onur-ozkan Apr 5, 2022
860163c
propogate the message if coin inside of the topic is activated
onur-ozkan Apr 5, 2022
43862b6
impl `send_raw_tx_bytes` for `MarketCoinOps`
onur-ozkan Apr 5, 2022
b02ce08
update transaction broadcasting
onur-ozkan Apr 5, 2022
f3747f7
create and use dedicated func for sending transaction messages
onur-ozkan Apr 5, 2022
7acdd35
remove unused field from `SwapMsgStore`
onur-ozkan Apr 5, 2022
06ecd56
fix linting
onur-ozkan Apr 6, 2022
5a73d5d
log the error on transaction broadcasting
onur-ozkan Apr 6, 2022
9a4c496
fix `send_raw_tx_bytes` of solana
onur-ozkan Apr 6, 2022
4a5d9c5
fix `send_raw_tx_bytes`
onur-ozkan Apr 6, 2022
a9f2e6b
move use statement
onur-ozkan Apr 6, 2022
840d022
save development state
onur-ozkan Apr 6, 2022
658ff56
send transactions as p2p message
onur-ozkan Apr 6, 2022
f8ed4cc
update exptected error result in test fn `construct_and_send_invalid_…
onur-ozkan Apr 7, 2022
fedbc32
[opt] inline wrapper functions
onur-ozkan Apr 7, 2022
78d64e3
fix `send_raw_tx` and test `send_raw_tx_bytes`
onur-ozkan Apr 7, 2022
e9d16a9
un-inline `send_raw_tx`
onur-ozkan Apr 7, 2022
8545045
Updates after code-review
onur-ozkan Apr 10, 2022
5c24769
change log level of tx broadcasting
onur-ozkan Apr 11, 2022
1c3d7bd
save development state
onur-ozkan Apr 13, 2022
b11fe2c
implement fail-safe returns for `send_taker_refunds_payment`
onur-ozkan Apr 13, 2022
98df7cf
save development state
onur-ozkan Apr 13, 2022
b1f9745
optimize code-base
onur-ozkan Apr 13, 2022
f136301
fix fmt
onur-ozkan Apr 13, 2022
9a203e7
create wrapper macro `FSTX_ERR` that wraps `ERR`
onur-ozkan Apr 13, 2022
b6c8ecb
fix indendation of `FSTX_ERR` macro
onur-ozkan Apr 13, 2022
d10d4a9
update namings
onur-ozkan Apr 13, 2022
3a2b0e9
replace `format!` with `ERRL!` in `FailSafeTxErr::RpcCallFailed`
onur-ozkan Apr 13, 2022
3299524
optimize PR diffs
onur-ozkan Apr 13, 2022
d2cbe7b
doc comment `send_raw_tx_bytes`
onur-ozkan Apr 13, 2022
6534913
optimize `mm2src/coins/utxo/utxo_common.rs` diffs
onur-ozkan Apr 13, 2022
1778350
use full path for tx macros
onur-ozkan Apr 14, 2022
903526f
Merge remote-tracking branch 'origin/dev' into p2p-transaction-helper…
onur-ozkan Apr 14, 2022
6b9e579
save development state
onur-ozkan Apr 18, 2022
19a493d
add test fn for `send_maker_spends_taker_payment`
onur-ozkan Apr 18, 2022
aa43384
update `test_send_contract_calls_recoverable_tx`
onur-ozkan Apr 18, 2022
21f2b6a
fix typo
onur-ozkan Apr 18, 2022
7811106
impl helper functions for `enum TransactionErr`
onur-ozkan Apr 19, 2022
9c9db1c
refactor `send_raw_tx_bytes`
onur-ozkan Apr 20, 2022
f461dcc
sub to `txhlp/$coin` when utxo coin enabled in native mode
onur-ozkan Apr 20, 2022
bad90b6
unbox `TransactionEnum` in `TxRecoverableError`
onur-ozkan Apr 20, 2022
8ca638f
add more spesific conditions on `txhlp` subscription
onur-ozkan Apr 21, 2022
ed574a5
rollback unnecessary broadcastings
onur-ozkan Apr 21, 2022
46ad808
fix PR notes
onur-ozkan Apr 29, 2022
d456326
fix auto-format's bug
onur-ozkan Apr 29, 2022
7e6c215
sync dev
onur-ozkan Apr 29, 2022
9444eda
remove unnecessary type casting
onur-ozkan Apr 29, 2022
5ba0dd1
resolve pr notes
onur-ozkan Apr 30, 2022
f87cef3
resolve pr notes
onur-ozkan Apr 30, 2022
21f9684
resolve pr notes
onur-ozkan May 4, 2022
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
79 changes: 48 additions & 31 deletions mm2src/coins/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,14 @@ use super::{BalanceError, BalanceFut, CoinBalance, CoinProtocol, CoinTransportMe
NumConversResult, RawTransactionError, RawTransactionFut, RawTransactionRequest, RawTransactionRes,
RawTransactionResult, RpcClientType, RpcTransportEventHandler, RpcTransportEventHandlerShared, SwapOps,
TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, Transaction,
TransactionDetails, TransactionEnum, TransactionFut, ValidateAddressResult, WithdrawError, WithdrawFee,
WithdrawFut, WithdrawRequest, WithdrawResult};
TransactionDetails, TransactionEnum, ValidateAddressResult, WithdrawError, WithdrawFee, WithdrawFut,
WithdrawRequest, WithdrawResult};

pub use ethcore_transaction::SignedTransaction as SignedEthTx;
pub use rlp;

mod web3_transport;
use crate::ValidatePaymentInput;
use crate::{TransactionErr, TransactionFut, ValidatePaymentInput};
use common::mm_number::MmNumber;
use common::privkey::key_pair_from_secret;
use web3_transport::{EthFeeHistoryNamespace, Web3Transport};
Expand Down Expand Up @@ -685,10 +685,11 @@ impl Deref for EthCoin {
#[async_trait]
impl SwapOps for EthCoin {
fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut {
let address = try_fus!(addr_from_raw_pubkey(fee_addr));
let address = try_tx_fus!(addr_from_raw_pubkey(fee_addr));

Box::new(
self.send_to_address(address, try_fus!(wei_from_big_decimal(&amount, self.decimals)))
self.send_to_address(address, try_tx_fus!(wei_from_big_decimal(&amount, self.decimals)))
.map_err(TransactionErr::PlainError)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EthCoin::send_to_address should return TransactionErr::TxRecoverableError. Please look at the sign_and_send_transaction_impl function:
https://github.com/KomodoPlatform/atomicDEX-API/blob/c23b1f7bb2941b51297709aee3ac3c46f5370c6f/mm2src/coins/eth.rs#L1382

.map(TransactionEnum::from),
)
}
Expand All @@ -702,18 +703,19 @@ impl SwapOps for EthCoin {
amount: BigDecimal,
swap_contract_address: &Option<BytesJson>,
) -> TransactionFut {
let taker_addr = try_fus!(addr_from_raw_pubkey(taker_pub));
let swap_contract_address = try_fus!(swap_contract_address.try_to_address());
let taker_addr = try_tx_fus!(addr_from_raw_pubkey(taker_pub));
let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address());

Box::new(
self.send_hash_time_locked_payment(
Comment thread
sergeyboyko0791 marked this conversation as resolved.
self.etomic_swap_id(time_lock, secret_hash),
try_fus!(wei_from_big_decimal(&amount, self.decimals)),
try_tx_fus!(wei_from_big_decimal(&amount, self.decimals)),
time_lock,
secret_hash,
taker_addr,
swap_contract_address,
)
.map_err(TransactionErr::PlainError)
.map(TransactionEnum::from),
)
}
Expand All @@ -727,18 +729,19 @@ impl SwapOps for EthCoin {
amount: BigDecimal,
swap_contract_address: &Option<BytesJson>,
) -> TransactionFut {
let maker_addr = try_fus!(addr_from_raw_pubkey(maker_pub));
let swap_contract_address = try_fus!(swap_contract_address.try_to_address());
let maker_addr = try_tx_fus!(addr_from_raw_pubkey(maker_pub));
let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address());

Box::new(
self.send_hash_time_locked_payment(
Comment thread
sergeyboyko0791 marked this conversation as resolved.
self.etomic_swap_id(time_lock, secret_hash),
try_fus!(wei_from_big_decimal(&amount, self.decimals)),
try_tx_fus!(wei_from_big_decimal(&amount, self.decimals)),
time_lock,
secret_hash,
maker_addr,
swap_contract_address,
)
.map_err(TransactionErr::PlainError)
.map(TransactionEnum::from),
)
}
Expand All @@ -752,12 +755,13 @@ impl SwapOps for EthCoin {
_htlc_privkey: &[u8],
swap_contract_address: &Option<BytesJson>,
) -> TransactionFut {
let tx: UnverifiedTransaction = try_fus!(rlp::decode(taker_payment_tx));
let signed = try_fus!(SignedEthTx::new(tx));
let swap_contract_address = try_fus!(swap_contract_address.try_to_address());
let tx: UnverifiedTransaction = try_tx_fus!(rlp::decode(taker_payment_tx));
let signed = try_tx_fus!(SignedEthTx::new(tx));
let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address());
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think, should we return TransactionErr::TxRecoverableError if swap_contract_address.try_to_address() fails?
Please also check if we should do that in other places.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should, why not if we can just return it right?


Box::new(
self.spend_hash_time_locked_payment(signed, swap_contract_address, secret)
.map_err(TransactionErr::PlainError)
.map(TransactionEnum::from),
)
}
Expand All @@ -771,11 +775,12 @@ impl SwapOps for EthCoin {
_htlc_privkey: &[u8],
swap_contract_address: &Option<BytesJson>,
) -> TransactionFut {
let tx: UnverifiedTransaction = try_fus!(rlp::decode(maker_payment_tx));
let signed = try_fus!(SignedEthTx::new(tx));
let swap_contract_address = try_fus!(swap_contract_address.try_to_address());
let tx: UnverifiedTransaction = try_tx_fus!(rlp::decode(maker_payment_tx));
let signed = try_tx_fus!(SignedEthTx::new(tx));
let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address());
Box::new(
self.spend_hash_time_locked_payment(signed, swap_contract_address, secret)
.map_err(TransactionErr::PlainError)
.map(TransactionEnum::from),
)
}
Expand All @@ -789,12 +794,13 @@ impl SwapOps for EthCoin {
_htlc_privkey: &[u8],
swap_contract_address: &Option<BytesJson>,
) -> TransactionFut {
let tx: UnverifiedTransaction = try_fus!(rlp::decode(taker_payment_tx));
let signed = try_fus!(SignedEthTx::new(tx));
let swap_contract_address = try_fus!(swap_contract_address.try_to_address());
let tx: UnverifiedTransaction = try_tx_fus!(rlp::decode(taker_payment_tx));
let signed = try_tx_fus!(SignedEthTx::new(tx));
let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address());

Box::new(
self.refund_hash_time_locked_payment(swap_contract_address, signed)
Comment thread
sergeyboyko0791 marked this conversation as resolved.
.map_err(TransactionErr::PlainError)
.map(TransactionEnum::from),
)
}
Expand All @@ -808,12 +814,13 @@ impl SwapOps for EthCoin {
_htlc_privkey: &[u8],
swap_contract_address: &Option<BytesJson>,
) -> TransactionFut {
let tx: UnverifiedTransaction = try_fus!(rlp::decode(maker_payment_tx));
let signed = try_fus!(SignedEthTx::new(tx));
let swap_contract_address = try_fus!(swap_contract_address.try_to_address());
let tx: UnverifiedTransaction = try_tx_fus!(rlp::decode(maker_payment_tx));
let signed = try_tx_fus!(SignedEthTx::new(tx));
let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address());

Box::new(
self.refund_hash_time_locked_payment(swap_contract_address, signed)
.map_err(TransactionErr::PlainError)
.map(TransactionEnum::from),
)
}
Expand Down Expand Up @@ -1138,6 +1145,16 @@ impl MarketCoinOps for EthCoin {
)
}

fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box<dyn Future<Item = String, Error = String> + Send> {
Box::new(
self.web3
.eth()
.send_raw_transaction(tx.into())
.map(|res| format!("{:02x}", res))
.map_err(|e| ERRL!("{}", e)),
)
}

fn wait_for_confirmations(
&self,
tx: &[u8],
Expand Down Expand Up @@ -1215,17 +1232,17 @@ impl MarketCoinOps for EthCoin {
from_block: u64,
swap_contract_address: &Option<BytesJson>,
) -> TransactionFut {
let unverified: UnverifiedTransaction = try_fus!(rlp::decode(tx_bytes));
let tx = try_fus!(SignedEthTx::new(unverified));
let swap_contract_address = try_fus!(swap_contract_address.try_to_address());
let unverified: UnverifiedTransaction = try_tx_fus!(rlp::decode(tx_bytes));
let tx = try_tx_fus!(SignedEthTx::new(unverified));
let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address());

let func_name = match self.coin_type {
EthCoinType::Eth => "ethPayment",
EthCoinType::Erc20 { .. } => "erc20Payment",
};

let payment_func = try_fus!(SWAP_CONTRACT.function(func_name));
let decoded = try_fus!(payment_func.decode_input(&tx.data));
let payment_func = try_tx_fus!(SWAP_CONTRACT.function(func_name));
let decoded = try_tx_fus!(payment_func.decode_input(&tx.data));
let id = match &decoded[0] {
Token::FixedBytes(bytes) => bytes.clone(),
_ => panic!(),
Expand Down Expand Up @@ -1280,15 +1297,15 @@ impl MarketCoinOps for EthCoin {
},
};

return Ok(TransactionEnum::from(try_s!(signed_tx_from_web3_tx(transaction))));
return Ok(TransactionEnum::from(try_tx_s!(signed_tx_from_web3_tx(transaction))));
}
}

if now_ms() / 1000 > wait_until {
return ERR!(
return TX_ERR!(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that TX_ERR returns TransactionErr::PlainError. So what do you think about renaming it to TX_PLAIN_ERR?
Also I'd suggest using snake_case for macros. I know that we use ERR a lot, so that there is no confusion, we can leave it as SCREAMING_SNAKE_CASE. I leave it up to you :)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, macros normally have snake_case naming convention, but here we are providing a compatibility for a macro that is already exists. We have to change all of them to avoid confusion(which we will do for #1247 ).

"Waited too long until {} for transaction {:?} to be spent ",
wait_until,
tx
tx,
);
}
Timer::sleep(5.).await;
Expand Down
9 changes: 9 additions & 0 deletions mm2src/coins/lightning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,15 @@ impl MarketCoinOps for LightningCoin {
))
}

fn send_raw_tx_bytes(&self, _tx: &[u8]) -> Box<dyn Future<Item = String, Error = String> + Send> {
Box::new(futures01::future::err(
MmError::new(
"send_raw_tx is not supported for lightning, please use send_payment method instead.".to_string(),
)
.to_string(),
))
}

// Todo: Implement this when implementing swaps for lightning as it's is used mainly for swaps
fn wait_for_confirmations(
&self,
Expand Down
73 changes: 71 additions & 2 deletions mm2src/coins/lp_coins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,43 @@ macro_rules! try_f {
};
}

/// `TransactionErr:PlainError` compatible `try_fus` macro.
macro_rules! try_tx_fus {
($e: expr) => {
match $e {
Ok(ok) => ok,
Err(err) => {
return Box::new(futures01::future::err(crate::TransactionErr::PlainError(ERRL!(
"{:?}", err
))))
},
}
};
}

/// `TransactionErr:PlainError` compatible `try_s` macro.
macro_rules! try_tx_s {
($e: expr) => {
match $e {
Ok(ok) => ok,
Err(err) => {
return Err(crate::TransactionErr::PlainError(format!(
"{}:{}] {:?}",
file!(),
line!(),
err
)))
},
}
};
}

/// `TransactionErr:PlainError` compatible `ERR` macro.
macro_rules! TX_ERR {
($format: expr, $($args: tt)+) => { Err(crate::TransactionErr::PlainError((ERRL!($format, $($args)+)))) };
($format: expr) => { Err(crate::TransactionErr::PlainError(ERRL!($format))) }
}

pub mod coin_balance;
#[doc(hidden)]
#[cfg(test)]
Expand Down Expand Up @@ -276,7 +313,36 @@ impl Deref for TransactionEnum {
}
}

pub type TransactionFut = Box<dyn Future<Item = TransactionEnum, Error = String> + Send>;
#[derive(Debug, Clone)]
#[allow(clippy::large_enum_variant)]
pub enum TransactionErr {
/// Keeps transactions while throwing errors.
TxRecoverableError(TransactionEnum, String),
/// Simply for plain error messages.
PlainError(String),
}

impl TransactionErr {
/// Returns transaction if the error includes it.
#[inline]
pub fn get_tx(&self) -> Option<TransactionEnum> {
match self {
TransactionErr::TxRecoverableError(tx, _) => Some(tx.clone()),
_ => None,
}
}

#[inline]
/// Returns plain text part of error.
pub fn get_plain_text_format(&self) -> String {
match self {
TransactionErr::TxRecoverableError(_, err) => err.to_string(),
TransactionErr::PlainError(err) => err.to_string(),
}
}
}

pub type TransactionFut = Box<dyn Future<Item = TransactionEnum, Error = TransactionErr> + Send>;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please consider this comment? #1258 (comment)
If you have a different point of view, I'll accept it 🙂

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think both ways are fine. Declaring on top of the module or just keep them close to it's couples. But, have to apply only one of them in the project, otherwise it will complicate things more.

@artemii235 which way we should follow? The choice will effect all the project (either all the types will move to the top, or will move to it's couple structs/functions).


#[derive(Debug, PartialEq)]
pub enum FoundSwapTxSpend {
Expand Down Expand Up @@ -473,6 +539,9 @@ pub trait MarketCoinOps {
/// Receives raw transaction bytes in hexadecimal format as input and returns tx hash in hexadecimal format
fn send_raw_tx(&self, tx: &str) -> Box<dyn Future<Item = String, Error = String> + Send>;

/// Receives raw transaction bytes as input and returns tx hash in hexadecimal format
fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box<dyn Future<Item = String, Error = String> + Send>;

fn wait_for_confirmations(
&self,
tx: &[u8],
Expand Down Expand Up @@ -735,7 +804,7 @@ impl Default for TransactionType {
/// Transaction details
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct TransactionDetails {
/// Raw bytes of signed transaction in hexadecimal string, this should be sent as is to send_raw_transaction RPC to broadcast the transaction
/// Raw bytes of signed transaction, this should be sent as is to `send_raw_transaction_bytes` RPC to broadcast the transaction
pub tx_hex: BytesJson,
/// Transaction hash in hexadecimal format
tx_hash: String,
Expand Down
Loading