-
Notifications
You must be signed in to change notification settings - Fork 97
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
fix(tpu-v2): fix tpu-v2 wait for payment spend and extract secret #2261
base: dev
Are you sure you want to change the base?
Changes from 10 commits
9d7f476
de3a970
ea5475b
934a2f0
ca0ee56
9449cca
2e65abf
43a1baf
c700b59
8d5ed46
707946a
1e7a197
fb383fb
9ec0bab
6c8b2c1
6dcb1c3
f817f5c
ddac3c8
f437dde
02736e4
a08b500
24cb4c3
5f666f3
47f904c
2056f9b
0b3ab9a
cf76cab
c1a5063
43c2d94
0ffffd9
c60a06f
7160045
6201aae
0877d06
d3e6ae1
90b80a3
17b1c94
2df4dd9
a2a448f
95a2b2b
673cd11
e3b4132
9007f12
9d5beeb
5bd4ee2
2d80017
46212fa
ae56f2d
b9cef2b
ac9a5a3
ab56a12
0ca61fd
653e074
f8ba975
0a5ff84
ec0d13c
b04f217
a9f481c
67321a6
41f20f9
43a0b8b
49f46e0
869019b
0f31d07
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,12 +1,13 @@ | ||||||||||||||||||||||||||||||||||||||||||||
use super::{check_decoded_length, validate_amount, validate_from_to_and_status, validate_payment_state, | ||||||||||||||||||||||||||||||||||||||||||||
EthPaymentType, PaymentMethod, PrepareTxDataError, ZERO_VALUE}; | ||||||||||||||||||||||||||||||||||||||||||||
use crate::eth::{decode_contract_call, get_function_input_data, wei_from_big_decimal, EthCoin, EthCoinType, | ||||||||||||||||||||||||||||||||||||||||||||
ParseCoinAssocTypes, RefundFundingSecretArgs, RefundTakerPaymentArgs, SendTakerFundingArgs, | ||||||||||||||||||||||||||||||||||||||||||||
SignedEthTx, SwapTxTypeWithSecretHash, TakerPaymentStateV2, TransactionErr, ValidateSwapV2TxError, | ||||||||||||||||||||||||||||||||||||||||||||
ValidateSwapV2TxResult, ValidateTakerFundingArgs, TAKER_SWAP_V2}; | ||||||||||||||||||||||||||||||||||||||||||||
use crate::{FundingTxSpend, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, SearchForFundingSpendErr, | ||||||||||||||||||||||||||||||||||||||||||||
WaitForPaymentSpendError}; | ||||||||||||||||||||||||||||||||||||||||||||
use crate::eth::{decode_contract_call, get_function_input_data, signed_tx_from_web3_tx, wei_from_big_decimal, EthCoin, | ||||||||||||||||||||||||||||||||||||||||||||
EthCoinType, ParseCoinAssocTypes, RefundFundingSecretArgs, RefundTakerPaymentArgs, | ||||||||||||||||||||||||||||||||||||||||||||
SendTakerFundingArgs, SignedEthTx, SwapTxTypeWithSecretHash, TakerPaymentStateV2, TransactionErr, | ||||||||||||||||||||||||||||||||||||||||||||
ValidateSwapV2TxError, ValidateSwapV2TxResult, ValidateTakerFundingArgs, TAKER_SWAP_V2}; | ||||||||||||||||||||||||||||||||||||||||||||
use crate::{FindPaymentSpendError, FundingTxSpend, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, MarketCoinOps, | ||||||||||||||||||||||||||||||||||||||||||||
SearchForFundingSpendErr}; | ||||||||||||||||||||||||||||||||||||||||||||
use common::executor::Timer; | ||||||||||||||||||||||||||||||||||||||||||||
use common::log::{error, info}; | ||||||||||||||||||||||||||||||||||||||||||||
use common::now_sec; | ||||||||||||||||||||||||||||||||||||||||||||
use ethabi::{Function, Token}; | ||||||||||||||||||||||||||||||||||||||||||||
use ethcore_transaction::Action; | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -15,7 +16,7 @@ use ethkey::public_to_address; | |||||||||||||||||||||||||||||||||||||||||||
use futures::compat::Future01CompatExt; | ||||||||||||||||||||||||||||||||||||||||||||
use mm2_err_handle::prelude::{MapToMmResult, MmError, MmResult}; | ||||||||||||||||||||||||||||||||||||||||||||
use std::convert::TryInto; | ||||||||||||||||||||||||||||||||||||||||||||
use web3::types::TransactionId; | ||||||||||||||||||||||||||||||||||||||||||||
use web3::types::{BlockNumber, FilterBuilder, Log, TransactionId}; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
const ETH_TAKER_PAYMENT: &str = "ethTakerPayment"; | ||||||||||||||||||||||||||||||||||||||||||||
const ERC20_TAKER_PAYMENT: &str = "erc20TakerPayment"; | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -457,37 +458,120 @@ impl EthCoin { | |||||||||||||||||||||||||||||||||||||||||||
Ok(spend_payment_tx) | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
/// Checks that taker payment state is `MakerSpent`. | ||||||||||||||||||||||||||||||||||||||||||||
/// Accepts maker spent payment transaction and returns it if payment status is correct. | ||||||||||||||||||||||||||||||||||||||||||||
pub(crate) async fn wait_for_taker_payment_spend_impl( | ||||||||||||||||||||||||||||||||||||||||||||
pub(crate) async fn find_taker_payment_spend_tx_impl( | ||||||||||||||||||||||||||||||||||||||||||||
&self, | ||||||||||||||||||||||||||||||||||||||||||||
taker_payment: &SignedEthTx, | ||||||||||||||||||||||||||||||||||||||||||||
taker_payment: &SignedEthTx, // it's approve_tx in Eth case, as in sign_and_send_taker_funding_spend we return approve_tx tx for it | ||||||||||||||||||||||||||||||||||||||||||||
from_block: u64, | ||||||||||||||||||||||||||||||||||||||||||||
wait_until: u64, | ||||||||||||||||||||||||||||||||||||||||||||
) -> MmResult<SignedEthTx, WaitForPaymentSpendError> { | ||||||||||||||||||||||||||||||||||||||||||||
let (decoded, taker_swap_v2_contract) = self | ||||||||||||||||||||||||||||||||||||||||||||
.get_decoded_and_swap_contract(taker_payment, "spendTakerPayment") | ||||||||||||||||||||||||||||||||||||||||||||
.await?; | ||||||||||||||||||||||||||||||||||||||||||||
check_every: f64, | ||||||||||||||||||||||||||||||||||||||||||||
) -> MmResult<SignedEthTx, FindPaymentSpendError> { | ||||||||||||||||||||||||||||||||||||||||||||
let taker_swap_v2_contract = self | ||||||||||||||||||||||||||||||||||||||||||||
.swap_v2_contracts | ||||||||||||||||||||||||||||||||||||||||||||
.as_ref() | ||||||||||||||||||||||||||||||||||||||||||||
.map(|contracts| contracts.taker_swap_v2_contract) | ||||||||||||||||||||||||||||||||||||||||||||
.ok_or_else(|| { | ||||||||||||||||||||||||||||||||||||||||||||
FindPaymentSpendError::Internal("Expected swap_v2_contracts to be Some, but found None".to_string()) | ||||||||||||||||||||||||||||||||||||||||||||
})?; | ||||||||||||||||||||||||||||||||||||||||||||
borngraced marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||
let approve_func = TAKER_SWAP_V2.function(TAKER_PAYMENT_APPROVE)?; | ||||||||||||||||||||||||||||||||||||||||||||
let decoded = decode_contract_call(approve_func, taker_payment.unsigned().data())?; | ||||||||||||||||||||||||||||||||||||||||||||
let id = match decoded.first() { | ||||||||||||||||||||||||||||||||||||||||||||
Some(Token::FixedBytes(bytes)) => bytes, | ||||||||||||||||||||||||||||||||||||||||||||
invalid_token => { | ||||||||||||||||||||||||||||||||||||||||||||
return MmError::err(FindPaymentSpendError::InvalidData(format!( | ||||||||||||||||||||||||||||||||||||||||||||
"Expected Token::FixedBytes, got {:?}", | ||||||||||||||||||||||||||||||||||||||||||||
invalid_token | ||||||||||||||||||||||||||||||||||||||||||||
))) | ||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||
// loop to find maker's spendTakerPayment transaction | ||||||||||||||||||||||||||||||||||||||||||||
loop { | ||||||||||||||||||||||||||||||||||||||||||||
let taker_status = self | ||||||||||||||||||||||||||||||||||||||||||||
.payment_status_v2( | ||||||||||||||||||||||||||||||||||||||||||||
taker_swap_v2_contract, | ||||||||||||||||||||||||||||||||||||||||||||
decoded[0].clone(), // id from spendTakerPayment | ||||||||||||||||||||||||||||||||||||||||||||
&TAKER_SWAP_V2, | ||||||||||||||||||||||||||||||||||||||||||||
EthPaymentType::TakerPayments, | ||||||||||||||||||||||||||||||||||||||||||||
TAKER_PAYMENT_STATE_INDEX, | ||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||
.await?; | ||||||||||||||||||||||||||||||||||||||||||||
if taker_status == U256::from(TakerPaymentStateV2::MakerSpent as u8) { | ||||||||||||||||||||||||||||||||||||||||||||
return Ok(taker_payment.clone()); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
let now = now_sec(); | ||||||||||||||||||||||||||||||||||||||||||||
if now > wait_until { | ||||||||||||||||||||||||||||||||||||||||||||
return MmError::err(WaitForPaymentSpendError::Timeout { wait_until, now }); | ||||||||||||||||||||||||||||||||||||||||||||
return MmError::err(FindPaymentSpendError::Timeout { wait_until, now }); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
Timer::sleep(10.).await; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
let current_block = match self.current_block().compat().await { | ||||||||||||||||||||||||||||||||||||||||||||
Ok(b) => b, | ||||||||||||||||||||||||||||||||||||||||||||
Err(e) => { | ||||||||||||||||||||||||||||||||||||||||||||
error!("Error getting block number: {}", e); | ||||||||||||||||||||||||||||||||||||||||||||
Timer::sleep(5.).await; | ||||||||||||||||||||||||||||||||||||||||||||
continue; | ||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
// get all logged TakerPaymentSpent events from `from_block` till current block | ||||||||||||||||||||||||||||||||||||||||||||
let events = match self | ||||||||||||||||||||||||||||||||||||||||||||
.events_from_block(taker_swap_v2_contract, "TakerPaymentSpent", from_block, current_block) | ||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldn't we advance There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Shouldn't change blocks range, It introduces risks to skip necessary block. Receiving empty events list does not necessarily indicate that there are no events, network latency can cause delays in the propagation and indexing of event logs even after a transaction is mined. Also we dont know all the nuances and differences of all blockchains. It is much safer to keep block range starting from swap start block. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. UPD: l suggest to add
dimxy marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||
.await | ||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||
Ok(events) => events, | ||||||||||||||||||||||||||||||||||||||||||||
Err(e) => { | ||||||||||||||||||||||||||||||||||||||||||||
error!( | ||||||||||||||||||||||||||||||||||||||||||||
"Error getting TakerPaymentSpent events from {} block: {}", | ||||||||||||||||||||||||||||||||||||||||||||
from_block, e | ||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||
Timer::sleep(5.).await; | ||||||||||||||||||||||||||||||||||||||||||||
continue; | ||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
if events.is_empty() { | ||||||||||||||||||||||||||||||||||||||||||||
info!( | ||||||||||||||||||||||||||||||||||||||||||||
"No events found yet for the block range {} to {}", | ||||||||||||||||||||||||||||||||||||||||||||
from_block, current_block | ||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||
Timer::sleep(5.).await; | ||||||||||||||||||||||||||||||||||||||||||||
continue; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
// this is how spent event looks like in EtomicSwapTakerV2: event TakerPaymentSpent(bytes32 id, bytes32 secret) | ||||||||||||||||||||||||||||||||||||||||||||
let found_event = events.into_iter().find(|event| &event.data.0[..32] == id.as_slice()); | ||||||||||||||||||||||||||||||||||||||||||||
dimxy marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
if let Some(event) = found_event { | ||||||||||||||||||||||||||||||||||||||||||||
if let Some(tx_hash) = event.transaction_hash { | ||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will this ever be None? will this be a recoverable state then? otherwise we can terminate early. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
are you talking about
For TPU V2 we aim to have automatic recover process, if komodo-defi-framework/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs Lines 1698 to 1716 in c700b59
Could clarify what do you mean by termination? You want to return error and break loop? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
aren't we getting events till the current mined block? so this tx shouldn't be pending?
I just meant we can not do nothing about the fact that tx hash is none. how I was thinking (which might be wrong) is that some event types don't have a tx hash which means we supplied a bad event id from the beginning meaning that we can't proceed further. this might not be the case though, gotta read more about this, excuse my eth illiteracy 😂 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
yeah, you are right as we are using async fn events_from_block(
&self,
swap_contract_address: Address,
event_name: &str,
from_block: u64,
to_block: u64,
) -> MmResult<Vec<Log>, FindPaymentSpendError> {
let contract_event = TAKER_SWAP_V2.event(event_name)?;
let filter = FilterBuilder::default()
.topics(Some(vec![contract_event.signature()]), None, None, None)
.from_block(BlockNumber::Number(from_block.into()))
.to_block(BlockNumber::Number(to_block.into()))
.address(vec![swap_contract_address])
.build();
let events_logs = self
.logs(filter)
.await
.map_err(|e| FindPaymentSpendError::Transport(e.to_string()))?;
Ok(events_logs)
}
I think you are confused a bit. Events/logs themselves don't necessarily contain the transaction hash. Instead, the transaction hash is associated with the transaction that emitted the event. So Log type from web3 just contains info about tx which emitted this log. Note about event and log words. event in Solidity is a way for a contract to emit logs during the execution of a function. So using from to block range we are looking for Log which was emitted by spend taker payment transaction. As for empty tx hash I would like to refer to previous comment #2261 (comment) empty event list or none transaction_hash are not 100% that there is no tx which we are looking for, it could be just blockchain indexation delays or other reasons. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i will read further regarding the truncated (not necessarily empty? right?) event list issue, any resourced regarding the indexaction delay issues and such would be so helpful! regarding an event not having a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I would say that chain reorganization, network latency, node synchronization lag issues could cause missing information issues. These problems usually temporarily, as I understand. You should wait for more confirmed blocks also try to fetch the info from different nodes.
Logs are not mutable. Also they are tied to transactions. When a transaction calls a smart contract function that emits an event, this event generates log, which is permanently recorded in the blockchain. But there’s a nuance. Lest check doc. According to the documentation https://www.chainnodes.org/docs/ethereum/eth_getLogs, a log from a pending transaction might lack a transaction hash, but when the transaction is confirmed, the log should include it. Therefore, ideally, when we request a list of logs using the komodo-defi-framework/mm2src/coins/eth/eth_swap_v2/eth_taker_swap_v2.rs Lines 530 to 531 in 8d5ed46
We dont need to change from_block. However, if Log has There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some additional info https://docs.alchemy.com/docs/deep-dive-into-eth_getlogs#what-are-logs-or-events
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
im missing u between the lines here so let me repeat that to you and see if i got it correctly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, in the context of not using "pending" tag in "eth_getLogs" API, we expect
dimxy marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||
let transaction = match self.transaction(TransactionId::Hash(tx_hash)).await { | ||||||||||||||||||||||||||||||||||||||||||||
Ok(Some(t)) => t, | ||||||||||||||||||||||||||||||||||||||||||||
Ok(None) => { | ||||||||||||||||||||||||||||||||||||||||||||
info!("Tx {} not found yet", tx_hash); | ||||||||||||||||||||||||||||||||||||||||||||
dimxy marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||
Timer::sleep(check_every).await; | ||||||||||||||||||||||||||||||||||||||||||||
continue; | ||||||||||||||||||||||||||||||||||||||||||||
mariocynicys marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||
Err(e) => { | ||||||||||||||||||||||||||||||||||||||||||||
error!("Get tx {} error: {}", tx_hash, e); | ||||||||||||||||||||||||||||||||||||||||||||
Timer::sleep(check_every).await; | ||||||||||||||||||||||||||||||||||||||||||||
continue; | ||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||
let result = signed_tx_from_web3_tx(transaction).map_err(FindPaymentSpendError::Internal)?; | ||||||||||||||||||||||||||||||||||||||||||||
return Ok(result); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
Timer::sleep(5.).await; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
async fn events_from_block( | ||||||||||||||||||||||||||||||||||||||||||||
&self, | ||||||||||||||||||||||||||||||||||||||||||||
swap_contract_address: Address, | ||||||||||||||||||||||||||||||||||||||||||||
event_name: &str, | ||||||||||||||||||||||||||||||||||||||||||||
from_block: u64, | ||||||||||||||||||||||||||||||||||||||||||||
to_block: u64, | ||||||||||||||||||||||||||||||||||||||||||||
) -> MmResult<Vec<Log>, FindPaymentSpendError> { | ||||||||||||||||||||||||||||||||||||||||||||
let contract_event = TAKER_SWAP_V2.event(event_name)?; | ||||||||||||||||||||||||||||||||||||||||||||
let filter = FilterBuilder::default() | ||||||||||||||||||||||||||||||||||||||||||||
.topics(Some(vec![contract_event.signature()]), None, None, None) | ||||||||||||||||||||||||||||||||||||||||||||
.from_block(BlockNumber::Number(from_block.into())) | ||||||||||||||||||||||||||||||||||||||||||||
.to_block(BlockNumber::Number(to_block.into())) | ||||||||||||||||||||||||||||||||||||||||||||
.address(vec![swap_contract_address]) | ||||||||||||||||||||||||||||||||||||||||||||
.build(); | ||||||||||||||||||||||||||||||||||||||||||||
let events_logs = self | ||||||||||||||||||||||||||||||||||||||||||||
.logs(filter) | ||||||||||||||||||||||||||||||||||||||||||||
.await | ||||||||||||||||||||||||||||||||||||||||||||
.map_err(|e| FindPaymentSpendError::Transport(e.to_string()))?; | ||||||||||||||||||||||||||||||||||||||||||||
Ok(events_logs) | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
/// Prepares data for EtomicSwapTakerV2 contract [ethTakerPayment](https://github.com/KomodoPlatform/etomic-swap/blob/5e15641cbf41766cd5b37b4d71842c270773f788/contracts/EtomicSwapTakerV2.sol#L44) method | ||||||||||||||||||||||||||||||||||||||||||||
async fn prepare_taker_eth_funding_data(&self, args: &TakerFundingArgs) -> Result<Vec<u8>, PrepareTxDataError> { | ||||||||||||||||||||||||||||||||||||||||||||
let function = TAKER_SWAP_V2.function(ETH_TAKER_PAYMENT)?; | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -692,6 +776,42 @@ impl EthCoin { | |||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
Ok((decoded, taker_swap_v2_contract)) | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
/// Extracts the maker's secret from the input of transaction that calls the `spendTakerPayment` smart contract method. | ||||||||||||||||||||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||||||||||||||||||||
/// function spendTakerPayment( | ||||||||||||||||||||||||||||||||||||||||||||
/// bytes32 id, | ||||||||||||||||||||||||||||||||||||||||||||
/// uint256 amount, | ||||||||||||||||||||||||||||||||||||||||||||
/// uint256 dexFee, | ||||||||||||||||||||||||||||||||||||||||||||
/// address taker, | ||||||||||||||||||||||||||||||||||||||||||||
/// bytes32 takerSecretHash, | ||||||||||||||||||||||||||||||||||||||||||||
/// bytes32 makerSecret, | ||||||||||||||||||||||||||||||||||||||||||||
/// address tokenAddress | ||||||||||||||||||||||||||||||||||||||||||||
/// ) | ||||||||||||||||||||||||||||||||||||||||||||
pub(crate) async fn extract_secret_v2_impl(&self, spend_tx: &SignedEthTx) -> Result<Vec<u8>, String> { | ||||||||||||||||||||||||||||||||||||||||||||
let function = try_s!(TAKER_SWAP_V2.function("spendTakerPayment")); | ||||||||||||||||||||||||||||||||||||||||||||
// should be 0xcc90c199 | ||||||||||||||||||||||||||||||||||||||||||||
let expected_signature = function.short_signature(); | ||||||||||||||||||||||||||||||||||||||||||||
let signature = &spend_tx.unsigned().data()[0..4]; | ||||||||||||||||||||||||||||||||||||||||||||
if signature != expected_signature { | ||||||||||||||||||||||||||||||||||||||||||||
return ERR!( | ||||||||||||||||||||||||||||||||||||||||||||
"Expected 'spendTakerPayment' contract call signature: {:?}, found {:?}", | ||||||||||||||||||||||||||||||||||||||||||||
expected_signature, | ||||||||||||||||||||||||||||||||||||||||||||
signature | ||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||
let decoded = try_s!(decode_contract_call(function, spend_tx.unsigned().data())); | ||||||||||||||||||||||||||||||||||||||||||||
if decoded.len() < 7 { | ||||||||||||||||||||||||||||||||||||||||||||
return ERR!("Invalid arguments in 'spendTakerPayment' call: {:?}", decoded); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
match &decoded[5] { | ||||||||||||||||||||||||||||||||||||||||||||
Token::FixedBytes(secret) => Ok(secret.to_vec()), | ||||||||||||||||||||||||||||||||||||||||||||
_ => ERR!( | ||||||||||||||||||||||||||||||||||||||||||||
"Expected secret to be fixed bytes, but decoded function data is {:?}", | ||||||||||||||||||||||||||||||||||||||||||||
decoded | ||||||||||||||||||||||||||||||||||||||||||||
), | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
/// Validation function for ETH taker payment data | ||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function can be written in a much better way. Repeatable can be used,
let mut tx_hash: Option<H256> = None;
can be removed andand_then
used instead. It's not easy to review it in the current state.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added it before loop in purpose. Once we find the transaction hash, we can skip re-fetching it in the next cycle iterations if smth go wrong. Its better to keep initialised variable before the loop to save found tx hash
also introduced block windows. As dimxy correctly noticed, providers can have different block limits when we request logs #2261 (comment) , so it's better to search for events using block windows.
Thats why the general function could look complicated.
I will try to split the logic to reutilize functions in new and legacy code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shamardy
after splitting logic into separate functions, there is no need in option variable yes
e3b4132
9007f12