-
Notifications
You must be signed in to change notification settings - Fork 2.7k
into_sub_account
should check seed length
#8564
Comments
Yeah we had some issues in our test that using |
I changed For the hashing function, what hasher should be used? And there may also be the case, that the hash value does not fit into the AccountId type. As I understand you correctly, the AccountId should just be filled up with the hashed seed, to reduce the probability of collisions, but may also be left out at all, as in the previous implementation? |
You should be able to pass a generic hashing trait so the end user can pick the hasher. Yeah, if the hash value is too much, we put as much as we can into the AccountId. Is there some code I can look at? |
…ount function fixes paritytech#8564
@shawntabrizi I opened a PR #8672 |
I also see that into_sub_account will always return the same default account in case AccountId can't decode the byte slice. substrate/primitives/runtime/src/traits.rs Lines 1146 to 1150 in 37e97cf
I think we should create a proper trait to be able to generate different account id safely. For example we could a new trait to frame_system::Config::AccountId: trait GenerateAccountFromSeed {
fn from_seed(s: &[u8; 8]) -> Self;
fn pallet_sub_account<P: PalletInfoAccess>(seed: &[u8]) -> Self {
Self::from_seed(twox64("pllt"++encode(P::index)++Some(seed))))
}
fn pallet_account<P: PalletInfoAccess>(seed: &[u8]) -> Self {
Self::from_seed(twox64("pllt"++encode(P::index)++None))))
}
} and implement it for u64 and u128. |
This looks like a safe alternative. How about generalizing with the Encode-Trait for the seed? trait GenerateAccountFromSeed {
fn from_seed<S: Encode>(s: S) -> Self;
fn pallet_sub_account<S: Encode, P: PalletInfoAccess>(seed: S) -> Self {
Self::from_seed(twox64("pllt"++ encode(P::index) ++ encode(seed)))
}
fn pallet_account<P: PalletInfoAccess>() -> Self {
Self::from_seed(twox64("pllt"++encode(P::index))))
}
} The drawback of hashing the whole representation is that it's not reversible/inspectable anymore. What are the implications on changing the underlying representation for existing accounts or code that maybe rely on that representation? Is there some migration necessary? |
I dont think this is exactly the direction we want to go. In this case, the account for a pallet will change depending on the order a user puts the pallets in their runtime. Currently, we have it that the treasury account for all substrate chains are the same account, which makes it easy for exchanges and block explorers to track those well known accounts. I think the goal here is to keep the same underlying logic about |
we can explicitly set pallet index so the order shouldn't be an issue. we should not assume treasury account address on different chains are the same, because there will be exceptions and I don't think that's a good idea anyway. |
I mean treasury doesn't have to use |
This Issue and PR seems stuck. How can we make progress here? I see three directions from here:
|
if we have Pallets can then write a test in integrity_test ensuring that they are able to generate their account ids. So if I don't mind it but it is not very handy. Instead I think it is better to have a proper trait bound on frame_system::Config::AccountId which allows to generate those id without issue. using some hash or ensuring no more than 8 byte of into is given, and that AccountId is more than 8 byte. This issue paritytech/polkadot-sdk#324 is about making pallet id not configurable but hardcoded. The only unique identifier of pallet are currently their name and their index. In general the pallets should then put those account into metadata if they want third party to interact with it, I think. (if treasury still wants a specific account id then we can still give the final account id in treasury::Config) |
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. |
#8672 is still open for discussion |
Pallet contract generates some account id by bounding Contrary to pallet contract, for now we use this I see 2 solutions: Solution 1: sub account is generated from non-cryptographic or cryptographic hash depending on usecase.For this solution we force
Solution 2: sub account is from trusted input (not influenced by user) and limited to 4 byte:For this solution we force
So it is exactly 16 bytes because we constraint the seed to be 4 bytes. Notesboth solution are annoying because it uses a hash and thus from the account id it is more difficult to see what is the meaning.
|
cc @emostov we ran into this as well. |
Currently,
into_sub_account
directly encodes the seed data into the generated account id bytes.We do not check that the seed data is greater than the length of the account id type, and thus do not check that some of the data may be truncated and not used to seed an account. This can obviously be bad since all of the seed information should be used to generate a unique account, and any truncation could lead to unintended account collisions.
into_sub_account
should return a result, and only generate an account if the seed data would fit completely into the account id space.Otherwise,
hash_into_sub_account
can be introduced which takes a hash of the seed data and uses that to generate as much data as needed for the account.We must review all uses of
into_sub_account
to make sure they would not suddenly stop working.The text was updated successfully, but these errors were encountered: