-
Notifications
You must be signed in to change notification settings - Fork 94
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
[r2r] validate swap parameters #1475
Conversation
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.
Good job!
Please fix a few moments
mm2src/coins/eth.rs
Outdated
} | ||
} | ||
|
||
fn validate_secret_hash(&self, secret_hash: &[u8], secret: &[u8]) -> bool { secret_hash == secret } |
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.
It can be simply done at the maker_swap.rs
and taker_swap.rs
modules
@@ -1353,3 +1353,172 @@ fn test_sign_verify_message() { | |||
.unwrap(); | |||
assert!(is_valid); | |||
} | |||
|
|||
#[test] | |||
fn test_eth_extract_secret() { |
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.
Is this test related to validation of the other pubkey?
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.
as there was not any test for extract_secret
in eth module I decided to add one..should I remove?
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.
No, let's keep it, thanks!
mm2src/coins/eth/eth_tests.rs
Outdated
} | ||
|
||
#[test] | ||
fn test_eth_validate_valid_and_invalid_secret_hash() { |
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.
So this test can be removed :)
mm2src/coins/qrc20/qrc20_tests.rs
Outdated
} | ||
|
||
#[test] | ||
fn test_qrc20_validate_valid_and_invalid_secret_hash() { |
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 is also can be removed
// Validate maker_coin_htlc_pubkey realness | ||
match self.taker_coin.validate_other_pubkey(taker_data.maker_coin_htlc_pub()) { | ||
Ok(_) => (), | ||
Err(err) => { |
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.
Please consider using if let Err(err) = ...
statement here
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.
ok done
}; | ||
|
||
// Validate taker_coin_htlc_pubkey realness | ||
match self.taker_coin.validate_other_pubkey(taker_data.taker_coin_htlc_pub()) { |
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.
Here's correct, our taker_coin
should validate the other's taker_coin_htlc_pub
.
// Validate taker_coin_htlc_pubkey realness | ||
match self.taker_coin.validate_other_pubkey(taker_data.taker_coin_htlc_pub()) { | ||
Ok(_) => (), | ||
Err(err) => { |
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.
Here the same please:
Please consider using
if let Err(err) = ...
statement here
@@ -963,6 +963,15 @@ impl TakerSwap { | |||
)])); | |||
} | |||
|
|||
if !self | |||
.maker_coin | |||
.validate_secret_hash(maker_data.secret_hash(), self.r().secret.0.as_slice()) |
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.
As I suggested above, we can simply check if maker_data.secret_hash() == self.r().secret.0
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.
done
match self.taker_coin.validate_other_pubkey(maker_data.maker_coin_htlc_pub()) { | ||
Ok(_) => (), | ||
Err(err) => { | ||
return Ok((Some(TakerSwapCommand::Finish), vec![TakerSwapEvent::NegotiateFailed( | ||
ERRL!("!maker_data.maker_coin_htlc_pub {}", err).into(), | ||
)])) | ||
}, | ||
}; | ||
|
||
// Validate taker_coin_htlc_pubkey realness | ||
match self.taker_coin.validate_other_pubkey(maker_data.taker_coin_htlc_pub()) { | ||
Ok(_) => (), | ||
Err(err) => { | ||
return Ok((Some(TakerSwapCommand::Finish), vec![TakerSwapEvent::NegotiateFailed( | ||
ERRL!("!maker_data.taker_coin_htlc_pub {}", err).into(), | ||
)])) | ||
}, | ||
}; |
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.
Same please:
Please consider using if let Err(err) = ... statement here
@@ -986,6 +995,25 @@ impl TakerSwap { | |||
)])) | |||
}, | |||
}; | |||
// Validate maker_coin_htlc_pubkey realness | |||
match self.taker_coin.validate_other_pubkey(maker_data.maker_coin_htlc_pub()) { |
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.
maker_coin
should validate maker_coin_htlc_pub
.
taker_coin
should validate taker_coin_htlc_pub
.
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.
done
45a562f
to
3bea7a1
Compare
fbba2b7
to
b2c2fef
Compare
* enable retry if tx is not available onchain * fixed review notes * fixed failing tests * pr review fixes * set test timeout to 1
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.
Great work! Only two comments
mm2src/coins/qrc20/qrc20_tests.rs
Outdated
@@ -1061,3 +1061,16 @@ fn test_send_contract_calls_recoverable_tx() { | |||
discriminant(&TransactionErr::TxRecoverable(TransactionEnum::from(tx), String::new())) | |||
); | |||
} | |||
|
|||
#[test] | |||
fn test_qrc20_validate_valid_and_invalid_pubkey() { |
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.
Since Qrc20Coin
uses utxo_common::validate_other_pubkey
, we can remove this test.
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.
done
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.
LGTM!
@shamardy could you please review? |
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 also took a quick look at it and have one question.
mm2src/coins/eth/eth_tests.rs
Outdated
erc20_tokens_infos: Default::default(), | ||
})); | ||
|
||
// raw transaction bytes of https://ropsten.etherscan.io/tx/0xe18bbca69dea9a4624e1f5b0b2021d5fe4c8daa03f36084a8ba011b08e5cd938 |
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.
The mentioned transaction calls erc20Payment
of swap contract, so extract_secret
should not be applicable to it. Is there a mistake in the comment?
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.
Nop, the comment is not a mistake. I actually made use of the TX to generate the secret used for the test. I didn't know extract_secret
isn't compatible with swap contract
. Will make changes, thanks
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.
@artemii235 why do you think extract_secret
isn't compatible with swap contract tx?
implementation of extract_secret
for eth..
fn extract_secret(&self, _secret_hash: &[u8], spend_tx: &[u8]) -> Result<Vec<u8>, String> {
let unverified: UnverifiedTransaction = try_s!(rlp::decode(spend_tx));
let function = try_s!(SWAP_CONTRACT.function("receiverSpend"));
let tokens = try_s!(function.decode_input(&unverified.data));
if tokens.len() < 3 {
return ERR!("Invalid arguments in 'receiverSpend' call: {:?}", tokens);
}
match &tokens[2] {
Token::FixedBytes(secret) => Ok(secret.to_vec()),
_ => ERR!(
"Expected secret to be fixed bytes, decoded function data is {:?}",
tokens
),
}
}
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.
The mentioned transaction https://ropsten.etherscan.io/tx/0xe18bbca69dea9a4624e1f5b0b2021d5fe4c8daa03f36084a8ba011b08e5cd938 calls erc20Payment
smart contract function.
While extract_secret
should be called on the transaction calling receiverSpend
(e.g. https://ropsten.etherscan.io/tx/0x432935be34424a0aa0403061652be8522da5b8637a6e499325ea910c430cd97d) - the name is actually hard-coded in extract_secret
. It shouldn't have worked at all, but it somehow decodes the function input bytes and returns the token address padded with 12 zero bytes. There should be a bug in decode_input
function - I added it in my fork of ethabi
crate.
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.
Oh great, thanks 👍
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.
What's interesting: even the most recent official ethabi
release doesn't seem to perform any validation that the input is actually from the original fn: https://github.com/rust-ethereum/ethabi/blob/6f18e11621d29b6cd978ef39b48fa572b823bb80/ethabi/src/function.rs#L78. The code expects input without 4 bytes of short signature (partial hash of the function name). So we have to implement additional validation in our code. #1494
@artemii235, I have made changes to this PR. You can now review again. thanks |
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.
Great work, thanks!
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.
Re-approve!
@borngraced I'm currently checking how to fix ETH tests. Will let you know when I get an answer. |
@borngraced let's wait for #1495 is merged |
Validated
maker_coin_htlc_pub
andtaker_coin_htlc_pub
on Maker sideValidated
maker_coin_htlc_pub
andtaker_coin_htlc_pub
andsecret_hash
on Taker sidefixes: #1458