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

Return account's asset balances #13352

Merged
merged 13 commits into from
Mar 2, 2023
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ members = [
"client/utils",
"frame/alliance",
"frame/assets",
"frame/assets/runtime-api",
"frame/atomic-swap",
"frame/aura",
"frame/authority-discovery",
Expand Down
2 changes: 2 additions & 0 deletions bin/node/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ frame-system-rpc-runtime-api = { version = "4.0.0-dev", default-features = false
frame-try-runtime = { version = "0.10.0-dev", default-features = false, path = "../../../frame/try-runtime", optional = true }
pallet-alliance = { version = "4.0.0-dev", default-features = false, path = "../../../frame/alliance" }
pallet-assets = { version = "4.0.0-dev", default-features = false, path = "../../../frame/assets" }
pallet-assets-runtime-api = { version = "4.0.0-dev", default-features = false, path = "../../../frame/assets/runtime-api" }
pallet-authority-discovery = { version = "4.0.0-dev", default-features = false, path = "../../../frame/authority-discovery" }
pallet-authorship = { version = "4.0.0-dev", default-features = false, path = "../../../frame/authorship" }
pallet-babe = { version = "4.0.0-dev", default-features = false, path = "../../../frame/babe" }
Expand Down Expand Up @@ -128,6 +129,7 @@ std = [
"frame-election-provider-support/std",
"sp-authority-discovery/std",
"pallet-assets/std",
"pallet-assets-runtime-api/std",
"pallet-authority-discovery/std",
"pallet-authorship/std",
"sp-consensus-babe/std",
Expand Down
14 changes: 14 additions & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2045,6 +2045,20 @@ impl_runtime_apis! {
}
}

impl pallet_assets_runtime_api::AssetsApi<
Block,
AccountId,
Balance,
u32,
> for Runtime
{
fn account_balances(instance: u8, account: AccountId) -> Vec<(u32, Balance)> {
match instance {
jsidorenko marked this conversation as resolved.
Show resolved Hide resolved
_ => Assets::account_balances(account),
}
}
}

impl pallet_contracts::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash> for Runtime
{
fn call(
Expand Down
26 changes: 26 additions & 0 deletions frame/assets/runtime-api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "pallet-assets-runtime-api"
version = "4.0.0-dev"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
license = "Apache-2.0"
homepage = "https://substrate.io"
repository = "https://github.com/paritytech/substrate/"
description = "Runtime API for assets FRAME pallet"
readme = "README.md"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = ["derive"] }
sp-api = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/api" }
sp-std = { version = "5.0.0", default-features = false, path = "../../../primitives/std" }

[features]
default = ["std"]
std = [
"codec/std",
"sp-api/std",
"sp-std/std",
]
3 changes: 3 additions & 0 deletions frame/assets/runtime-api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Runtime API definition for assets pallet.

License: Apache-2.0
35 changes: 35 additions & 0 deletions frame/assets/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// This file is part of Substrate.

// Copyright (C) 2022 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Runtime API definition for assets pallet.
//! Currently supports only one rpc endpoint.

#![cfg_attr(not(feature = "std"), no_std)]

use codec::Codec;
use sp_std::vec::Vec;

sp_api::decl_runtime_apis! {
pub trait AssetsApi<AccountId, AssetBalance, AssetId> where
AccountId: Codec,
AssetBalance: Codec,
AssetId: Codec
{
/// Returns the list of asset id and non-zero balance the AccountId has.
jsidorenko marked this conversation as resolved.
Show resolved Hide resolved
fn account_balances(instance: u8, account: AccountId) -> Vec<(AssetId, AssetBalance)>;
}
}
7 changes: 7 additions & 0 deletions frame/assets/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -924,4 +924,11 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
Ok(())
})
}

/// Used by the RPC service to provide account balances.
jsidorenko marked this conversation as resolved.
Show resolved Hide resolved
pub fn account_balances(account: T::AccountId) -> Vec<(T::AssetId, T::Balance)> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
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)> {

Copy link
Contributor

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.

Copy link
Member

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

Copy link
Contributor

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.

Asset::<T, I>::iter_keys()
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Asset::<T, I>::iter_keys()
Asset::<T, I>::iter_keys().take(max_iters.unwrap_or(u32::MAX))

.filter_map(|id| Self::maybe_balance(id, account.clone()).map(|balance| (id, balance)))
.collect::<Vec<_>>()
}
}
5 changes: 4 additions & 1 deletion frame/assets/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,14 @@ fn asset_ids() -> Vec<u32> {
fn basic_minting_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Assets::force_create(RuntimeOrigin::root(), 0, 1, true, 1));
assert_ok!(Assets::force_create(RuntimeOrigin::root(), 1, 1, true, 1));
assert_ok!(Assets::mint(RuntimeOrigin::signed(1), 0, 1, 100));
assert_eq!(Assets::balance(0, 1), 100);
assert_ok!(Assets::mint(RuntimeOrigin::signed(1), 0, 2, 100));
assert_eq!(Assets::balance(0, 2), 100);
assert_eq!(asset_ids(), vec![0, 999]);
assert_eq!(asset_ids(), vec![0, 1, 999]);
assert_ok!(Assets::mint(RuntimeOrigin::signed(1), 1, 1, 100));
assert_eq!(Assets::account_balances(1), vec![(0, 100), (999, 100), (1, 100)]);
});
}

Expand Down