Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Explicitly note that existing AccountIdConversion is truncating and add fallible try_into... #10719

Merged
merged 13 commits into from May 17, 2022

Conversation

shawntabrizi
Copy link
Contributor

@shawntabrizi shawntabrizi commented Jan 23, 2022

Closes: #8564
closes: #10812

Tired of running into this problem accidentally when writing tests.

The behavior of AccountIdConversion may occasionally lead to duplicate accounts if the seed provided to generate the account is bigger than the encoded AccountId type. In tests, where accounts are often u64, this can happen, and actually lead to hard to debug behaviors with account balances, and stuff like that.

This updates the API so that the existing behavior is explicitly mentioned, and also provides an alternative try_into... function which can handle such a truncation problem, and explicitly return an error when an infallible operation is not needed.

BREAKS API!

Migration is simple:

Whenever you use into_account or into_sub_account, you must now explicitly choose between into_account_truncating or try_into_account, and if you use the latter, handle the situation where we may return None.

Polkadot companion: paritytech/polkadot#4947
cumulus companion: paritytech/cumulus#1262

@github-actions github-actions bot added the A0-please_review Pull request needs code review. label Jan 23, 2022
@shawntabrizi shawntabrizi added B7-runtimenoteworthy C1-low PR touches the given topic and has a low impact on builders. D2-breaksapi D5-nicetohaveaudit ⚠️ PR contains trivial changes to logic that should be properly reviewed. and removed A0-please_review Pull request needs code review. labels Jan 23, 2022
@shawntabrizi shawntabrizi added this to In progress in Runtime via automation Jan 23, 2022
@ggwpez ggwpez self-requested a review February 9, 2022 13:48
Copy link
Member

@ggwpez ggwpez left a comment

Choose a reason for hiding this comment

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

A test that the truncating works is missing. I can do that later if you are not at it already.

primitives/runtime/src/traits.rs Outdated Show resolved Hide resolved
Copy link
Member

@bkchr bkchr left a comment

Choose a reason for hiding this comment

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

Added some comment and what should be fixed.

I'm not really convinced that this will help in tests, because people will still not get the relation between the input and a short account id. However, it should make the code more correct 👍

if b.len() > T::max_encoded_len() {
return None
};
let account = T::decode(&mut TrailingZeroInput(b))
Copy link
Member

Choose a reason for hiding this comment

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

IMO the check above is wrong, because if you for example have an enum max_encoded_len returns you the length of the biggest enum variant. This is wrong here, just imagine you are decoding the shortest variant and then you would not have consumed all bytes.

If you want to make it correct, you need to extend TrailingZeroInput to be able to check if the given input was consumed completely after having the type decoded.

Copy link
Member

Choose a reason for hiding this comment

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

The AccountId type has constant length, but in general I see that it does not work for all T.
So my proposal of adding a const_encoded_len could also fix this, right?

Copy link
Member

Choose a reason for hiding this comment

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

How do you know that the AccountId has a constant length? AccountId is some generic value that could be anything (one of the reasons for this pr). Just because Polkadot uses AccountId32, it doesn't mean that everyone uses this or is required to use this.

Copy link
Member

@ggwpez ggwpez Feb 21, 2022

Choose a reason for hiding this comment

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

Yes therefore we could add a FixEncodedLen trait analogous to MaxEncodedLen that requires a type to always have the same encoding len.
PS: Probably still better to make it work even for non FixEncodedLen types 😄

Copy link
Contributor

@kianenigma kianenigma May 3, 2022

Choose a reason for hiding this comment

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

+1 using MaxEncodedLen is IMO also wrong. Ideally, you just decode, and check how many bytes where actually used for decoding.

Maybe one trick here could be to decode, then re-encode, and see if we go back to the same bytes. A bit hacky and also assumes reversible encode/decode.

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 did something like what @kianenigma suggested. I check the length of the bytes used for the seed, and check that the length of bytes of the account is greater or equal to, otherwise, we know some bytes were truncated.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks. I also tried my luck on this but could not create a test that the function actually returns Some(). The AccountId type is u64, so an overflow is very likely anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You can just create a mock environment where account id is 32 bytes?

@stale
Copy link

stale bot commented Mar 23, 2022

