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

Create custom addHexPrefix function #9306

Merged
merged 14 commits into from
Nov 6, 2020

Conversation

PatrykLucka
Copy link
Contributor

Creates custom addHexPrefix function. The one provided by ethereumjs-util does not handle incorrect eth address hex formats such us starting with - or 0X.

Fixes #9262

@PatrykLucka PatrykLucka requested a review from a team as a code owner August 25, 2020 11:41
@PatrykLucka PatrykLucka requested a review from rekmarks August 25, 2020 11:41
app/scripts/lib/util.js Outdated Show resolved Hide resolved
app/scripts/lib/util.js Outdated Show resolved Hide resolved
ui/app/hooks/useCancelTransaction.js Outdated Show resolved Hide resolved
@PatrykLucka PatrykLucka requested a review from Gudahtt August 28, 2020 09:30
@PatrykLucka PatrykLucka force-pushed the create-custom-addHexPrefix branch from 2e716ed to 5732479 Compare September 7, 2020 13:57
@github-actions
Copy link
Contributor

github-actions bot commented Sep 7, 2020

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

Copy link
Member

@Gudahtt Gudahtt left a comment

Choose a reason for hiding this comment

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

Does it make sens to allow negative numbers anywhere we're using addHexPrefix? Addresses can't be negative, and neither can the gas price, gas limit, private key, balance, nonce, etc. Or at least not that I know of... maybe there's some type of network out there that supports negative gas price/limit or balance 🤔

If there are no valid cases for having a negative number, maybe this is better addressed with additional validation.

