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

feat: add InvestmentPortfolio Runtime API #1608

Merged
merged 6 commits into from
Nov 21, 2023
Merged

Conversation

wischli
Copy link
Contributor

@wischli wischli commented Nov 15, 2023

Description

Fixes #1589

Changes and Descriptions

  • Adds account based InvestmenPortfolio Runtime API
  • Removes existent Runtime API which has not been used by Apps
  • Removes InvestmentsPortfolio trait due to not being used

TODO

  • Integration tests
  • Ensure integrity with Apps

Checklist:

  • I have added Rust doc comments to structs, enums, traits and functions
  • I have made corresponding changes to the documentation
  • I have performed a self-review of my code
  • I have added tests that prove my fix is effective or that my feature works

@wischli wischli added I9-release A specific release. P7-asap Issue should be addressed in the next days. D2-notify Pull request can be merged and notification about changes should be documented. I8-enhancement An additional feature. D5-breaks-api Pull request changes public api. Document changes publicly. labels Nov 15, 2023
@wischli wischli self-assigned this Nov 15, 2023
@wischli wischli marked this pull request as ready for review November 17, 2023 16:35
@@ -219,26 +219,6 @@ pub trait InvestmentAccountant<AccountId> {
) -> Result<(), Self::Error>;
}

/// Trait to handle Investment Portfolios for accounts
pub trait InvestmentsPortfolio<Account> {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

NOTE: Removed because unused.

Comment on lines 254 to 256
/// The amount of tranche tokens which can not be used at all and get
/// slashed
pub reserved_tranche_tokens: Balance,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

NOTE: Decided against supporting frozen as we don't support frozen fungibles in restricted tokens yet and are not freezing anywhere in the codebase.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Didn't we want to add the CurrencyId of the actual pool_currency here as a field?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IMO it's impossible to map free pool_currency to an InvestmentId because

  • We will have multiple pools with the same pool_currency
  • Once it is free, the root cause for that is unknown without introducing additional storage

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah sorry. I meant, to add this in order for the UI to show that they user has pending amount of PoolCurrency investing. So the UI know what currencie to display.

Does this make more sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I cant follow. Could you elaborate @mustermeiszer ? We already have a field for pending pool currency. Any pool currency that is not related to an investment id shouldnt be part of this portfolio API per definition (no key value mapping).

Copy link
Collaborator

Choose a reason for hiding this comment

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

fn investment_portfolio(account_id: AccountId) -> Vec<(InvestmentId, InvestmentPortfolio)>

as per this API the UI has no knowledge what is the pool_currency, so we should give it this information in the structure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now I get it, you are talking about the currency id while I was still in the amounts space. I will add it then to have a full portfolio without any need for further queries. On that note: The investment id key contains the pool id such that another query suffices to read the pool currency.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines 2168 to 2170
impl runtime_common::apis::InvestmentsApi<Block, AccountId, TrancheCurrency, InvestmentPortfolio<Balance>> for Runtime {
fn investment_portfolio(account_id: AccountId) -> Vec<(TrancheCurrency, InvestmentPortfolio<Balance>)> {
runtime_common::investment_portfolios::get_account_portfolio::<Runtime, PoolSystem>(account_id)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

NOTE: Maybe we should bump the version to V2 but Apps has not used this API so far.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Then I would just overwrite as you did.

NunoAlexandre
NunoAlexandre previously approved these changes Nov 20, 2023
Copy link
Contributor

@NunoAlexandre NunoAlexandre left a comment

Choose a reason for hiding this comment

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

Looks very nice, thanks for adding coverage in the integration tests and useful notes ✨

Comment on lines +386 to +388
/// NOTE: Moving inner scope to any pallet would introduce tight(er)
/// coupling due to requirement of iterating over storage maps which in turn
/// require the pallet's Config trait.
Copy link
Contributor

Choose a reason for hiding this comment

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

👌

Comment on lines 254 to 256
/// The amount of tranche tokens which can not be used at all and get
/// slashed
pub reserved_tranche_tokens: Balance,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Didn't we want to add the CurrencyId of the actual pool_currency here as a field?

Comment on lines 254 to 255
/// The amount of tranche tokens which can not be used at all and get
/// slashed
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the and get slashed is confusing. Wouldn't it be and could can get clashed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah the wording is suboptimal as it the can is implicitly connected to can not be used at all as well as (can) get slashed. I will improve this!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines 2168 to 2170
impl runtime_common::apis::InvestmentsApi<Block, AccountId, TrancheCurrency, InvestmentPortfolio<Balance>> for Runtime {
fn investment_portfolio(account_id: AccountId) -> Vec<(TrancheCurrency, InvestmentPortfolio<Balance>)> {
runtime_common::investment_portfolios::get_account_portfolio::<Runtime, PoolSystem>(account_id)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Then I would just overwrite as you did.

runtime/common/src/lib.rs Outdated Show resolved Hide resolved
>::new();

// Denote current tranche token balances before dry running collecting
orml_tokens::Accounts::<T>::iter_key_prefix(&investor).for_each(|currency| {
if let CurrencyId::Tranche(pool_id, tranche_id) = CurrencyId::from(currency) {
let balance = orml_tokens::Accounts::<T>::get(&investor, currency);
let pool_currency = PoolInspector::currency_for(pool_id)
.expect("Pool must exist; qed")
Copy link
Contributor Author

@wischli wischli Nov 20, 2023

Choose a reason for hiding this comment

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

I think we can safely expect here and the two below cases of querying the pool currency. If we want to be super duper safe, I can wrap the rest of the inner scopes into a .map. WDYT @mustermeiszer ?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, I would also say so. I also think zo remember that api calls are wrapped in a panic catching-something, I will double check that.

But think the expect is fine!

Copy link
Collaborator

@mustermeiszer mustermeiszer left a comment

Choose a reason for hiding this comment

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

Nice and clean!

@wischli wischli merged commit 55570cc into main Nov 21, 2023
8 checks passed
@wischli wischli deleted the feat/investment-portfolio branch November 21, 2023 07:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
D2-notify Pull request can be merged and notification about changes should be documented. D5-breaks-api Pull request changes public api. Document changes publicly. I8-enhancement An additional feature. I9-release A specific release. P7-asap Issue should be addressed in the next days.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Investments: RuntimeApi for redeem and collected tokens
3 participants