Hey, is anyone still working on this? Due to the inactivity this issue has been automatically marked as stale. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the A5-stale Pull request did not receive any updates in a long time. No review needed at this stage. Close it. label Mar 23, 2022
@stale stale bot closed this Apr 6, 2022
Runtime automation moved this from In progress to Done Apr 6, 2022
@ggwpez ggwpez mentioned this pull request Apr 8, 2022
4 tasks
@emostov emostov reopened this Apr 11, 2022
Runtime automation moved this from Done to In progress Apr 11, 2022
@stale stale bot removed the A5-stale Pull request did not receive any updates in a long time. No review needed at this stage. Close it. label Apr 11, 2022
@emostov
Copy link
Contributor

emostov commented Apr 11, 2022

This is still useful

Copy link
Contributor

@kianenigma kianenigma left a comment

Choose a reason for hiding this comment

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

I am a huge fan of this PR and have hit this wall in the past, but I think https://github.com/paritytech/substrate/pull/10719/files#r810890249 should be resolved first.

@shawntabrizi
Copy link
Contributor Author

bot merge

@paritytech-processbot
Copy link

Error: "Check reviews" status is not passing for paritytech/polkadot#4947

@shawntabrizi
Copy link
Contributor Author

bot merge

@paritytech-processbot
Copy link

Error: "Check reviews" status is not passing for paritytech/cumulus#1262

@shawntabrizi
Copy link
Contributor Author

bot merge

@paritytech-processbot
Copy link

Error: Github API says paritytech/polkadot#4947 is not mergeable

@shawntabrizi
Copy link
Contributor Author

bot merge

@paritytech-processbot
Copy link

Error: "Check reviews" status is not passing for paritytech/polkadot#4947

@shawntabrizi
Copy link
Contributor Author

bot merge

@paritytech-processbot paritytech-processbot bot merged commit 2823dc4 into master May 17, 2022
Runtime automation moved this from Needs Audit to Done May 17, 2022
@paritytech-processbot paritytech-processbot bot deleted the shawntabrizi-improve-accountidconversion branch May 17, 2022 21:12
@kianenigma
Copy link
Contributor

We should have a DecodeExact like this to achieve what we do in this PR cleaner

https://github.com/paritytech/parity-scale-codec/blob/master/src/decode_all.rs#L22

@shawntabrizi shawntabrizi moved this from Done to Archive in Runtime May 19, 2022
godcodehunter pushed a commit to sensoriumxr/substrate that referenced this pull request Jun 22, 2022
… add fallible `try_into...` (paritytech#10719)

* note truncating, add fallible try_into

* fmt

* migrate all to `truncating`

* typo

* uno mas

* Update primitives/runtime/src/traits.rs

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* check the bytes before and after are sensible

* fmt

* Update lib.rs

* Update primitives/runtime/src/traits.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
jiguantong added a commit to darwinia-network/darwinia-messages-substrate that referenced this pull request Jun 30, 2022
jiguantong added a commit to darwinia-network/darwinia-messages-substrate that referenced this pull request Jun 30, 2022
jiguantong added a commit to darwinia-network/darwinia-parachain that referenced this pull request Jul 1, 2022
jiguantong added a commit to darwinia-network/darwinia-parachain that referenced this pull request Jul 9, 2022
DaviRain-Su pushed a commit to octopus-network/substrate that referenced this pull request Aug 23, 2022
… add fallible `try_into...` (paritytech#10719)

* note truncating, add fallible try_into

* fmt

* migrate all to `truncating`

* typo

* uno mas

* Update primitives/runtime/src/traits.rs

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* check the bytes before and after are sensible

* fmt

* Update lib.rs

* Update primitives/runtime/src/traits.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
ark0f pushed a commit to gear-tech/substrate that referenced this pull request Feb 27, 2023
… add fallible `try_into...` (paritytech#10719)

* note truncating, add fallible try_into

* fmt

* migrate all to `truncating`

* typo

* uno mas

* Update primitives/runtime/src/traits.rs

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* check the bytes before and after are sensible

* fmt

* Update lib.rs

* Update primitives/runtime/src/traits.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
C1-low PR touches the given topic and has a low impact on builders. D2-breaksapi D5-nicetohaveaudit ⚠️ PR contains trivial changes to logic that should be properly reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] PalletIds not uniquely determined by 8 symbol input into_sub_account should check seed length
5 participants