@@ -17,7 +17,7 @@ import { getConversionRate, getSelectedAccount } from '../selectors'
*/
export function useCancelTransaction (transactionGroup) {
const { primaryTransaction, initialTransaction } = transactionGroup
const gasPrice = primaryTransaction.txParams?.gasPrice
const gasPrice = parseInt(primaryTransaction.txParams?.gasPrice, 16) < 0 ? '0x0' : primaryTransaction.txParams?.gasPrice
Copy link
Member

Choose a reason for hiding this comment

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

Is this necessary for cancellation transactions? These should only be possible by using our UI, and I didn't think we allowed a negative gas price there 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would have to check that, but I'm pretty sure I added this change to allow users to "repair" their extension after getting error. I had to reinstall MM to make it work again, even with other updates, but with this change, when opening MM gas price of pending transaction was changed to 0 (instead of negative number) and it was fixing the problem. Does it make sense?

@PatrykLucka
Copy link
Contributor Author

It was reported in #9262. Even if in theory there shouldn't be such situation, there is an option in our UI to set gas price < 0. Additional validation sounds good, but there could be some other ways to make one of the processed numbers negative and as result crashing whole app. The only way to make it work again is to reinstall extension.

@Gudahtt
Copy link
Member

Gudahtt commented Sep 8, 2020

The reproduction example in #9262 shows the negative gas price being set by a dapp, not via our UI. We already reject incoming messages outright in some cases where they fail validation, so this seems like a case where this validation should be expanded

@danjm danjm added this to the v8.1.next? milestone Nov 2, 2020
@PatrykLucka PatrykLucka force-pushed the create-custom-addHexPrefix branch from 5732479 to 061a71d Compare November 4, 2020 11:38
@PatrykLucka PatrykLucka force-pushed the create-custom-addHexPrefix branch from 9de17f7 to 2ba32e8 Compare November 5, 2020 11:40
app/scripts/lib/util.js Outdated Show resolved Hide resolved
app/scripts/lib/util.js Outdated Show resolved Hide resolved
app/scripts/lib/util.js Outdated Show resolved Hide resolved
app/scripts/lib/util.js Outdated Show resolved Hide resolved
app/scripts/lib/util.js Outdated Show resolved Hide resolved
Comment on lines 23 to 26
const gasPrice =
primaryTransaction.txParams?.gasPrice?.startsWith('-')
? '0x0'
: primaryTransaction.txParams?.gasPrice
Copy link
Member

@rekmarks rekmarks Nov 5, 2020

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

This is only labeled as outdated due to linting.

Comment on lines +165 to +185
/**
* Prefixes a hex string with '0x' or '-0x' and returns it. Idempotent.
*
* @param {string} str - The string to prefix.
* @returns {string} The prefixed string.
*/
const addHexPrefix = (str) => {
if (typeof str !== 'string' || str.match(/^-?0x/u)) {
return str
}

if (str.match(/^-?0X/u)) {
return str.replace('0X', '0x')
}

if (str.startsWith('-')) {
return str.replace('-', '-0x')
}

return `0x${str}`
}
Copy link
Member

@rekmarks rekmarks Nov 5, 2020

Choose a reason for hiding this comment

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

rekmarks
rekmarks previously approved these changes Nov 5, 2020
Copy link
Member

@rekmarks rekmarks left a comment

Choose a reason for hiding this comment

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

I think this is good to go, but since I made some edits I'll ask for a second review.

@@ -173,13 +162,47 @@ function isPrefixedFormattedHexString(value) {
return /^0x[1-9a-f]+[0-9a-f]*$/iu.test(value)
}

/**
* Prefixes a hex string with '0x' or '-0x' and returns it. Idempotent.
Copy link
Contributor

Choose a reason for hiding this comment

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

Very nice use of the word "Idempotent" 🙌

Copy link
Contributor

@danjm danjm left a comment

Choose a reason for hiding this comment

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

This code looks good. Approving.

But I think the original issue that motivated this also requires us to make a change so that gas price validation happens on gas prices suggested by the dapp. At least on ethereum mainnet, we should make sure no transaction can be submitted with a gas price we know will fail. We do prevent this when the user is manually editing gas, but we don't on the submit button on the confirm screen. This should be handled in another PR.

@Gudahtt
Copy link
Member

Gudahtt commented Nov 6, 2020

we should make sure no transaction can be submitted with a gas price we know will fail.

I don't think this was the case here. It's not that we knew the price would fail - it's that it was an invalid price, and it crashed our UI. The validation we need here is in our dapp request handling, and it should have been rejected outright without showing the user anything, just as we do with other malformed requests.

I think we could avoid all of this work by some combination of request validation and migrating the state of pending transaction confirmations to remove negative gas prices. I'm not against this being merged in the meantime, but handling invalid types mid-operation is not a great approach in general - we should verify our assumptions about this data at the boundaries rather than within the app. This is only one place where a negative gas price caused things to blow up after all - there may be others that remain unaddressed.

@danjm
Copy link
Contributor

danjm commented Nov 6, 2020

Well if we did ensure that 'no transaction can be submitted with a gas price we know will fail', this particular case would have been avoided. This doesn't invalidate anything else @Gudahtt said in the above comment, but this issue also points to the need to check whether gas prices that come from dapps are too low.

@danjm
Copy link
Contributor

danjm commented Nov 6, 2020

Actually, my comment that "Well if we did ensure that 'no transaction can be submitted with a gas price we know will fail', this particular case would have been avoided" was wrong. This issue happens on render of confirmation screen, not after submit which I previously thought.

However, I think that "this issue also points to the need to check whether gas prices that come from dapps are too low" holds true. I didn't realize, or had forgotten, that gas price set via rpc methods would be the gas price used in our confirmation screen. I now realize that this comment is tangential to this PR, but we should also add front end validation and error messaging for gas prices that are valid prices, but guaranteed to fail.

@rekmarks rekmarks merged commit ee205b8 into MetaMask:develop Nov 6, 2020
@github-actions github-actions bot locked and limited conversation to collaborators Nov 6, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Sending a tx with a negative gas crashes MetaMask both on FF(8.0.8) and Chrome(8.0.7).
4 participants