-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Conversation
Do we really need this here in Substrate? I mean the runtime api could also just be declared for Statemint/Statemine. It could also there directly have concrete namings like |
Cross-chain consistency of getting asset balances is better than bespoke naming. I'd suggest that being able to get the balances of an account is something that should come as standard. |
While I agree with this. The current implementation here with a In the future when we have https://forum.polkadot.network/t/wasm-view-functions/1045 we can have a standard. I will approve the pr for now, but I request some better docs on how "instance" is defined. |
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 fact this assumes a chain can have multiple kinds of asset id is just super confusing and not making sense.
Yes a chain can have multiple pallet-assets instance with different AssetId type for each instance. However the chain SHOULD still have a single unified asset id. It could be
enum AssetId {
LocalAssets(u32),
ForeignAssets(MultiLocation),
}
and having one pallet-assets handle local assets and another one handle foreign assets. But the API / UI / UX should never require user to specify an instance ID AND an asset id.
Co-authored-by: Bastian Köcher <[email protected]>
I removed the instance param as it causes too much confusion |
What would be the proper solution then? |
Acala for example, we have pallet-balances, orml-tokens, and ERC20 from EVM and we have a single CurrencyId for all those. |
But this is kind of a bad idea anyway. It could be very very expensive to iterate all the assets. This could be a DoS vector to the node. Take a look at Ethereum, how many ERC20 are there and how are you going to iterate every ERC20 on Ethereum to return a balance list? |
@xlc In Ethereum, there are balance contracts those accept an array of contracts to check and return you up to 1k balances at once |
I am happy to remove my review, but I'd like the PR authors to also study the links that I have provided and express if they agree that the correct solution is to not only solve this at the level of assets pallet, but at the XCM layer. Currently, an account can have "value bearing assets" in balances/assets pallet, in a DEX pallet, in some liquid staking pool pallet, in a lending platform. A wallet in our ecosystem has no meaningful way to scrape all of this information as it stands now, unless if they go on and study each parachain/platform one by one. The XCM-centric approach would solve all of this in one go, and moves the responsibility of implementing this API to each individual chain, which is where it should logically reside. |
This pull request has been mentioned on Polkadot Forum. There might be relevant details there: https://forum.polkadot.network/t/xcm-as-a-standard-for-reading-and-interacting-with-parachains/266/5 |
Okay, sorry, but I am still not onboard. What about a |
@@ -924,4 +924,11 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> { | |||
Ok(()) | |||
}) | |||
} | |||
|
|||
/// Returns all the non-zero balances for all assets of the given `account`. | |||
pub fn account_balances(account: T::AccountId) -> Vec<(T::AssetId, T::Balance)> { |
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.
pub fn account_balances(account: T::AccountId) -> Vec<(T::AssetId, T::Balance)> { | |
pub fn account_balances(account: T::AccountId, max_iters: Option<u32>) -> Vec<(T::AssetId, T::Balance)> { |
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.
Then the node implementing this can decide up to how many iterations it wants to support.
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 node does not augments calls to the runtime. So, what ever calls this would need to set this value. But I'm fine with the idea in general
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 don’t think this approach will work in general. This will need to have proper paging support to be exhaustive and this kind of API is simply impossible for ERC20 tokens implementation.
|
||
/// Returns all the non-zero balances for all assets of the given `account`. | ||
pub fn account_balances(account: T::AccountId) -> Vec<(T::AssetId, T::Balance)> { | ||
Asset::<T, I>::iter_keys() |
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.
Asset::<T, I>::iter_keys() | |
Asset::<T, I>::iter_keys().take(max_iters.unwrap_or(u32::MAX)) |
use codec::Codec; | ||
use sp_std::vec::Vec; | ||
|
||
sp_api::decl_runtime_apis! { |
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.
Why is this re-defined in every single runtime in Cumulus?
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.
there is just one common definition for all statemine/t runtimes (statemine/statemint/westmint),
but lets discuss it here: paritytech/cumulus#2180 (comment)
I am not against this PR getting in if it solves some specific problem we need tomorrow, but yeah, the XCM route seems like the right approach. We should instead have a new XCM Query RPC, and one of the XCM queries should be exactly like this, and implementable by runtime developers to work against any pallets. |
Would be great if one of you could draft how this would look like.
|
@shawntabrizi |
bot rebase |
Rebased |
bot rebase |
Rebased |
bot rebase |
Rebased |
bot merge |
* Runtime method to get user's assets balances * Fix test (typo) * Update frame/assets/src/functions.rs * Remove instance param * Update frame/assets/src/functions.rs Co-authored-by: Bastian Köcher <[email protected]> * Remove instance param * Refactor * Chore * Update doc --------- Co-authored-by: Bastian Köcher <[email protected]> Co-authored-by: parity-processbot <>
This pull request has been mentioned on Polkadot Forum. There might be relevant details there: https://forum.polkadot.network/t/polkadot-release-analysis-v0-9-40/2468/1 |
* Runtime method to get user's assets balances * Fix test (typo) * Update frame/assets/src/functions.rs * Remove instance param * Update frame/assets/src/functions.rs Co-authored-by: Bastian Köcher <[email protected]> * Remove instance param * Refactor * Chore * Update doc --------- Co-authored-by: Bastian Köcher <[email protected]> Co-authored-by: parity-processbot <>
* Runtime method to get user's assets balances * Fix test (typo) * Update frame/assets/src/functions.rs * Remove instance param * Update frame/assets/src/functions.rs Co-authored-by: Bastian Köcher <[email protected]> * Remove instance param * Refactor * Chore * Update doc --------- Co-authored-by: Bastian Köcher <[email protected]> Co-authored-by: parity-processbot <>
This method solves the problem of fetching the account's asset balances, now instead of sending 100+ RPC requests it would be possible to send just one.
Cumulus Companion: paritytech/cumulus#2180