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

[r2r] validate swap parameters #1475

Merged
merged 27 commits into from
Oct 11, 2022
Merged

[r2r] validate swap parameters #1475

merged 27 commits into from
Oct 11, 2022

Conversation

borngraced
Copy link
Member

Validated maker_coin_htlc_pub and taker_coin_htlc_pub on Maker side
Validated maker_coin_htlc_pub and taker_coin_htlc_pub and secret_hash on Taker side

fixes: #1458

@borngraced borngraced changed the title [wip] validate swap parameters [r2r] validate swap parameters Sep 20, 2022
Copy link

@sergeyboyko0791 sergeyboyko0791 left a 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

}
}

fn validate_secret_hash(&self, secret_hash: &[u8], secret: &[u8]) -> bool { secret_hash == secret }

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() {

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?

Copy link
Member Author

@borngraced borngraced Sep 23, 2022

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?

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!

}

#[test]
fn test_eth_validate_valid_and_invalid_secret_hash() {

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 :)

}

#[test]
fn test_qrc20_validate_valid_and_invalid_secret_hash() {

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) => {

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

Copy link
Member Author

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()) {

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) => {

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())

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

Copy link
Member Author

Choose a reason for hiding this comment

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

done

Comment on lines 999 to 1016
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(),
)]))
},
};

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()) {

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@borngraced borngraced changed the title [r2r] validate swap parameters [wip] validate swap parameters Sep 27, 2022
@borngraced borngraced force-pushed the validate_swap_parameters branch 2 times, most recently from fbba2b7 to b2c2fef Compare September 30, 2022 11:46
* enable retry if tx is not available onchain

* fixed review notes

* fixed failing tests

* pr review fixes

* set test timeout to 1
@borngraced borngraced changed the title [wip] validate swap parameters [r2r] validate swap parameters Oct 3, 2022
Copy link

@sergeyboyko0791 sergeyboyko0791 left a 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/utxo/utxo_tests.rs Show resolved Hide resolved
@@ -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() {

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

sergeyboyko0791
sergeyboyko0791 previously approved these changes Oct 5, 2022
Copy link

@sergeyboyko0791 sergeyboyko0791 left a comment

Choose a reason for hiding this comment

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

LGTM!

@sergeyboyko0791
Copy link

@shamardy could you please review?

Copy link
Member

@artemii235 artemii235 left a 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.

erc20_tokens_infos: Default::default(),
}));

// raw transaction bytes of https://ropsten.etherscan.io/tx/0xe18bbca69dea9a4624e1f5b0b2021d5fe4c8daa03f36084a8ba011b08e5cd938
Copy link
Member

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?

Copy link
Member Author

@borngraced borngraced Oct 6, 2022

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

Copy link
Member Author

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
            ),
        }
    }

Copy link
Member

@artemii235 artemii235 Oct 7, 2022

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.
image

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.

cc @sergeyboyko0791

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh great, thanks 👍

Copy link
Member

@artemii235 artemii235 Oct 7, 2022

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

@borngraced
Copy link
Member Author

@artemii235, I have made changes to this PR. You can now review again. thanks

Copy link
Member

@artemii235 artemii235 left a comment

Choose a reason for hiding this comment

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

Great work, thanks!

Copy link

@sergeyboyko0791 sergeyboyko0791 left a comment

Choose a reason for hiding this comment

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

Re-approve!

@sergeyboyko0791
Copy link

@borngraced I'm currently checking how to fix ETH tests. Will let you know when I get an answer.

@sergeyboyko0791
Copy link

@borngraced let's wait for #1495 is merged

@sergeyboyko0791 sergeyboyko0791 merged commit 8e92b9d into dev Oct 11, 2022
@sergeyboyko0791 sergeyboyko0791 deleted the validate_swap_parameters branch October 11, 2022 10:58
@borngraced borngraced mentioned this pull request Feb 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants