From 1524af2ebee3e6b6974473180348b86154f78add Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Mon, 30 Sep 2024 11:51:48 +0300 Subject: [PATCH 01/33] use const --- x/bank/src/abci_handler.rs | 54 +++++++++++++++++++++----------------- x/bank/src/types/query.rs | 2 +- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/x/bank/src/abci_handler.rs b/x/bank/src/abci_handler.rs index db08e7d1..787136a5 100644 --- a/x/bank/src/abci_handler.rs +++ b/x/bank/src/abci_handler.rs @@ -109,10 +109,7 @@ impl< BankNodeQueryResponse::DenomsMetadata(self.query_denoms(ctx, req)) } BankNodeQueryRequest::DenomMetadata(req) => { - let metadata = self - .keeper - .get_denom_metadata(ctx, &req.denom) - .expect("Query ctx doesn't have any gas"); + let metadata = self.keeper.get_denom_metadata(ctx, &req.denom).unwrap_gas(); BankNodeQueryResponse::DenomMetadata(QueryDenomMetadataResponse { metadata }) } BankNodeQueryRequest::Params(_req) => { @@ -123,23 +120,9 @@ impl< BankNodeQueryRequest::SupplyOf(req) => { BankNodeQueryResponse::SupplyOf(self.query_supply_of(ctx, req)) } - BankNodeQueryRequest::Spendable(QuerySpendableBalancesRequest { - address, - pagination, - }) => { - // TODO: edit error "handling" - let (spendable, pagination_result) = self - .keeper - .spendable_coins(ctx, &address, pagination.map(Pagination::from)) - .map(|(spendable, _, pag)| { - (spendable.map(Vec::from), pag.map(PaginationResponse::from)) - }) - .unwrap_or_default(); - - BankNodeQueryResponse::Spendable(QuerySpendableBalancesResponse { - balances: spendable.unwrap_or_default(), - pagination: pagination_result, - }) + BankNodeQueryRequest::Spendable(req) => { + let balance = self.spendable(ctx, req); + BankNodeQueryResponse::Spendable(balance) } } } @@ -195,7 +178,7 @@ impl< Ok(self.query_total_supply(ctx, req).encode_vec()) } - "/cosmos.bank.v1beta1.Query/Balance" => { + QueryBalanceRequest::QUERY_URL => { let req = QueryBalanceRequest::decode(query.data)?; Ok(self.query_balance(ctx, req).encode_vec()) @@ -207,12 +190,12 @@ impl< Ok(result) } - "/cosmos.bank.v1beta1.Query/DenomMetadata" => { + QueryDenomMetadataRequest::QUERY_URL => { let req = QueryDenomMetadataRequest::decode(query.data)?; let metadata = self.keeper.get_denom_metadata(ctx, &req.denom).unwrap_gas(); Ok(QueryDenomMetadataResponse { metadata }.encode_vec()) } - "/cosmos.bank.v1beta1.Query/Params" => { + QueryParamsRequest::QUERY_URL => { // a kind of type check let _req = QueryParamsRequest::decode(query.data)?; let params = self.keeper.params(ctx); @@ -237,6 +220,29 @@ impl, M: Module, MI: self.keeper.init_genesis(ctx, genesis) } + fn spendable( + &self, + ctx: &QueryContext, + QuerySpendableBalancesRequest { + address, + pagination, + }: QuerySpendableBalancesRequest, + ) -> QuerySpendableBalancesResponse { + // TODO: edit error "handling" + let (spendable, pagination_result) = self + .keeper + .spendable_coins(ctx, &address, pagination.map(Pagination::from)) + .map(|(spendable, _, pag)| { + (spendable.map(Vec::from), pag.map(PaginationResponse::from)) + }) + .unwrap_or_default(); + + QuerySpendableBalancesResponse { + balances: spendable.unwrap_or_default(), + pagination: pagination_result, + } + } + fn query_balances( &self, ctx: &QueryContext, diff --git a/x/bank/src/types/query.rs b/x/bank/src/types/query.rs index 313053a3..33e36845 100644 --- a/x/bank/src/types/query.rs +++ b/x/bank/src/types/query.rs @@ -67,7 +67,7 @@ pub struct QueryAllBalancesRequest { } #[derive(Clone, Debug, PartialEq, Query, Protobuf)] -#[query(url = "/cosmos.bank.v1beta1.Query/DenomsMetadata")] +#[query(url = "/cosmos.bank.v1beta1.Query/DenomMetadata")] #[proto(raw = "inner::QueryDenomMetadataRequest")] pub struct QueryDenomMetadataRequest { /// denom is the coin denom to query metadata for. From 6b32aeb56b32067043b6723eff5b525f33afcc8b Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Mon, 30 Sep 2024 12:10:28 +0300 Subject: [PATCH 02/33] remove get_* --- gears/src/x/ante.rs | 2 +- gears/src/x/keepers/bank.rs | 2 +- gears/src/x/keepers/mocks/bank.rs | 2 +- gears/src/x/keepers/mocks/staking.rs | 2 +- gears/src/x/keepers/staking.rs | 2 +- x/bank/src/abci_handler.rs | 4 ++-- x/bank/src/keeper.rs | 10 +++++----- x/distribution/src/keeper/allocation.rs | 2 +- x/distribution/src/keeper/mod.rs | 2 +- x/staking/src/keeper/mod.rs | 11 ++++------- 10 files changed, 18 insertions(+), 21 deletions(-) diff --git a/gears/src/x/ante.rs b/gears/src/x/ante.rs index b2274ae5..52fab43a 100644 --- a/gears/src/x/ante.rs +++ b/gears/src/x/ante.rs @@ -583,7 +583,7 @@ impl< &self, denom: &Denom, ) -> Result, Self::Error> { - self.bank_keeper.get_denom_metadata(self.ctx, denom) + self.bank_keeper.denom_metadata(self.ctx, denom) } } diff --git a/gears/src/x/keepers/bank.rs b/gears/src/x/keepers/bank.rs index bc02dc8d..22376176 100644 --- a/gears/src/x/keepers/bank.rs +++ b/gears/src/x/keepers/bank.rs @@ -27,7 +27,7 @@ pub trait BankKeeper: Clone + Send + Sync + 'static { amount: UnsignedCoins, ) -> Result<(), BankKeeperError>; - fn get_denom_metadata>( + fn denom_metadata>( &self, ctx: &CTX, base: &Denom, diff --git a/gears/src/x/keepers/mocks/bank.rs b/gears/src/x/keepers/mocks/bank.rs index 5781eb6c..2047f5fe 100644 --- a/gears/src/x/keepers/mocks/bank.rs +++ b/gears/src/x/keepers/mocks/bank.rs @@ -39,7 +39,7 @@ impl BankKeeper for MockBankKeeper { Ok(()) } - fn get_denom_metadata>( + fn denom_metadata>( &self, _: &CTX, _: &crate::types::denom::Denom, diff --git a/gears/src/x/keepers/mocks/staking.rs b/gears/src/x/keepers/mocks/staking.rs index 77233dcd..5bcc3a1f 100644 --- a/gears/src/x/keepers/mocks/staking.rs +++ b/gears/src/x/keepers/mocks/staking.rs @@ -13,7 +13,7 @@ use super::bank::MockBankKeeper; impl StakingBankKeeper for MockBankKeeper { // TODO: Remove and use balances_all - fn get_all_balances>( + fn all_balances>( &self, _: &CTX, _: address::AccAddress, diff --git a/gears/src/x/keepers/staking.rs b/gears/src/x/keepers/staking.rs index 9e6d892d..808c46d8 100644 --- a/gears/src/x/keepers/staking.rs +++ b/gears/src/x/keepers/staking.rs @@ -213,7 +213,7 @@ pub trait StakingBankKeeper: // // BurnCoins(ctx sdk.Context, name string, amt sdk.Coins) error - fn get_all_balances>( + fn all_balances>( &self, ctx: &CTX, addr: AccAddress, diff --git a/x/bank/src/abci_handler.rs b/x/bank/src/abci_handler.rs index 787136a5..b4996d19 100644 --- a/x/bank/src/abci_handler.rs +++ b/x/bank/src/abci_handler.rs @@ -109,7 +109,7 @@ impl< BankNodeQueryResponse::DenomsMetadata(self.query_denoms(ctx, req)) } BankNodeQueryRequest::DenomMetadata(req) => { - let metadata = self.keeper.get_denom_metadata(ctx, &req.denom).unwrap_gas(); + let metadata = self.keeper.denom_metadata(ctx, &req.denom).unwrap_gas(); BankNodeQueryResponse::DenomMetadata(QueryDenomMetadataResponse { metadata }) } BankNodeQueryRequest::Params(_req) => { @@ -192,7 +192,7 @@ impl< } QueryDenomMetadataRequest::QUERY_URL => { let req = QueryDenomMetadataRequest::decode(query.data)?; - let metadata = self.keeper.get_denom_metadata(ctx, &req.denom).unwrap_gas(); + let metadata = self.keeper.denom_metadata(ctx, &req.denom).unwrap_gas(); Ok(QueryDenomMetadataResponse { metadata }.encode_vec()) } QueryParamsRequest::QUERY_URL => { diff --git a/x/bank/src/keeper.rs b/x/bank/src/keeper.rs index 8f78d872..4df677a9 100644 --- a/x/bank/src/keeper.rs +++ b/x/bank/src/keeper.rs @@ -81,7 +81,7 @@ impl< Ok(()) } - fn get_denom_metadata>( + fn denom_metadata>( &self, ctx: &CTX, base: &Denom, @@ -174,7 +174,7 @@ impl< M: Module, > StakingBankKeeper for Keeper { - fn get_all_balances>( + fn all_balances>( &self, ctx: &CTX, addr: AccAddress, @@ -517,7 +517,7 @@ impl, M: Module> let to_address = msg.to_address; for send_coin in msg.amount { - let mut from_account_store = self.get_address_balances_store(ctx, &from_address); + let mut from_account_store = self.address_balances_store(ctx, &from_address); let from_balance = from_account_store .get(send_coin.denom.to_string().as_bytes())? .ok_or(InsufficientFundsError::RequiredActual { @@ -549,7 +549,7 @@ impl, M: Module> )?; } - let mut to_account_store = self.get_address_balances_store(ctx, &to_address); + let mut to_account_store = self.address_balances_store(ctx, &to_address); let to_balance = to_account_store.get(send_coin.denom.to_string().as_bytes())?; let mut to_balance: UnsignedCoin = match to_balance { @@ -628,7 +628,7 @@ impl, M: Module> } } - fn get_address_balances_store<'a, DB: Database>( + fn address_balances_store<'a, DB: Database>( &'a self, ctx: &'a mut impl TransactionalContext, address: &AccAddress, diff --git a/x/distribution/src/keeper/allocation.rs b/x/distribution/src/keeper/allocation.rs index 58ff8030..fd9ff382 100644 --- a/x/distribution/src/keeper/allocation.rs +++ b/x/distribution/src/keeper/allocation.rs @@ -44,7 +44,7 @@ impl< // (and distributed to the previous proposer) let fees_collected_int = self .bank_keeper - .get_all_balances(ctx, self.fee_collector_module.get_address()) + .all_balances(ctx, self.fee_collector_module.get_address()) .unwrap_gas(); let fees_collected = DecimalCoins::try_from(fees_collected_int.clone())?; diff --git a/x/distribution/src/keeper/mod.rs b/x/distribution/src/keeper/mod.rs index ae2b2f17..fdfe958e 100644 --- a/x/distribution/src/keeper/mod.rs +++ b/x/distribution/src/keeper/mod.rs @@ -182,7 +182,7 @@ impl< self.check_set_distribution_account(ctx).unwrap_gas(); let balances = self .bank_keeper - .get_all_balances(ctx, self.distribution_module.get_address()) + .all_balances(ctx, self.distribution_module.get_address()) .unwrap_gas(); if module_holdings_int != Some(UnsignedCoins::new(balances)?) { diff --git a/x/staking/src/keeper/mod.rs b/x/staking/src/keeper/mod.rs index 80be591d..71b979a7 100644 --- a/x/staking/src/keeper/mod.rs +++ b/x/staking/src/keeper/mod.rs @@ -208,7 +208,7 @@ impl< let bonded_balance = self .bank_keeper - .get_all_balances::>(ctx, self.bonded_module.get_address()) + .all_balances::>(ctx, self.bonded_module.get_address()) .unwrap_gas(); // there's a check in the cosmos SDK to ensure that a new module account is only created if the balance is zero @@ -232,10 +232,7 @@ impl< let not_bonded_balance = self .bank_keeper - .get_all_balances::>( - ctx, - self.not_bonded_module.get_address(), - ) + .all_balances::>(ctx, self.not_bonded_module.get_address()) .unwrap_gas(); // see comment above for the logic of creating a new module account @@ -592,12 +589,12 @@ impl< let denom = self.staking_params_keeper.try_get(ctx)?.bond_denom; let not_bonded_tokens = self .bank_keeper - .get_all_balances(ctx, self.not_bonded_module.get_address())? + .all_balances(ctx, self.not_bonded_module.get_address())? .into_iter() .find(|e| e.denom == denom); let bonded_tokens = self .bank_keeper - .get_all_balances(ctx, self.bonded_module.get_address())? + .all_balances(ctx, self.bonded_module.get_address())? .into_iter() .find(|e| e.denom == denom); Ok(Pool { From 9ec703a8494646266846f3dbac3333449f3d88ba Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Mon, 30 Sep 2024 13:02:10 +0300 Subject: [PATCH 03/33] remove duplicate methods --- extensions/src/lib.rs | 2 +- gears/src/x/keepers/auth.rs | 2 +- gears/src/x/keepers/bank.rs | 17 ++++- gears/src/x/keepers/gov.rs | 12 ++-- gears/src/x/keepers/mocks/bank.rs | 23 ++++++- gears/src/x/keepers/mocks/gov.rs | 9 --- gears/src/x/keepers/mocks/staking.rs | 14 +--- gears/src/x/keepers/staking.rs | 13 ++-- x/bank/src/abci_handler.rs | 13 ++-- x/bank/src/keeper.rs | 85 ++++++++++--------------- x/distribution/src/keeper/allocation.rs | 5 +- x/distribution/src/keeper/mod.rs | 5 +- x/gov/src/keeper.rs | 5 +- x/staking/src/keeper/mod.rs | 20 ++++-- 14 files changed, 115 insertions(+), 110 deletions(-) diff --git a/extensions/src/lib.rs b/extensions/src/lib.rs index 5398a9ff..1eaca425 100644 --- a/extensions/src/lib.rs +++ b/extensions/src/lib.rs @@ -1,7 +1,7 @@ -pub mod lock; pub mod corruption; pub mod gas; pub mod infallible; +pub mod lock; pub mod pagination; pub mod socker_addr; pub mod testing; diff --git a/gears/src/x/keepers/auth.rs b/gears/src/x/keepers/auth.rs index 3089c27c..a7082702 100644 --- a/gears/src/x/keepers/auth.rs +++ b/gears/src/x/keepers/auth.rs @@ -13,7 +13,7 @@ pub trait AuthParams { fn tx_cost_per_byte(&self) -> u64; } -pub trait AuthKeeper: Clone { +pub trait AuthKeeper: Clone + Send + Sync + 'static { type Params: AuthParams; fn get_auth_params>( diff --git a/gears/src/x/keepers/bank.rs b/gears/src/x/keepers/bank.rs index 22376176..37306bd3 100644 --- a/gears/src/x/keepers/bank.rs +++ b/gears/src/x/keepers/bank.rs @@ -1,15 +1,28 @@ use database::Database; +use extensions::pagination::{Pagination, PaginationResult}; use kv_store::StoreKey; use crate::{ context::{QueryableContext, TransactionalContext}, types::{ - address::AccAddress, base::coins::UnsignedCoins, denom::Denom, - store::gas::errors::GasStoreErrors, tx::metadata::Metadata, + address::AccAddress, + base::{coin::UnsignedCoin, coins::UnsignedCoins}, + denom::Denom, + store::gas::errors::GasStoreErrors, + tx::metadata::Metadata, }, x::{errors::BankKeeperError, module::Module}, }; +pub trait BalancesKeeper: Clone + Send + Sync + 'static { + fn balance_all>( + &self, + ctx: &CTX, + address: AccAddress, + pagination: Option, + ) -> Result<(Option, Vec), GasStoreErrors>; +} + pub trait BankKeeper: Clone + Send + Sync + 'static { fn send_coins_from_account_to_module>( &self, diff --git a/gears/src/x/keepers/gov.rs b/gears/src/x/keepers/gov.rs index f5a8b531..e21173ab 100644 --- a/gears/src/x/keepers/gov.rs +++ b/gears/src/x/keepers/gov.rs @@ -10,15 +10,11 @@ use crate::{ x::module::Module, }; -use super::bank::BankKeeper; - -pub trait GovernanceBankKeeper: BankKeeper { - fn balance_all>( - &self, - ctx: &CTX, - address: &AccAddress, - ) -> Result, GasStoreErrors>; +use super::bank::{BalancesKeeper, BankKeeper}; +pub trait GovernanceBankKeeper: + BankKeeper + BalancesKeeper +{ fn balance>( &self, ctx: &CTX, diff --git a/gears/src/x/keepers/mocks/bank.rs b/gears/src/x/keepers/mocks/bank.rs index 2047f5fe..fd5c9a14 100644 --- a/gears/src/x/keepers/mocks/bank.rs +++ b/gears/src/x/keepers/mocks/bank.rs @@ -2,7 +2,11 @@ use kv_store::StoreKey; use crate::{ types::{base::coin::UnsignedCoin, store::gas::errors::GasStoreErrors, tx::metadata::Metadata}, - x::{errors::BankKeeperError, keepers::bank::BankKeeper, module::Module}, + x::{ + errors::BankKeeperError, + keepers::bank::{BalancesKeeper, BankKeeper}, + module::Module, + }, }; #[derive(former::Former, Clone, Debug)] @@ -12,6 +16,23 @@ pub struct MockBankKeeper { pub balance: UnsignedCoin, } +impl BalancesKeeper for MockBankKeeper { + fn balance_all>( + &self, + _ctx: &CTX, + _address: address::AccAddress, + _pagination: Option, + ) -> Result< + ( + Option, + Vec, + ), + GasStoreErrors, + > { + Ok((None, self.balance_all.clone())) + } +} + impl BankKeeper for MockBankKeeper { fn send_coins_from_account_to_module< DB: database::Database, diff --git a/gears/src/x/keepers/mocks/gov.rs b/gears/src/x/keepers/mocks/gov.rs index 83b436fe..01e3edd9 100644 --- a/gears/src/x/keepers/mocks/gov.rs +++ b/gears/src/x/keepers/mocks/gov.rs @@ -8,15 +8,6 @@ use crate::{ use super::bank::MockBankKeeper; impl GovernanceBankKeeper for MockBankKeeper { - // TODO: Move to BankKeeper - fn balance_all>( - &self, - _: &CTX, - _: &address::AccAddress, - ) -> Result, GasStoreErrors> { - Ok(self.balance_all.clone()) - } - fn balance>( &self, _: &CTX, diff --git a/gears/src/x/keepers/mocks/staking.rs b/gears/src/x/keepers/mocks/staking.rs index 5bcc3a1f..f9e8376d 100644 --- a/gears/src/x/keepers/mocks/staking.rs +++ b/gears/src/x/keepers/mocks/staking.rs @@ -2,25 +2,13 @@ use kv_store::StoreKey; use crate::{ context::TransactionalContext, - types::{ - base::{coin::UnsignedCoin, coins::UnsignedCoins}, - store::gas::errors::GasStoreErrors, - }, + types::base::coins::UnsignedCoins, x::{errors::BankKeeperError, keepers::staking::StakingBankKeeper, module::Module}, }; use super::bank::MockBankKeeper; impl StakingBankKeeper for MockBankKeeper { - // TODO: Remove and use balances_all - fn all_balances>( - &self, - _: &CTX, - _: address::AccAddress, - ) -> Result, GasStoreErrors> { - Ok(self.balance_all.clone()) - } - fn send_coins_from_module_to_module< DB: database::Database, CTX: TransactionalContext, diff --git a/gears/src/x/keepers/staking.rs b/gears/src/x/keepers/staking.rs index 808c46d8..8452c1a9 100644 --- a/gears/src/x/keepers/staking.rs +++ b/gears/src/x/keepers/staking.rs @@ -17,7 +17,10 @@ use crate::{ }, }; -use super::{auth::AuthKeeper, bank::BankKeeper}; +use super::{ + auth::AuthKeeper, + bank::{BalancesKeeper, BankKeeper}, +}; /// Delay, in blocks, between when validator updates are returned to the /// consensus-engine and when they are applied. For example, if @@ -203,7 +206,7 @@ pub trait DistributionStakingKeeper: /// StakingBankKeeper defines the expected interface needed to retrieve account balances. pub trait StakingBankKeeper: - Clone + Send + Sync + 'static + BankKeeper + BankKeeper + BalancesKeeper + Clone + Send + Sync + 'static { // GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin // LockedCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins @@ -213,12 +216,6 @@ pub trait StakingBankKeeper: // // BurnCoins(ctx sdk.Context, name string, amt sdk.Coins) error - fn all_balances>( - &self, - ctx: &CTX, - addr: AccAddress, - ) -> Result, GasStoreErrors>; - fn send_coins_from_module_to_module>( &self, ctx: &mut CTX, diff --git a/x/bank/src/abci_handler.rs b/x/bank/src/abci_handler.rs index b4996d19..d8982e2e 100644 --- a/x/bank/src/abci_handler.rs +++ b/x/bank/src/abci_handler.rs @@ -14,7 +14,7 @@ use gears::store::StoreKey; use gears::tendermint::types::request::query::RequestQuery; use gears::types::pagination::response::PaginationResponse; use gears::x::keepers::auth::AuthKeeper; -use gears::x::keepers::bank::BankKeeper; +use gears::x::keepers::bank::{BalancesKeeper, BankKeeper}; use gears::x::module::Module; use serde::Serialize; @@ -206,8 +206,13 @@ impl< } } -impl, M: Module, MI: ModuleInfo> - BankABCIHandler +impl< + SK: StoreKey, + PSK: ParamsSubspaceKey, + AK: AuthKeeper + Send + Sync + 'static, + M: Module, + MI: ModuleInfo, + > BankABCIHandler { pub fn new(keeper: Keeper) -> Self { BankABCIHandler { @@ -253,7 +258,7 @@ impl, M: Module, MI: ) -> QueryAllBalancesResponse { let (p_result, balances) = self .keeper - .all_balances(ctx, address, pagination.map(Pagination::from)) + .balance_all(ctx, address, pagination.map(Pagination::from)) .unwrap_gas(); QueryAllBalancesResponse { diff --git a/x/bank/src/keeper.rs b/x/bank/src/keeper.rs index 4df677a9..93ee000c 100644 --- a/x/bank/src/keeper.rs +++ b/x/bank/src/keeper.rs @@ -1,4 +1,3 @@ -use crate::types::iter::balances::BalanceIterator; use crate::{BankParams, BankParamsKeeper, GenesisState}; use bytes::Bytes; use gears::application::keepers::params::ParamsKeeper; @@ -24,7 +23,7 @@ use gears::types::tx::metadata::Metadata; use gears::types::uint::Uint256; use gears::x::errors::{AccountNotFound, BankCoinsError, BankKeeperError, InsufficientFundsError}; use gears::x::keepers::auth::AuthKeeper; -use gears::x::keepers::bank::BankKeeper; +use gears::x::keepers::bank::{BalancesKeeper, BankKeeper}; use gears::x::keepers::gov::GovernanceBankKeeper; use gears::x::keepers::staking::StakingBankKeeper; use gears::x::module::Module; @@ -172,18 +171,39 @@ impl< PSK: ParamsSubspaceKey, AK: AuthKeeper + Send + Sync + 'static, M: Module, - > StakingBankKeeper for Keeper + > BalancesKeeper for Keeper { - fn all_balances>( + fn balance_all>( &self, ctx: &CTX, addr: AccAddress, - ) -> Result, GasStoreErrors> { - let (_, result) = self.all_balances(ctx, addr, None)?; + pagination: Option, + ) -> Result<(Option, Vec), GasStoreErrors> { + let bank_store = ctx.kv_store(&self.store_key); + let prefix = create_denom_balance_prefix(addr.clone()); + let account_store = bank_store.prefix_store(prefix); + + let mut balances = vec![]; - Ok(result) + let (p_result, iterator) = account_store.into_range(..).maybe_paginate(pagination); + for rcoin in iterator { + let (_, coin) = rcoin?; + let coin: UnsignedCoin = UnsignedCoin::decode::(coin.into_owned().into()) + .ok() + .unwrap_or_corrupt(); + balances.push(coin); + } + Ok((p_result, balances)) } +} +impl< + SK: StoreKey, + PSK: ParamsSubspaceKey, + AK: AuthKeeper + Send + Sync + 'static, + M: Module, + > StakingBankKeeper for Keeper +{ fn send_coins_from_module_to_module>( &self, ctx: &mut CTX, @@ -222,24 +242,6 @@ impl< M: Module, > GovernanceBankKeeper for Keeper { - fn balance_all>( - &self, - ctx: &CTX, - address: &AccAddress, - ) -> Result, GasStoreErrors> { - let iterator = BalanceIterator::new(ctx.kv_store(&self.store_key), address) - .map(|this| this.map(|(_, val)| val)); - - let mut balances = Vec::::new(); - for coin in iterator { - let coin = coin?; - - balances.push(coin); - } - - Ok(balances) - } - fn balance>( &self, ctx: &CTX, @@ -269,8 +271,12 @@ impl< } } -impl, M: Module> - Keeper +impl< + SK: StoreKey, + PSK: ParamsSubspaceKey, + AK: AuthKeeper + Send + Sync + 'static, + M: Module, + > Keeper { pub fn new(store_key: SK, params_subspace_key: PSK, auth_keeper: AK) -> Self { let bank_params_keeper = BankParamsKeeper { @@ -410,29 +416,6 @@ impl, M: Module> Ok(()) } - pub fn all_balances>( - &self, - ctx: &CTX, - addr: AccAddress, - pagination: Option, - ) -> Result<(Option, Vec), GasStoreErrors> { - let bank_store = ctx.kv_store(&self.store_key); - let prefix = create_denom_balance_prefix(addr); - let account_store = bank_store.prefix_store(prefix); - - let mut balances = vec![]; - - let (p_result, iterator) = account_store.into_range(..).maybe_paginate(pagination); - for rcoin in iterator { - let (_, coin) = rcoin?; - let coin: UnsignedCoin = UnsignedCoin::decode::(coin.into_owned().into()) - .ok() - .unwrap_or_corrupt(); - balances.push(coin); - } - Ok((p_result, balances)) - } - /// Gets the total supply of every denom pub fn total_supply( &self, @@ -962,7 +945,7 @@ impl, M: Module> ), BankKeeperError, > { - let (pagination, total) = self.all_balances(ctx, addr.clone(), pagination)?; + let (pagination, total) = self.balance_all(ctx, addr.clone(), pagination)?; let locked = self.locked_coins(ctx, addr)?; let total = UnsignedCoins::new(total)?; diff --git a/x/distribution/src/keeper/allocation.rs b/x/distribution/src/keeper/allocation.rs index fd9ff382..dc327070 100644 --- a/x/distribution/src/keeper/allocation.rs +++ b/x/distribution/src/keeper/allocation.rs @@ -44,8 +44,9 @@ impl< // (and distributed to the previous proposer) let fees_collected_int = self .bank_keeper - .all_balances(ctx, self.fee_collector_module.get_address()) - .unwrap_gas(); + .balance_all(ctx, self.fee_collector_module.get_address(), None) + .unwrap_gas() + .1; let fees_collected = DecimalCoins::try_from(fees_collected_int.clone())?; // transfer collected fees to the distribution module account diff --git a/x/distribution/src/keeper/mod.rs b/x/distribution/src/keeper/mod.rs index fdfe958e..e4742ffc 100644 --- a/x/distribution/src/keeper/mod.rs +++ b/x/distribution/src/keeper/mod.rs @@ -182,8 +182,9 @@ impl< self.check_set_distribution_account(ctx).unwrap_gas(); let balances = self .bank_keeper - .all_balances(ctx, self.distribution_module.get_address()) - .unwrap_gas(); + .balance_all(ctx, self.distribution_module.get_address(), None) + .unwrap_gas() + .1; if module_holdings_int != Some(UnsignedCoins::new(balances)?) { return Err(anyhow!( diff --git a/x/gov/src/keeper.rs b/x/gov/src/keeper.rs index 977310ec..358f3e90 100644 --- a/x/gov/src/keeper.rs +++ b/x/gov/src/keeper.rs @@ -181,8 +181,9 @@ impl< let balance = self .bank_keeper - .balance_all(ctx, &self.gov_mod.get_address()) - .unwrap_gas(); + .balance_all(ctx, self.gov_mod.get_address(), None) + .unwrap_gas() + .1; /* Okay. I think that in our implementation there is no need to create account if it. diff --git a/x/staking/src/keeper/mod.rs b/x/staking/src/keeper/mod.rs index 71b979a7..81cc2078 100644 --- a/x/staking/src/keeper/mod.rs +++ b/x/staking/src/keeper/mod.rs @@ -208,8 +208,9 @@ impl< let bonded_balance = self .bank_keeper - .all_balances::>(ctx, self.bonded_module.get_address()) - .unwrap_gas(); + .balance_all::>(ctx, self.bonded_module.get_address(), None) + .unwrap_gas() + .1; // there's a check in the cosmos SDK to ensure that a new module account is only created if the balance is zero // (the logic being that the module account will be set in the genesis file and created by the auth module @@ -232,8 +233,13 @@ impl< let not_bonded_balance = self .bank_keeper - .all_balances::>(ctx, self.not_bonded_module.get_address()) - .unwrap_gas(); + .balance_all::>( + ctx, + self.not_bonded_module.get_address(), + None, + ) + .unwrap_gas() + .1; // see comment above for the logic of creating a new module account self.auth_keeper @@ -589,12 +595,14 @@ impl< let denom = self.staking_params_keeper.try_get(ctx)?.bond_denom; let not_bonded_tokens = self .bank_keeper - .all_balances(ctx, self.not_bonded_module.get_address())? + .balance_all(ctx, self.not_bonded_module.get_address(), None)? + .1 .into_iter() .find(|e| e.denom == denom); let bonded_tokens = self .bank_keeper - .all_balances(ctx, self.bonded_module.get_address())? + .balance_all(ctx, self.bonded_module.get_address(), None)? + .1 .into_iter() .find(|e| e.denom == denom); Ok(Pool { From ff9cf5e2f6b8ce9479d50ea05113da599515bb07 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Mon, 30 Sep 2024 13:08:50 +0300 Subject: [PATCH 04/33] refactor keys --- x/bank/src/keeper.rs | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/x/bank/src/keeper.rs b/x/bank/src/keeper.rs index 93ee000c..ccc317a7 100644 --- a/x/bank/src/keeper.rs +++ b/x/bank/src/keeper.rs @@ -959,22 +959,16 @@ impl< } fn denom_metadata_key(denom: String) -> Vec { - let mut key = Vec::new(); - key.extend(DENOM_METADATA_PREFIX); - key.extend(denom.into_bytes()); - key + [DENOM_METADATA_PREFIX.to_vec(), denom.into_bytes()].concat() } fn create_denom_balance_prefix(addr: AccAddress) -> Vec { - let addr_len = addr.len(); - let mut addr: Vec = addr.into(); - let mut prefix = Vec::new(); - - prefix.extend(ADDRESS_BALANCES_STORE_PREFIX); - prefix.push(addr_len); - prefix.append(&mut addr); - - prefix + [ + ADDRESS_BALANCES_STORE_PREFIX.to_vec(), + [addr.len()].to_vec(), + addr.into(), + ] + .concat() } //TODO: copy tests across From 8b17c05ddc14cc01a60f0d96b0bce1b88db55372 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Mon, 30 Sep 2024 15:15:06 +0300 Subject: [PATCH 05/33] comment out unused iterator --- x/bank/src/types/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/bank/src/types/mod.rs b/x/bank/src/types/mod.rs index 89ba963e..c63ce6dc 100644 --- a/x/bank/src/types/mod.rs +++ b/x/bank/src/types/mod.rs @@ -1,2 +1,2 @@ -pub mod iter; +// pub mod iter; pub mod query; From ae1e118d15194ca34cc7bf4df7748054fd5d3da3 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Mon, 30 Sep 2024 15:45:18 +0300 Subject: [PATCH 06/33] split to different files keeper --- x/bank/src/abci_handler.rs | 1 - x/bank/src/genesis.rs | 1 - x/bank/src/keeper/balances.rs | 34 ++++ x/bank/src/keeper/bank.rs | 115 +++++++++++ x/bank/src/keeper/gov.rs | 37 ++++ x/bank/src/{keeper.rs => keeper/mod.rs} | 250 ++---------------------- x/bank/src/keeper/staking.rs | 39 ++++ 7 files changed, 243 insertions(+), 234 deletions(-) create mode 100644 x/bank/src/keeper/balances.rs create mode 100644 x/bank/src/keeper/bank.rs create mode 100644 x/bank/src/keeper/gov.rs rename x/bank/src/{keeper.rs => keeper/mod.rs} (79%) create mode 100644 x/bank/src/keeper/staking.rs diff --git a/x/bank/src/abci_handler.rs b/x/bank/src/abci_handler.rs index d8982e2e..98b04c9f 100644 --- a/x/bank/src/abci_handler.rs +++ b/x/bank/src/abci_handler.rs @@ -233,7 +233,6 @@ impl< pagination, }: QuerySpendableBalancesRequest, ) -> QuerySpendableBalancesResponse { - // TODO: edit error "handling" let (spendable, pagination_result) = self .keeper .spendable_coins(ctx, &address, pagination.map(Pagination::from)) diff --git a/x/bank/src/genesis.rs b/x/bank/src/genesis.rs index a22e9d77..9c05c1b9 100644 --- a/x/bank/src/genesis.rs +++ b/x/bank/src/genesis.rs @@ -6,7 +6,6 @@ use serde::{Deserialize, Serialize}; use crate::BankParams; -// TODO: should remove total supply since it can be derived from the balances #[derive(Serialize, Deserialize, Clone, Debug)] pub struct GenesisState { pub balances: Vec, diff --git a/x/bank/src/keeper/balances.rs b/x/bank/src/keeper/balances.rs new file mode 100644 index 00000000..273497a7 --- /dev/null +++ b/x/bank/src/keeper/balances.rs @@ -0,0 +1,34 @@ +use super::*; + +impl< + SK: StoreKey, + PSK: ParamsSubspaceKey, + AK: AuthKeeper + Send + Sync + 'static, + M: Module, + > BalancesKeeper for Keeper +{ + fn balance_all>( + &self, + ctx: &CTX, + addr: AccAddress, + pagination: Option, + ) -> Result<(Option, Vec), GasStoreErrors> { + let bank_store = ctx.kv_store(&self.store_key); + let prefix = create_denom_balance_prefix(addr.clone()); + let account_store = bank_store.prefix_store(prefix); + + let mut balances = vec![]; + + let (p_result, iterator) = account_store.into_range(..).maybe_paginate(pagination); + for rcoin in iterator { + let (_, coin) = rcoin?; + let coin: UnsignedCoin = UnsignedCoin::decode::(coin.into_owned().into()) + .ok() + .unwrap_or_corrupt(); + balances.push(coin); + } + Ok((p_result, balances)) + } + + +} diff --git a/x/bank/src/keeper/bank.rs b/x/bank/src/keeper/bank.rs new file mode 100644 index 00000000..b6beb089 --- /dev/null +++ b/x/bank/src/keeper/bank.rs @@ -0,0 +1,115 @@ +use super::*; + +impl< + SK: StoreKey, + PSK: ParamsSubspaceKey, + AK: AuthKeeper + Send + Sync + 'static, + M: Module, + > BankKeeper for Keeper +{ + fn send_coins_from_account_to_module>( + &self, + ctx: &mut CTX, + from_address: AccAddress, + to_module: &M, + amount: UnsignedCoins, + ) -> Result<(), BankKeeperError> { + self.auth_keeper + .check_create_new_module_account(ctx, to_module)?; + + let msg = MsgSend { + from_address, + to_address: to_module.get_address(), + amount, + }; + + self.send_coins(ctx, msg)?; + + Ok(()) + } + + fn denom_metadata>( + &self, + ctx: &CTX, + base: &Denom, + ) -> Result, GasStoreErrors> { + let bank_store = ctx.kv_store(&self.store_key); + let denom_metadata_store = bank_store.prefix_store(denom_metadata_key(base.to_string())); + + Ok(denom_metadata_store + .get(&base.to_string().into_bytes())? + .map(|metadata| { + Metadata::decode::<&[u8]>(&metadata) + .ok() + .unwrap_or_corrupt() + })) + } + + fn coins_burn>( + &self, + ctx: &mut CTX, + module: &M, + deposit: &UnsignedCoins, + ) -> Result<(), BankKeeperError> { + let module_acc_addr = module.get_address(); + + let account = self + .auth_keeper + .get_account(ctx, &module_acc_addr)? + .ok_or(AccountNotFound::new(module_acc_addr.to_string()))?; + + match account.has_permissions("burner") { + true => Ok(()), + false => Err(BankKeeperError::AccountPermission), + }?; + + self.sub_unlocked_coins(ctx, &module_acc_addr, deposit)?; + + for coin in deposit.inner() { + let supply = self.supply(ctx, &coin.denom)?; // TODO: HOW TO HANDLE OPTION::NONE + if let Some(mut supply) = supply { + supply.amount.sub_assign(coin.amount); + self.set_supply(ctx, supply)?; + } + } + + ctx.push_event(Event::new( + "burn", + vec![ + EventAttribute::new( + "burner".as_bytes().to_owned().into(), + account.get_address().as_ref().to_owned().into(), + false, + ), + EventAttribute::new( + "amount".as_bytes().to_owned().into(), + format!("{deposit:?}").into(), + false, + ), + ], + )); + + Ok(()) + } + + fn send_coins_from_module_to_account>( + &self, + ctx: &mut CTX, + address: &AccAddress, + module: &M, + amount: UnsignedCoins, + ) -> Result<(), BankKeeperError> { + let module_address = module.get_address(); + + // TODO: what is blocked account and how to handle it https://github.com/cosmos/cosmos-sdk/blob/d3f09c222243bb3da3464969f0366330dcb977a8/x/bank/keeper/keeper.go#L316-L318 + + self.send_coins( + ctx, + MsgSend { + from_address: module_address, + to_address: address.clone(), + amount, + }, + ) + } +} diff --git a/x/bank/src/keeper/gov.rs b/x/bank/src/keeper/gov.rs new file mode 100644 index 00000000..3b21e635 --- /dev/null +++ b/x/bank/src/keeper/gov.rs @@ -0,0 +1,37 @@ +use super::*; + +impl< + SK: StoreKey, + PSK: ParamsSubspaceKey, + AK: AuthKeeper + Send + Sync + 'static, + M: Module, + > GovernanceBankKeeper for Keeper +{ + fn balance>( + &self, + ctx: &CTX, + address: &AccAddress, + denom: &Denom, + ) -> Result { + let store = ctx + .kv_store(&self.store_key) + .prefix_store(account_key(address)); + + let coin_bytes = store.get(denom.as_str().as_bytes())?; + let coin = if let Some(coin_bytes) = coin_bytes { + UnsignedCoin { + denom: denom.to_owned(), + amount: Uint256::from_str(&String::from_utf8_lossy(&coin_bytes)) + .ok() + .unwrap_or_corrupt(), + } + } else { + UnsignedCoin { + denom: denom.to_owned(), + amount: Uint256::zero(), + } + }; + + Ok(coin) + } +} diff --git a/x/bank/src/keeper.rs b/x/bank/src/keeper/mod.rs similarity index 79% rename from x/bank/src/keeper.rs rename to x/bank/src/keeper/mod.rs index ccc317a7..21fbf8d8 100644 --- a/x/bank/src/keeper.rs +++ b/x/bank/src/keeper/mod.rs @@ -31,6 +31,11 @@ use std::marker::PhantomData; use std::ops::SubAssign; use std::{collections::HashMap, str::FromStr}; +pub mod balances; +pub mod bank; +pub mod gov; +pub mod staking; + const SUPPLY_KEY: [u8; 1] = [0]; const ADDRESS_BALANCES_STORE_PREFIX: [u8; 1] = [2]; const DENOM_METADATA_PREFIX: [u8; 1] = [1]; @@ -44,6 +49,19 @@ pub(crate) fn account_key(addr: &AccAddress) -> Vec { .concat() } +fn denom_metadata_key(denom: String) -> Vec { + [DENOM_METADATA_PREFIX.to_vec(), denom.into_bytes()].concat() +} + +fn create_denom_balance_prefix(addr: AccAddress) -> Vec { + [ + ADDRESS_BALANCES_STORE_PREFIX.to_vec(), + [addr.len()].to_vec(), + addr.into(), + ] + .concat() +} + #[derive(Debug, Clone)] pub struct Keeper, M: Module> { store_key: SK, @@ -52,225 +70,6 @@ pub struct Keeper, M module_key: PhantomData, } -impl< - SK: StoreKey, - PSK: ParamsSubspaceKey, - AK: AuthKeeper + Send + Sync + 'static, - M: Module, - > BankKeeper for Keeper -{ - fn send_coins_from_account_to_module>( - &self, - ctx: &mut CTX, - from_address: AccAddress, - to_module: &M, - amount: UnsignedCoins, - ) -> Result<(), BankKeeperError> { - self.auth_keeper - .check_create_new_module_account(ctx, to_module)?; - - let msg = MsgSend { - from_address, - to_address: to_module.get_address(), - amount, - }; - - self.send_coins(ctx, msg)?; - - Ok(()) - } - - fn denom_metadata>( - &self, - ctx: &CTX, - base: &Denom, - ) -> Result, GasStoreErrors> { - let bank_store = ctx.kv_store(&self.store_key); - let denom_metadata_store = bank_store.prefix_store(denom_metadata_key(base.to_string())); - - Ok(denom_metadata_store - .get(&base.to_string().into_bytes())? - .map(|metadata| { - Metadata::decode::<&[u8]>(&metadata) - .ok() - .unwrap_or_corrupt() - })) - } - - fn coins_burn>( - &self, - ctx: &mut CTX, - module: &M, - deposit: &UnsignedCoins, - ) -> Result<(), BankKeeperError> { - let module_acc_addr = module.get_address(); - - let account = self - .auth_keeper - .get_account(ctx, &module_acc_addr)? - .ok_or(AccountNotFound::new(module_acc_addr.to_string()))?; - - match account.has_permissions("burner") { - true => Ok(()), - false => Err(BankKeeperError::AccountPermission), - }?; - - self.sub_unlocked_coins(ctx, &module_acc_addr, deposit)?; - - for coin in deposit.inner() { - let supply = self.supply(ctx, &coin.denom)?; // TODO: HOW TO HANDLE OPTION::NONE - if let Some(mut supply) = supply { - supply.amount.sub_assign(coin.amount); - self.set_supply(ctx, supply)?; - } - } - - ctx.push_event(Event::new( - "burn", - vec![ - EventAttribute::new( - "burner".as_bytes().to_owned().into(), - account.get_address().as_ref().to_owned().into(), - false, - ), - EventAttribute::new( - "amount".as_bytes().to_owned().into(), - format!("{deposit:?}").into(), - false, - ), - ], - )); - - Ok(()) - } - - fn send_coins_from_module_to_account>( - &self, - ctx: &mut CTX, - address: &AccAddress, - module: &M, - amount: UnsignedCoins, - ) -> Result<(), BankKeeperError> { - let module_address = module.get_address(); - - // TODO: what is blocked account and how to handle it https://github.com/cosmos/cosmos-sdk/blob/d3f09c222243bb3da3464969f0366330dcb977a8/x/bank/keeper/keeper.go#L316-L318 - - self.send_coins( - ctx, - MsgSend { - from_address: module_address, - to_address: address.clone(), - amount, - }, - ) - } -} - -impl< - SK: StoreKey, - PSK: ParamsSubspaceKey, - AK: AuthKeeper + Send + Sync + 'static, - M: Module, - > BalancesKeeper for Keeper -{ - fn balance_all>( - &self, - ctx: &CTX, - addr: AccAddress, - pagination: Option, - ) -> Result<(Option, Vec), GasStoreErrors> { - let bank_store = ctx.kv_store(&self.store_key); - let prefix = create_denom_balance_prefix(addr.clone()); - let account_store = bank_store.prefix_store(prefix); - - let mut balances = vec![]; - - let (p_result, iterator) = account_store.into_range(..).maybe_paginate(pagination); - for rcoin in iterator { - let (_, coin) = rcoin?; - let coin: UnsignedCoin = UnsignedCoin::decode::(coin.into_owned().into()) - .ok() - .unwrap_or_corrupt(); - balances.push(coin); - } - Ok((p_result, balances)) - } -} - -impl< - SK: StoreKey, - PSK: ParamsSubspaceKey, - AK: AuthKeeper + Send + Sync + 'static, - M: Module, - > StakingBankKeeper for Keeper -{ - fn send_coins_from_module_to_module>( - &self, - ctx: &mut CTX, - sender_pool: &M, - recepient_pool: &M, - amount: UnsignedCoins, - ) -> Result<(), BankKeeperError> { - self.send_coins_from_module_to_module(ctx, sender_pool, recepient_pool, amount) - } - - fn undelegate_coins_from_module_to_account>( - &self, - ctx: &mut CTX, - sender_module: &M, - addr: AccAddress, - amount: UnsignedCoins, - ) -> Result<(), BankKeeperError> { - self.undelegate_coins_from_module_to_account(ctx, sender_module, addr, amount) - } - - fn delegate_coins_from_account_to_module>( - &self, - ctx: &mut CTX, - sender_addr: AccAddress, - recepient_module: &M, - amount: UnsignedCoins, - ) -> Result<(), BankKeeperError> { - self.delegate_coins_from_account_to_module(ctx, sender_addr, recepient_module, amount) - } -} - -impl< - SK: StoreKey, - PSK: ParamsSubspaceKey, - AK: AuthKeeper + Send + Sync + 'static, - M: Module, - > GovernanceBankKeeper for Keeper -{ - fn balance>( - &self, - ctx: &CTX, - address: &AccAddress, - denom: &Denom, - ) -> Result { - let store = ctx - .kv_store(&self.store_key) - .prefix_store(account_key(address)); - - let coin_bytes = store.get(denom.as_str().as_bytes())?; - let coin = if let Some(coin_bytes) = coin_bytes { - UnsignedCoin { - denom: denom.to_owned(), - amount: Uint256::from_str(&String::from_utf8_lossy(&coin_bytes)) - .ok() - .unwrap_or_corrupt(), - } - } else { - UnsignedCoin { - denom: denom.to_owned(), - amount: Uint256::zero(), - } - }; - - Ok(coin) - } -} - impl< SK: StoreKey, PSK: ParamsSubspaceKey, @@ -958,17 +757,4 @@ impl< } } -fn denom_metadata_key(denom: String) -> Vec { - [DENOM_METADATA_PREFIX.to_vec(), denom.into_bytes()].concat() -} - -fn create_denom_balance_prefix(addr: AccAddress) -> Vec { - [ - ADDRESS_BALANCES_STORE_PREFIX.to_vec(), - [addr.len()].to_vec(), - addr.into(), - ] - .concat() -} - //TODO: copy tests across diff --git a/x/bank/src/keeper/staking.rs b/x/bank/src/keeper/staking.rs new file mode 100644 index 00000000..e4f30d0c --- /dev/null +++ b/x/bank/src/keeper/staking.rs @@ -0,0 +1,39 @@ +use super::*; + +impl< + SK: StoreKey, + PSK: ParamsSubspaceKey, + AK: AuthKeeper + Send + Sync + 'static, + M: Module, + > StakingBankKeeper for Keeper +{ + fn send_coins_from_module_to_module>( + &self, + ctx: &mut CTX, + sender_pool: &M, + recepient_pool: &M, + amount: UnsignedCoins, + ) -> Result<(), BankKeeperError> { + self.send_coins_from_module_to_module(ctx, sender_pool, recepient_pool, amount) + } + + fn undelegate_coins_from_module_to_account>( + &self, + ctx: &mut CTX, + sender_module: &M, + addr: AccAddress, + amount: UnsignedCoins, + ) -> Result<(), BankKeeperError> { + self.undelegate_coins_from_module_to_account(ctx, sender_module, addr, amount) + } + + fn delegate_coins_from_account_to_module>( + &self, + ctx: &mut CTX, + sender_addr: AccAddress, + recepient_module: &M, + amount: UnsignedCoins, + ) -> Result<(), BankKeeperError> { + self.delegate_coins_from_account_to_module(ctx, sender_addr, recepient_module, amount) + } +} From 411de60c49bb15e0e617e34b7742e7b1e8dfed91 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Mon, 30 Sep 2024 16:04:36 +0300 Subject: [PATCH 07/33] move implementation to trait --- gears/src/x/keepers/staking.rs | 7 +++ x/bank/src/keeper/mod.rs | 80 ---------------------------------- x/bank/src/keeper/staking.rs | 44 +++++++++++++++++-- 3 files changed, 48 insertions(+), 83 deletions(-) diff --git a/gears/src/x/keepers/staking.rs b/gears/src/x/keepers/staking.rs index 8452c1a9..60633a5e 100644 --- a/gears/src/x/keepers/staking.rs +++ b/gears/src/x/keepers/staking.rs @@ -216,6 +216,10 @@ pub trait StakingBankKeeper: // // BurnCoins(ctx sdk.Context, name string, amt sdk.Coins) error + /// Method delegates coins and transfers them from a + /// delegator account to a module account. It creates the module accounts if it don't exist. + /// It's safe operation because the modules are app generic parameter + /// which cannot be added in runtime. fn send_coins_from_module_to_module>( &self, ctx: &mut CTX, @@ -224,6 +228,9 @@ pub trait StakingBankKeeper: amount: UnsignedCoins, ) -> Result<(), BankKeeperError>; + /// Method undelegates the unbonding coins and transfers + /// them from a module account to the delegator account. It will panic if the + /// module account does not exist or is unauthorized. fn undelegate_coins_from_module_to_account>( &self, ctx: &mut CTX, diff --git a/x/bank/src/keeper/mod.rs b/x/bank/src/keeper/mod.rs index 21fbf8d8..d582401e 100644 --- a/x/bank/src/keeper/mod.rs +++ b/x/bank/src/keeper/mod.rs @@ -263,29 +263,6 @@ impl< Ok(()) } - /// send_coins_from_module_to_module delegates coins and transfers them from a - /// delegator account to a module account. It creates the module accounts if it don't exist. - /// It's safe operation because the modules are app generic parameter - /// which cannot be added in runtime. - pub fn send_coins_from_module_to_module>( - &self, - ctx: &mut CTX, - sender_pool: &M, - recepient_pool: &M, - amount: UnsignedCoins, - ) -> Result<(), BankKeeperError> { - self.auth_keeper - .check_create_new_module_account(ctx, recepient_pool)?; - - let msg = MsgSend { - from_address: sender_pool.get_address(), - to_address: recepient_pool.get_address(), - amount, - }; - - self.send_coins(ctx, msg) - } - fn send_coins>( &self, ctx: &mut CTX, @@ -463,33 +440,6 @@ impl< (p_result, denoms_metadata) } - pub fn delegate_coins_from_account_to_module< - DB: Database, - CTX: TransactionalContext, - >( - &self, - ctx: &mut CTX, - sender_addr: AccAddress, - recepient_module: &M, - amount: UnsignedCoins, - ) -> Result<(), BankKeeperError> { - let recepient_module_addr = recepient_module.get_address(); - self.auth_keeper - .check_create_new_module_account(ctx, recepient_module)?; - - if !recepient_module - .get_permissions() - .iter() - .any(|p| p == "staking") - { - return Err(BankKeeperError::Permission(format!( - "module account {} does not have permissions to receive delegated coins", - recepient_module.get_name() - ))); - } - self.delegate_coins(ctx, sender_addr, recepient_module_addr, amount) - } - /// delegate_coins performs delegation by deducting amt coins from an account with /// address addr. For vesting accounts, delegations amounts are tracked for both /// vesting and vested coins. The coins are then transferred from the delegator @@ -556,36 +506,6 @@ impl< Ok(self.add_coins(ctx, &module_acc_addr, amount.into())?) } - /// undelegate_coins_from_module_to_account undelegates the unbonding coins and transfers - /// them from a module account to the delegator account. It will panic if the - /// module account does not exist or is unauthorized. - pub fn undelegate_coins_from_module_to_account< - DB: Database, - CTX: TransactionalContext, - >( - &self, - ctx: &mut CTX, - sender_module: &M, - addr: AccAddress, - amount: UnsignedCoins, - ) -> Result<(), BankKeeperError> { - let sender_module_addr = sender_module.get_address(); - self.auth_keeper - .check_create_new_module_account(ctx, sender_module)?; - - if !sender_module - .get_permissions() - .iter() - .any(|p| p == "staking") - { - return Err(BankKeeperError::Permission(format!( - "module account {} does not have permissions to receive undelegate coins", - sender_module.get_name() - ))); - } - self.undelegate_coins(ctx, sender_module_addr, addr, amount) - } - /// undelegate_coins performs undelegation by crediting amt coins to an account with /// address addr. For vesting accounts, undelegation amounts are tracked for both /// vesting and vested coins. The coins are then transferred from a ModuleAccount diff --git a/x/bank/src/keeper/staking.rs b/x/bank/src/keeper/staking.rs index e4f30d0c..18967d77 100644 --- a/x/bank/src/keeper/staking.rs +++ b/x/bank/src/keeper/staking.rs @@ -14,7 +14,16 @@ impl< recepient_pool: &M, amount: UnsignedCoins, ) -> Result<(), BankKeeperError> { - self.send_coins_from_module_to_module(ctx, sender_pool, recepient_pool, amount) + self.auth_keeper + .check_create_new_module_account(ctx, recepient_pool)?; + + let msg = MsgSend { + from_address: sender_pool.get_address(), + to_address: recepient_pool.get_address(), + amount, + }; + + self.send_coins(ctx, msg) } fn undelegate_coins_from_module_to_account>( @@ -24,7 +33,22 @@ impl< addr: AccAddress, amount: UnsignedCoins, ) -> Result<(), BankKeeperError> { - self.undelegate_coins_from_module_to_account(ctx, sender_module, addr, amount) + let sender_module_addr = sender_module.get_address(); + self.auth_keeper + .check_create_new_module_account(ctx, sender_module)?; + + if !sender_module + .get_permissions() + .iter() + .any(|p| p == "staking") + { + return Err(BankKeeperError::Permission(format!( + "module account {} does not have permissions to receive undelegate coins", + sender_module.get_name() + ))); + } + + self.undelegate_coins(ctx, sender_module_addr, addr, amount) } fn delegate_coins_from_account_to_module>( @@ -34,6 +58,20 @@ impl< recepient_module: &M, amount: UnsignedCoins, ) -> Result<(), BankKeeperError> { - self.delegate_coins_from_account_to_module(ctx, sender_addr, recepient_module, amount) + let recepient_module_addr = recepient_module.get_address(); + self.auth_keeper + .check_create_new_module_account(ctx, recepient_module)?; + + if !recepient_module + .get_permissions() + .iter() + .any(|p| p == "staking") + { + return Err(BankKeeperError::Permission(format!( + "module account {} does not have permissions to receive delegated coins", + recepient_module.get_name() + ))); + } + self.delegate_coins(ctx, sender_addr, recepient_module_addr, amount) } } From c79c50f60e40cee3fbc050002bf1ce63a72b67a3 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Tue, 1 Oct 2024 11:55:21 +0300 Subject: [PATCH 08/33] coment --- x/bank/src/keeper/bank.rs | 5 ++++- x/bank/src/keeper/mod.rs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/x/bank/src/keeper/bank.rs b/x/bank/src/keeper/bank.rs index b6beb089..c6c7747b 100644 --- a/x/bank/src/keeper/bank.rs +++ b/x/bank/src/keeper/bank.rs @@ -66,7 +66,10 @@ impl< self.sub_unlocked_coins(ctx, &module_acc_addr, deposit)?; for coin in deposit.inner() { - let supply = self.supply(ctx, &coin.denom)?; // TODO: HOW TO HANDLE OPTION::NONE + let supply = self.supply(ctx, &coin.denom)?; + // we slightly different from cosmos in this. They return coin always. + // If no value found then new coin with zero balance, subtraction and call of set_supply which deletes coins with zero balance + // We omitted it but if any issue arise be aware that maybe we should delete zero coins if we store any. if let Some(mut supply) = supply { supply.amount.sub_assign(coin.amount); self.set_supply(ctx, supply)?; diff --git a/x/bank/src/keeper/mod.rs b/x/bank/src/keeper/mod.rs index d582401e..f7f34434 100644 --- a/x/bank/src/keeper/mod.rs +++ b/x/bank/src/keeper/mod.rs @@ -356,7 +356,7 @@ impl< ctx: &mut CTX, coin: UnsignedCoin, ) -> Result<(), GasStoreErrors> { - // TODO: need to delete coins with zero balance + // If there will be any issue with bank then delete coins with zero balance. See for more details: let bank_store = ctx.kv_store_mut(&self.store_key); let mut supply_store = bank_store.prefix_store_mut(SUPPLY_KEY); From ee8dc76f7fcb51df2cad6b4a0bd6c002fa6ffd96 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Tue, 1 Oct 2024 11:55:45 +0300 Subject: [PATCH 09/33] url for comment --- x/bank/src/keeper/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/bank/src/keeper/mod.rs b/x/bank/src/keeper/mod.rs index f7f34434..c2240c7f 100644 --- a/x/bank/src/keeper/mod.rs +++ b/x/bank/src/keeper/mod.rs @@ -356,7 +356,7 @@ impl< ctx: &mut CTX, coin: UnsignedCoin, ) -> Result<(), GasStoreErrors> { - // If there will be any issue with bank then delete coins with zero balance. See for more details: + // If there will be any issue with bank then delete coins with zero balance. See for more details: https://github.com/NYBACHOK/gears/blob/c79c50f60e40cee3fbc050002bf1ce63a72b67a3/x/bank/src/keeper/bank.rs#L70-L72 let bank_store = ctx.kv_store_mut(&self.store_key); let mut supply_store = bank_store.prefix_store_mut(SUPPLY_KEY); From 54bbbe5a1c322a6aefe3e77a9ba6109f6e97ace9 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Tue, 1 Oct 2024 12:32:42 +0300 Subject: [PATCH 10/33] after merge --- x/bank/src/keeper/bank.rs | 6 +++--- x/bank/src/keeper/staking.rs | 20 ++++++++------------ x/distribution/src/keeper/allocation.rs | 2 +- x/gov/src/keeper.rs | 2 +- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/x/bank/src/keeper/bank.rs b/x/bank/src/keeper/bank.rs index c6c7747b..568648fc 100644 --- a/x/bank/src/keeper/bank.rs +++ b/x/bank/src/keeper/bank.rs @@ -19,7 +19,7 @@ impl< let msg = MsgSend { from_address, - to_address: to_module.get_address(), + to_address: to_module.address(), amount, }; @@ -51,7 +51,7 @@ impl< module: &M, deposit: &UnsignedCoins, ) -> Result<(), BankKeeperError> { - let module_acc_addr = module.get_address(); + let module_acc_addr = module.address(); let account = self .auth_keeper @@ -102,7 +102,7 @@ impl< module: &M, amount: UnsignedCoins, ) -> Result<(), BankKeeperError> { - let module_address = module.get_address(); + let module_address = module.address(); // TODO: what is blocked account and how to handle it https://github.com/cosmos/cosmos-sdk/blob/d3f09c222243bb3da3464969f0366330dcb977a8/x/bank/keeper/keeper.go#L316-L318 diff --git a/x/bank/src/keeper/staking.rs b/x/bank/src/keeper/staking.rs index 18967d77..96db6dd4 100644 --- a/x/bank/src/keeper/staking.rs +++ b/x/bank/src/keeper/staking.rs @@ -18,8 +18,8 @@ impl< .check_create_new_module_account(ctx, recepient_pool)?; let msg = MsgSend { - from_address: sender_pool.get_address(), - to_address: recepient_pool.get_address(), + from_address: sender_pool.address(), + to_address: recepient_pool.address(), amount, }; @@ -33,18 +33,14 @@ impl< addr: AccAddress, amount: UnsignedCoins, ) -> Result<(), BankKeeperError> { - let sender_module_addr = sender_module.get_address(); + let sender_module_addr = sender_module.address(); self.auth_keeper .check_create_new_module_account(ctx, sender_module)?; - if !sender_module - .get_permissions() - .iter() - .any(|p| p == "staking") - { + if !sender_module.permissions().iter().any(|p| p == "staking") { return Err(BankKeeperError::Permission(format!( "module account {} does not have permissions to receive undelegate coins", - sender_module.get_name() + sender_module.name() ))); } @@ -58,18 +54,18 @@ impl< recepient_module: &M, amount: UnsignedCoins, ) -> Result<(), BankKeeperError> { - let recepient_module_addr = recepient_module.get_address(); + let recepient_module_addr = recepient_module.address(); self.auth_keeper .check_create_new_module_account(ctx, recepient_module)?; if !recepient_module - .get_permissions() + .permissions() .iter() .any(|p| p == "staking") { return Err(BankKeeperError::Permission(format!( "module account {} does not have permissions to receive delegated coins", - recepient_module.get_name() + recepient_module.name() ))); } self.delegate_coins(ctx, sender_addr, recepient_module_addr, amount) diff --git a/x/distribution/src/keeper/allocation.rs b/x/distribution/src/keeper/allocation.rs index dc327070..f6caa5f3 100644 --- a/x/distribution/src/keeper/allocation.rs +++ b/x/distribution/src/keeper/allocation.rs @@ -44,7 +44,7 @@ impl< // (and distributed to the previous proposer) let fees_collected_int = self .bank_keeper - .balance_all(ctx, self.fee_collector_module.get_address(), None) + .balance_all(ctx, self.fee_collector_module.address(), None) .unwrap_gas() .1; let fees_collected = DecimalCoins::try_from(fees_collected_int.clone())?; diff --git a/x/gov/src/keeper.rs b/x/gov/src/keeper.rs index 358f3e90..b07932f7 100644 --- a/x/gov/src/keeper.rs +++ b/x/gov/src/keeper.rs @@ -181,7 +181,7 @@ impl< let balance = self .bank_keeper - .balance_all(ctx, self.gov_mod.get_address(), None) + .balance_all(ctx, self.gov_mod.address(), None) .unwrap_gas() .1; /* From 2fdb88ab9cec30b43921cc6fe9cbddf767d11de8 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Tue, 1 Oct 2024 13:38:33 +0300 Subject: [PATCH 11/33] check for blocked account --- gaia-rs/src/modules.rs | 2 +- gears/src/x/errors.rs | 2 ++ x/bank/Cargo.toml | 1 + x/bank/src/abci_handler.rs | 2 +- x/bank/src/keeper/bank.rs | 17 +++++++++++++++-- x/bank/src/keeper/gov.rs | 2 +- x/bank/src/keeper/staking.rs | 2 +- x/bank/tests/abci.rs | 2 +- 8 files changed, 23 insertions(+), 7 deletions(-) diff --git a/gaia-rs/src/modules.rs b/gaia-rs/src/modules.rs index a65156ef..21823ae5 100644 --- a/gaia-rs/src/modules.rs +++ b/gaia-rs/src/modules.rs @@ -1,6 +1,6 @@ use gears::x::module::Module; -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, strum::EnumIter)] pub enum GaiaModules { FeeCollector, BondedPool, diff --git a/gears/src/x/errors.rs b/gears/src/x/errors.rs index d7508653..6db37a44 100644 --- a/gears/src/x/errors.rs +++ b/gears/src/x/errors.rs @@ -176,6 +176,8 @@ pub enum BankKeeperError { AccountNotFound(#[from] AccountNotFound), #[error("account doesnt have enought permission")] AccountPermission, + #[error("{0} is not allowed to receive funds. Probably tried send to module as account")] + Blocked(AccAddress), #[error("{0}")] GasError(#[from] GasStoreErrors), } diff --git a/x/bank/Cargo.toml b/x/bank/Cargo.toml index 447c3fc6..01cb4786 100644 --- a/x/bank/Cargo.toml +++ b/x/bank/Cargo.toml @@ -16,6 +16,7 @@ thiserror = { workspace = true } clap = { workspace = true } anyhow = { workspace = true } nz = { workspace = true } +strum = { workspace = true } #serialization serde = { workspace = true, default-features = false } diff --git a/x/bank/src/abci_handler.rs b/x/bank/src/abci_handler.rs index 98b04c9f..e873f86a 100644 --- a/x/bank/src/abci_handler.rs +++ b/x/bank/src/abci_handler.rs @@ -75,7 +75,7 @@ impl< SK: StoreKey, PSK: ParamsSubspaceKey, AK: AuthKeeper + Send + Sync + 'static, - M: Module, + M: Module + strum::IntoEnumIterator, MI: ModuleInfo + Clone + Send + Sync + 'static, > ABCIHandler for BankABCIHandler { diff --git a/x/bank/src/keeper/bank.rs b/x/bank/src/keeper/bank.rs index 568648fc..69cd9cee 100644 --- a/x/bank/src/keeper/bank.rs +++ b/x/bank/src/keeper/bank.rs @@ -1,10 +1,12 @@ +use std::{collections::HashSet, sync::OnceLock}; + use super::*; impl< SK: StoreKey, PSK: ParamsSubspaceKey, AK: AuthKeeper + Send + Sync + 'static, - M: Module, + M: Module + strum::IntoEnumIterator, > BankKeeper for Keeper { fn send_coins_from_account_to_module>( @@ -104,7 +106,12 @@ impl< ) -> Result<(), BankKeeperError> { let module_address = module.address(); - // TODO: what is blocked account and how to handle it https://github.com/cosmos/cosmos-sdk/blob/d3f09c222243bb3da3464969f0366330dcb977a8/x/bank/keeper/keeper.go#L316-L318 + // Simple check that we don't try to send coins to account that actually a module. + // Cosmos uses set with accounts. For details check: + // https://github.com/cosmos/cosmos-sdk/blob/d3f09c222243bb3da3464969f0366330dcb977a8/x/bank/keeper/keeper.go#L316-L318 + if blocked_addr::().contains(address) { + Err(BankKeeperError::Blocked(address.to_owned()))? + } self.send_coins( ctx, @@ -116,3 +123,9 @@ impl< ) } } + +fn blocked_addr() -> &'static HashSet { + static ADDR: OnceLock> = OnceLock::new(); + + ADDR.get_or_init(|| M::iter().map(|this| this.address()).collect::>()) +} diff --git a/x/bank/src/keeper/gov.rs b/x/bank/src/keeper/gov.rs index 3b21e635..b646ce38 100644 --- a/x/bank/src/keeper/gov.rs +++ b/x/bank/src/keeper/gov.rs @@ -4,7 +4,7 @@ impl< SK: StoreKey, PSK: ParamsSubspaceKey, AK: AuthKeeper + Send + Sync + 'static, - M: Module, + M: Module + strum::IntoEnumIterator, > GovernanceBankKeeper for Keeper { fn balance>( diff --git a/x/bank/src/keeper/staking.rs b/x/bank/src/keeper/staking.rs index 96db6dd4..c0545086 100644 --- a/x/bank/src/keeper/staking.rs +++ b/x/bank/src/keeper/staking.rs @@ -4,7 +4,7 @@ impl< SK: StoreKey, PSK: ParamsSubspaceKey, AK: AuthKeeper + Send + Sync + 'static, - M: Module, + M: Module + strum::IntoEnumIterator, > StakingBankKeeper for Keeper { fn send_coins_from_module_to_module>( diff --git a/x/bank/tests/abci.rs b/x/bank/tests/abci.rs index 7150a4f4..0d31de06 100644 --- a/x/bank/tests/abci.rs +++ b/x/bank/tests/abci.rs @@ -113,7 +113,7 @@ impl ModuleInfo for BankModuleInfo { const NAME: &'static str = "bank"; } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, strum::EnumIter)] pub enum BankModules { FeeCollector, } From 1391c34386aba6f1cb87c63533e0c132be90dac1 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Tue, 1 Oct 2024 13:57:19 +0300 Subject: [PATCH 12/33] fmt --- x/bank/src/keeper/balances.rs | 2 -- x/bank/src/keeper/bank.rs | 2 +- x/staking/src/keeper/mod.rs | 6 +----- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/x/bank/src/keeper/balances.rs b/x/bank/src/keeper/balances.rs index 273497a7..c44020d9 100644 --- a/x/bank/src/keeper/balances.rs +++ b/x/bank/src/keeper/balances.rs @@ -29,6 +29,4 @@ impl< } Ok((p_result, balances)) } - - } diff --git a/x/bank/src/keeper/bank.rs b/x/bank/src/keeper/bank.rs index 69cd9cee..3a8261d5 100644 --- a/x/bank/src/keeper/bank.rs +++ b/x/bank/src/keeper/bank.rs @@ -107,7 +107,7 @@ impl< let module_address = module.address(); // Simple check that we don't try to send coins to account that actually a module. - // Cosmos uses set with accounts. For details check: + // Cosmos uses set with accounts. For details check: // https://github.com/cosmos/cosmos-sdk/blob/d3f09c222243bb3da3464969f0366330dcb977a8/x/bank/keeper/keeper.go#L316-L318 if blocked_addr::().contains(address) { Err(BankKeeperError::Blocked(address.to_owned()))? diff --git a/x/staking/src/keeper/mod.rs b/x/staking/src/keeper/mod.rs index 91d39e85..31d41c8e 100644 --- a/x/staking/src/keeper/mod.rs +++ b/x/staking/src/keeper/mod.rs @@ -233,11 +233,7 @@ impl< let not_bonded_balance = self .bank_keeper - .balance_all::>( - ctx, - self.not_bonded_module.address(), - None, - ) + .balance_all::>(ctx, self.not_bonded_module.address(), None) .unwrap_gas() .1; From 3ba575c828fe922b2e21f288fb7a3c32f76ee186 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Tue, 1 Oct 2024 16:18:03 +0300 Subject: [PATCH 13/33] add bank aux cmd for coins meta --- gaia-rs/src/lib.rs | 7 +++ x/bank/src/aux/cli.rs | 72 ++++++++++++++++++++++++++++ x/bank/src/aux/metadata.rs | 96 ++++++++++++++++++++++++++++++++++++++ x/bank/src/aux/mod.rs | 42 +++++++++++++++++ x/bank/src/lib.rs | 1 + 5 files changed, 218 insertions(+) create mode 100644 x/bank/src/aux/cli.rs create mode 100644 x/bank/src/aux/metadata.rs create mode 100644 x/bank/src/aux/mod.rs diff --git a/gaia-rs/src/lib.rs b/gaia-rs/src/lib.rs index 6b02a792..581db2bf 100644 --- a/gaia-rs/src/lib.rs +++ b/gaia-rs/src/lib.rs @@ -156,6 +156,7 @@ impl AuxHandler for GaiaCore { genutil::gentx::gentx_cmd(cmd, "bank", "staking", &EmptyNodeFetcher)?; } }, + GaiaAuxCmd::Bank(cmd) => bank::aux::handle_aux_cmd(cmd)?, } Ok(NilAux) @@ -166,6 +167,8 @@ impl AuxHandler for GaiaCore { pub enum GaiaAuxCli { #[command(flatten)] Genutil(genutil::client::cli::GenesisCommands), + #[command(flatten)] + Bank(bank::aux::cli::BankAuxCliCommands), } impl TryFrom> for GaiaAuxCmd { @@ -176,12 +179,16 @@ impl TryFrom> for GaiaAuxCmd { GaiaAuxCli::Genutil(var) => GaiaAuxCmd::Genutil( genutil::client::cli::GenesisAuxCli { command: var }.try_into()?, ), + GaiaAuxCli::Bank(var) => { + GaiaAuxCmd::Bank(bank::aux::cli::BankAuxCli { command: var }.try_into()?) + } }) } } pub enum GaiaAuxCmd { Genutil(genutil::cmd::GenesisCmd), + Bank(bank::aux::BankAuxCmd), } impl AuxHandler for GaiaCoreClient { diff --git a/x/bank/src/aux/cli.rs b/x/bank/src/aux/cli.rs new file mode 100644 index 00000000..6f66a4ff --- /dev/null +++ b/x/bank/src/aux/cli.rs @@ -0,0 +1,72 @@ +use std::{marker::PhantomData, path::PathBuf}; + +use clap::{ArgAction, Args, Subcommand, ValueHint}; +use gears::application::ApplicationInfo; + +use super::{metadata::CoinsMetaGenesisCmd, BankAuxCmd}; + +/// Add metadata about coins to genesis file +#[derive(Debug, Clone, Args)] +pub struct CoinsMetaGenesisCli { + #[arg(long, action = ArgAction::Set, value_hint = ValueHint::DirPath, default_value_os_t = AI::home_dir(), help = "directory for config and data")] + pub home: PathBuf, + /// Json with array of metadata or path to json file + pub metadata: String, + /// Dedup input metadata list + #[arg(long, default_value_t = false)] + pub dedup_input: bool, + /// Ignore duplicates found in original genesis file + #[arg(long, default_value_t = true)] + pub ignore_dup: bool, + /// Overwrite metadata with same coin name + #[arg(long, default_value_t = false)] + pub overwrite_same: bool, + + #[arg(skip)] + _marker: PhantomData, +} + +impl From> for CoinsMetaGenesisCmd { + fn from( + CoinsMetaGenesisCli { + home, + metadata, + dedup_input, + ignore_dup, + overwrite_same, + _marker, + }: CoinsMetaGenesisCli, + ) -> Self { + Self { + home, + metadata, + dedup_input, + ignore_dup, + overwrite_same, + } + } +} + +#[derive(Debug, Clone, Subcommand)] +pub enum BankAuxCliCommands { + #[command(name = "add-coins-metadata")] + Genesis(CoinsMetaGenesisCli), +} + +#[derive(Debug, Clone, Args)] +pub struct BankAuxCli { + #[command(subcommand)] + pub command: BankAuxCliCommands, +} + +impl TryFrom> for BankAuxCmd { + type Error = anyhow::Error; + + fn try_from(BankAuxCli { command }: BankAuxCli) -> Result { + match command { + BankAuxCliCommands::Genesis(coins_meta_genesis_cli) => { + Ok(BankAuxCmd::Genesis(coins_meta_genesis_cli.into())) + } + } + } +} diff --git a/x/bank/src/aux/metadata.rs b/x/bank/src/aux/metadata.rs new file mode 100644 index 00000000..49605e91 --- /dev/null +++ b/x/bank/src/aux/metadata.rs @@ -0,0 +1,96 @@ +use std::{ + collections::HashMap, + path::{Path, PathBuf}, +}; + +use gears::{config::ConfigDirectory, types::tx::metadata::Metadata}; + +#[derive(Debug, Clone)] +pub struct CoinsMetaGenesisCmd { + pub home: PathBuf, + pub metadata: String, + pub dedup_input: bool, + pub ignore_dup: bool, + pub overwrite_same: bool, +} + +pub fn add_coins_meta_to_genesis( + home: impl AsRef, + metadata: impl IntoIterator, + dedup_input: bool, + ignore_dup: bool, + overwrite_same: bool, +) -> anyhow::Result<()> { + let metadata = { + let mut metadata = metadata.into_iter().collect::>(); + let pre_dup_len = metadata.len(); + + metadata.dedup(); + + if !dedup_input && ((pre_dup_len != metadata.len()) == true) { + Err(anyhow::anyhow!("Found duplicates in new list"))? + } + + metadata + }; + + let genesis_path = ConfigDirectory::GenesisFile.path_from_hone(&home); + + let mut genesis = serde_json::from_slice::(&std::fs::read(&genesis_path)?)?; + + let value = genesis + .get_mut("app_state") + .ok_or(anyhow::anyhow!("missing `app_state`"))? + .get_mut("bank") + .ok_or(anyhow::anyhow!("`bank` module is not found"))? + .get_mut("denom_metadata") + .ok_or(anyhow::anyhow!("`denom_metadata` is not found"))?; + + let owned_value = value.take(); + + let mut original_meta = serde_json::from_value::>(owned_value)? + .into_iter() + .map(|this| (this.name.clone(), this)) + .collect::>(); + + for meta in metadata { + let dup = original_meta.get(&meta.name); + + match dup { + Some(dup) => { + if !ignore_dup { + Err(anyhow::anyhow!("Duplicate meta: {}", dup.name))? + } + + if !overwrite_same && ((dup == &meta) == true) { + Err(anyhow::anyhow!( + "Similar meta with name: {}\nNew: {:#?}\nOriginal: {:#?}", + dup.name, + meta, + dup + ))? + } else { + original_meta.insert(meta.name.clone(), meta); + } + } + None => { + original_meta.insert(meta.name.clone(), meta); + } + } + } + + *value = serde_json::to_value( + original_meta + .into_iter() + .map(|(_, this)| this) + .collect::>(), + ) + .expect("serde encoding"); + + std::fs::write( + genesis_path, + serde_json::to_string_pretty(value).expect("serde encoding"), + )?; + + Ok(()) +} diff --git a/x/bank/src/aux/mod.rs b/x/bank/src/aux/mod.rs new file mode 100644 index 00000000..8247e23f --- /dev/null +++ b/x/bank/src/aux/mod.rs @@ -0,0 +1,42 @@ +use gears::types::tx::metadata::Metadata; +use metadata::CoinsMetaGenesisCmd; + +pub mod cli; + +mod metadata; + +#[derive(Debug, Clone)] +pub enum BankAuxCmd { + Genesis(CoinsMetaGenesisCmd), +} + +pub fn handle_aux_cmd(cmd: BankAuxCmd) -> anyhow::Result<()> { + match cmd { + BankAuxCmd::Genesis(CoinsMetaGenesisCmd { + home, + metadata, + dedup_input, + ignore_dup, + overwrite_same, + }) => { + let metadata = match serde_json::from_str(&metadata) { + Ok(metadata) => metadata, + Err(_) => match serde_json::from_slice::>(&std::fs::read(&metadata)?) + { + Ok(metadata) => metadata, + Err(_) => Err(anyhow::anyhow!( + "Failed to read `metadata` as json or path to json file" + ))?, + }, + }; + + metadata::add_coins_meta_to_genesis( + home, + metadata, + dedup_input, + ignore_dup, + overwrite_same, + ) + } + } +} diff --git a/x/bank/src/lib.rs b/x/bank/src/lib.rs index ac2f2135..45f8af8a 100644 --- a/x/bank/src/lib.rs +++ b/x/bank/src/lib.rs @@ -1,3 +1,4 @@ +pub mod aux; mod abci_handler; mod client; pub mod errors; From dd028f35f4a8675f54a4d1cc2e7b609127961f22 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Tue, 1 Oct 2024 16:36:59 +0300 Subject: [PATCH 14/33] fix json writing --- x/bank/src/aux/metadata.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/x/bank/src/aux/metadata.rs b/x/bank/src/aux/metadata.rs index 49605e91..5f157d4b 100644 --- a/x/bank/src/aux/metadata.rs +++ b/x/bank/src/aux/metadata.rs @@ -39,16 +39,13 @@ pub fn add_coins_meta_to_genesis( let mut genesis = serde_json::from_slice::(&std::fs::read(&genesis_path)?)?; let value = genesis - .get_mut("app_state") - .ok_or(anyhow::anyhow!("missing `app_state`"))? - .get_mut("bank") - .ok_or(anyhow::anyhow!("`bank` module is not found"))? - .get_mut("denom_metadata") - .ok_or(anyhow::anyhow!("`denom_metadata` is not found"))?; + .pointer_mut("/app_state/bank/denom_metadata") + .ok_or(anyhow::anyhow!( + "`/app_state/bank/denom_metadata` not found. Check is genesis file is valid" + ))? + .take(); - let owned_value = value.take(); - - let mut original_meta = serde_json::from_value::>(owned_value)? + let mut original_meta = serde_json::from_value::>(value)? .into_iter() .map(|this| (this.name.clone(), this)) .collect::>(); @@ -79,7 +76,9 @@ pub fn add_coins_meta_to_genesis( } } - *value = serde_json::to_value( + *genesis + .pointer_mut("/app_state/bank/denom_metadata") + .expect("we checked that this exists") = serde_json::to_value( original_meta .into_iter() .map(|(_, this)| this) @@ -89,7 +88,7 @@ pub fn add_coins_meta_to_genesis( std::fs::write( genesis_path, - serde_json::to_string_pretty(value).expect("serde encoding"), + serde_json::to_string_pretty(&genesis).expect("serde encoding"), )?; Ok(()) From e1b7fd4d2bb2b944b4d3ade30bf2f4a4b68b522e Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Tue, 1 Oct 2024 16:43:22 +0300 Subject: [PATCH 15/33] edit flag for duplicates --- x/bank/src/aux/cli.rs | 10 +++++----- x/bank/src/aux/metadata.rs | 6 +++--- x/bank/src/aux/mod.rs | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/x/bank/src/aux/cli.rs b/x/bank/src/aux/cli.rs index 6f66a4ff..3bd23ab9 100644 --- a/x/bank/src/aux/cli.rs +++ b/x/bank/src/aux/cli.rs @@ -15,9 +15,9 @@ pub struct CoinsMetaGenesisCli { /// Dedup input metadata list #[arg(long, default_value_t = false)] pub dedup_input: bool, - /// Ignore duplicates found in original genesis file - #[arg(long, default_value_t = true)] - pub ignore_dup: bool, + /// Return error if found duplicates with original genesis file + #[arg(long, default_value_t = false)] + pub fail_on_dup: bool, /// Overwrite metadata with same coin name #[arg(long, default_value_t = false)] pub overwrite_same: bool, @@ -32,7 +32,7 @@ impl From> for CoinsMetaGenesisCmd home, metadata, dedup_input, - ignore_dup, + fail_on_dup, overwrite_same, _marker, }: CoinsMetaGenesisCli, @@ -41,7 +41,7 @@ impl From> for CoinsMetaGenesisCmd home, metadata, dedup_input, - ignore_dup, + fail_on_dup, overwrite_same, } } diff --git a/x/bank/src/aux/metadata.rs b/x/bank/src/aux/metadata.rs index 5f157d4b..508330a6 100644 --- a/x/bank/src/aux/metadata.rs +++ b/x/bank/src/aux/metadata.rs @@ -10,7 +10,7 @@ pub struct CoinsMetaGenesisCmd { pub home: PathBuf, pub metadata: String, pub dedup_input: bool, - pub ignore_dup: bool, + pub fail_on_dup: bool, pub overwrite_same: bool, } @@ -18,7 +18,7 @@ pub fn add_coins_meta_to_genesis( home: impl AsRef, metadata: impl IntoIterator, dedup_input: bool, - ignore_dup: bool, + fail_on_dup: bool, overwrite_same: bool, ) -> anyhow::Result<()> { let metadata = { @@ -55,7 +55,7 @@ pub fn add_coins_meta_to_genesis( match dup { Some(dup) => { - if !ignore_dup { + if fail_on_dup { Err(anyhow::anyhow!("Duplicate meta: {}", dup.name))? } diff --git a/x/bank/src/aux/mod.rs b/x/bank/src/aux/mod.rs index 8247e23f..84f73326 100644 --- a/x/bank/src/aux/mod.rs +++ b/x/bank/src/aux/mod.rs @@ -16,7 +16,7 @@ pub fn handle_aux_cmd(cmd: BankAuxCmd) -> anyhow::Result<()> { home, metadata, dedup_input, - ignore_dup, + fail_on_dup: ignore_dup, overwrite_same, }) => { let metadata = match serde_json::from_str(&metadata) { From 80aa99e4096727dd9463a61a62584eac3fc57ff0 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Wed, 2 Oct 2024 09:35:53 +0300 Subject: [PATCH 16/33] polish cmd --- x/bank/src/aux/cli.rs | 18 ++++++------- x/bank/src/aux/metadata.rs | 54 ++++++++++++++++++-------------------- x/bank/src/aux/mod.rs | 12 +++------ 3 files changed, 38 insertions(+), 46 deletions(-) diff --git a/x/bank/src/aux/cli.rs b/x/bank/src/aux/cli.rs index 3bd23ab9..fb725b7a 100644 --- a/x/bank/src/aux/cli.rs +++ b/x/bank/src/aux/cli.rs @@ -13,14 +13,14 @@ pub struct CoinsMetaGenesisCli { /// Json with array of metadata or path to json file pub metadata: String, /// Dedup input metadata list - #[arg(long, default_value_t = false)] + #[arg(long = "dedup", default_value_t = false)] pub dedup_input: bool, - /// Return error if found duplicates with original genesis file - #[arg(long, default_value_t = false)] - pub fail_on_dup: bool, /// Overwrite metadata with same coin name + #[arg(long = "overwrite", default_value_t = false)] + pub overwrite_dup: bool, + /// Don't save changes to disk #[arg(long, default_value_t = false)] - pub overwrite_same: bool, + pub dry: bool, #[arg(skip)] _marker: PhantomData, @@ -32,8 +32,8 @@ impl From> for CoinsMetaGenesisCmd home, metadata, dedup_input, - fail_on_dup, - overwrite_same, + overwrite_dup, + dry, _marker, }: CoinsMetaGenesisCli, ) -> Self { @@ -41,8 +41,8 @@ impl From> for CoinsMetaGenesisCmd home, metadata, dedup_input, - fail_on_dup, - overwrite_same, + overwrite_dup, + dry, } } } diff --git a/x/bank/src/aux/metadata.rs b/x/bank/src/aux/metadata.rs index 508330a6..c8b9f177 100644 --- a/x/bank/src/aux/metadata.rs +++ b/x/bank/src/aux/metadata.rs @@ -10,16 +10,16 @@ pub struct CoinsMetaGenesisCmd { pub home: PathBuf, pub metadata: String, pub dedup_input: bool, - pub fail_on_dup: bool, - pub overwrite_same: bool, + pub overwrite_dup: bool, + pub dry: bool, } pub fn add_coins_meta_to_genesis( home: impl AsRef, metadata: impl IntoIterator, dedup_input: bool, - fail_on_dup: bool, - overwrite_same: bool, + overwrite_dup: bool, + dry: bool, ) -> anyhow::Result<()> { let metadata = { let mut metadata = metadata.into_iter().collect::>(); @@ -55,19 +55,15 @@ pub fn add_coins_meta_to_genesis( match dup { Some(dup) => { - if fail_on_dup { - Err(anyhow::anyhow!("Duplicate meta: {}", dup.name))? - } - - if !overwrite_same && ((dup == &meta) == true) { + if overwrite_dup { + original_meta.insert(meta.name.clone(), meta); + } else { Err(anyhow::anyhow!( - "Similar meta with name: {}\nNew: {:#?}\nOriginal: {:#?}", + "Duplicate meta with name: {}\nNew: {}\nOriginal: {}", dup.name, - meta, - dup + serde_json::to_string_pretty(&meta).expect("serde encoding"), + serde_json::to_string_pretty(&dup).expect("serde encoding"), ))? - } else { - original_meta.insert(meta.name.clone(), meta); } } None => { @@ -76,20 +72,22 @@ pub fn add_coins_meta_to_genesis( } } - *genesis - .pointer_mut("/app_state/bank/denom_metadata") - .expect("we checked that this exists") = serde_json::to_value( - original_meta - .into_iter() - .map(|(_, this)| this) - .collect::>(), - ) - .expect("serde encoding"); - - std::fs::write( - genesis_path, - serde_json::to_string_pretty(&genesis).expect("serde encoding"), - )?; + if !dry { + *genesis + .pointer_mut("/app_state/bank/denom_metadata") + .expect("we checked that this exists") = serde_json::to_value( + original_meta + .into_iter() + .map(|(_, this)| this) + .collect::>(), + ) + .expect("serde encoding"); + + std::fs::write( + genesis_path, + serde_json::to_string_pretty(&genesis).expect("serde encoding"), + )?; + } Ok(()) } diff --git a/x/bank/src/aux/mod.rs b/x/bank/src/aux/mod.rs index 84f73326..46a9ad92 100644 --- a/x/bank/src/aux/mod.rs +++ b/x/bank/src/aux/mod.rs @@ -16,8 +16,8 @@ pub fn handle_aux_cmd(cmd: BankAuxCmd) -> anyhow::Result<()> { home, metadata, dedup_input, - fail_on_dup: ignore_dup, - overwrite_same, + overwrite_dup, + dry, }) => { let metadata = match serde_json::from_str(&metadata) { Ok(metadata) => metadata, @@ -30,13 +30,7 @@ pub fn handle_aux_cmd(cmd: BankAuxCmd) -> anyhow::Result<()> { }, }; - metadata::add_coins_meta_to_genesis( - home, - metadata, - dedup_input, - ignore_dup, - overwrite_same, - ) + metadata::add_coins_meta_to_genesis(home, metadata, dedup_input, overwrite_dup, dry) } } } From 09c0f99ce82ed76af6ff0cc7507979a3390b2388 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Wed, 2 Oct 2024 10:10:24 +0300 Subject: [PATCH 17/33] remove todo from unused code --- x/bank/src/types/iter/balances.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/bank/src/types/iter/balances.rs b/x/bank/src/types/iter/balances.rs index 0d982036..c0d93de8 100644 --- a/x/bank/src/types/iter/balances.rs +++ b/x/bank/src/types/iter/balances.rs @@ -18,7 +18,7 @@ impl<'a, DB: Database> BalanceIterator<'a, DB> { pub fn new(store: Store<'a, DB>, addr: &AccAddress) -> BalanceIterator<'a, DB> { let store = store.prefix_store(account_key(addr)); - // TODO: WHY https://github.com/cosmos/cosmos-sdk/blob/d3f09c222243bb3da3464969f0366330dcb977a8/store/prefix/store.go#L88-L93 + // https://github.com/cosmos/cosmos-sdk/blob/d3f09c222243bb3da3464969f0366330dcb977a8/store/prefix/store.go#L88-L93 BalanceIterator(store.into_range(..)) } } From f2058cca00ebfeb639b132fc81625b173a592055 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Wed, 2 Oct 2024 10:14:40 +0300 Subject: [PATCH 18/33] small changes --- x/bank/src/abci_handler.rs | 10 +++------- x/bank/src/genesis.rs | 3 --- x/bank/src/types/query.rs | 2 +- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/x/bank/src/abci_handler.rs b/x/bank/src/abci_handler.rs index e873f86a..0b40d632 100644 --- a/x/bank/src/abci_handler.rs +++ b/x/bank/src/abci_handler.rs @@ -121,7 +121,7 @@ impl< BankNodeQueryResponse::SupplyOf(self.query_supply_of(ctx, req)) } BankNodeQueryRequest::Spendable(req) => { - let balance = self.spendable(ctx, req); + let balance = self.query_spendable(ctx, req); BankNodeQueryResponse::Spendable(balance) } } @@ -155,7 +155,7 @@ impl< ctx: &mut InitContext<'_, DB, Self::StoreKey>, genesis: Self::Genesis, ) -> Vec { - self.genesis(ctx, genesis); + self.keeper.init_genesis(ctx, genesis); Vec::new() } @@ -221,11 +221,7 @@ impl< } } - pub fn genesis(&self, ctx: &mut InitContext<'_, DB, SK>, genesis: GenesisState) { - self.keeper.init_genesis(ctx, genesis) - } - - fn spendable( + fn query_spendable( &self, ctx: &QueryContext, QuerySpendableBalancesRequest { diff --git a/x/bank/src/genesis.rs b/x/bank/src/genesis.rs index 9c05c1b9..b2b2cadb 100644 --- a/x/bank/src/genesis.rs +++ b/x/bank/src/genesis.rs @@ -28,9 +28,6 @@ impl Default for GenesisState { send_enabled: vec![], default_send_enabled: true, }, - //TODO: this denom metadata should not be hard coded into the bank module - // this has been added here for short term convenience. There should be a - // CLI command to add denom metadata to the genesis state denom_metadata: vec![], // denom_metadata: vec![Metadata { // description: String::new(), diff --git a/x/bank/src/types/query.rs b/x/bank/src/types/query.rs index 5a50931c..160f42c3 100644 --- a/x/bank/src/types/query.rs +++ b/x/bank/src/types/query.rs @@ -43,7 +43,7 @@ pub struct QueryDenomsMetadataRequest { /// QueryBalanceRequest is the request type for the Query/Balance RPC method. #[derive(Clone, PartialEq, Debug, Query, Protobuf)] -#[query(url = "/cosmos.bank.v1beta1.Query/Balance")] // TODO: are u sure? +#[query(url = "/cosmos.bank.v1beta1.Query/Balance")] #[proto(raw = "inner::QueryBalanceRequest")] pub struct QueryBalanceRequest { /// address is the address to query balances for. From 46201813ee6896135a855cc3d883c296e38bddbd Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Wed, 2 Oct 2024 11:03:25 +0300 Subject: [PATCH 19/33] mistake --- gaia-rs/src/abci_handler.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gaia-rs/src/abci_handler.rs b/gaia-rs/src/abci_handler.rs index 199d8d64..b28fa7c4 100644 --- a/gaia-rs/src/abci_handler.rs +++ b/gaia-rs/src/abci_handler.rs @@ -190,7 +190,7 @@ impl ABCIHandler for GaiaABCIHandler { ctx: &mut InitContext<'_, DB, GaiaStoreKey>, genesis: GenesisState, ) -> Vec { - self.bank_abci_handler.genesis(ctx, genesis.bank); + self.bank_abci_handler.init_genesis(ctx, genesis.bank); let staking_updates = self.staking_abci_handler.genesis(ctx, genesis.staking); self.ibc_abci_handler.genesis(ctx, genesis.ibc); self.auth_abci_handler.init_genesis(ctx, genesis.auth); From 936fe31d3d7bbbd38db62199c92a1fc4a6eb450e Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Wed, 2 Oct 2024 11:32:57 +0300 Subject: [PATCH 20/33] simple coins --- gears/src/types/base/coin/decimal.rs | 6 ++ gears/src/types/base/coin/unsigned.rs | 6 ++ gears/src/types/base/coins/mod.rs | 5 +- gears/src/types/base/coins/simple.rs | 128 ++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 gears/src/types/base/coins/simple.rs diff --git a/gears/src/types/base/coin/decimal.rs b/gears/src/types/base/coin/decimal.rs index 438dbf8a..54e979ce 100644 --- a/gears/src/types/base/coin/decimal.rs +++ b/gears/src/types/base/coin/decimal.rs @@ -121,3 +121,9 @@ impl FromStr for DecimalCoin { Ok(Self { denom, amount }) } } + +impl std::fmt::Display for DecimalCoin { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}{}", self.amount.to_string(), self.denom.to_string()) + } +} diff --git a/gears/src/types/base/coin/unsigned.rs b/gears/src/types/base/coin/unsigned.rs index d3c5a80d..055a50d6 100644 --- a/gears/src/types/base/coin/unsigned.rs +++ b/gears/src/types/base/coin/unsigned.rs @@ -122,3 +122,9 @@ impl PaginationKey for UnsignedCoin { Cow::Borrowed(self.denom.as_ref()) } } + +impl std::fmt::Display for UnsignedCoin { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}{}", self.amount.to_string(), self.denom.to_string()) + } +} diff --git a/gears/src/types/base/coins/mod.rs b/gears/src/types/base/coins/mod.rs index eff4479c..1421fb7c 100644 --- a/gears/src/types/base/coins/mod.rs +++ b/gears/src/types/base/coins/mod.rs @@ -1,9 +1,12 @@ use core_types::Protobuf; -pub use decimal::*; use prost::Message; + +pub use decimal::*; +pub use simple::*; pub use unsigned::*; mod decimal; +mod simple; mod unsigned; use std::{marker::PhantomData, str::FromStr}; diff --git a/gears/src/types/base/coins/simple.rs b/gears/src/types/base/coins/simple.rs new file mode 100644 index 00000000..ce3c1912 --- /dev/null +++ b/gears/src/types/base/coins/simple.rs @@ -0,0 +1,128 @@ +use crate::types::base::coin::{DecimalCoin, UnsignedCoin}; + +use super::*; + +pub type SimpleDecimalCoins = SimpleCoins; +pub type SimpleUnsignedCoins = SimpleCoins; + +#[derive(Debug, Clone)] +pub struct SimpleCoins(Vec); + +impl SimpleCoins { + pub fn new(coins: impl IntoIterator) -> Self { + Self(coins.into_iter().collect()) + } +} + +impl From> for SimpleCoins { + fn from(value: Vec) -> Self { + Self(value) + } +} + +impl From> for Vec { + fn from(value: SimpleCoins) -> Self { + value.0 + } +} + +impl> TryFrom> for Coins { + type Error = CoinsError; + + fn try_from(value: SimpleCoins) -> Result { + Self::new(value.0) + } +} + +impl std::fmt::Display for SimpleCoins { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let result = self + .0 + .iter() + .map(|this| this.to_string()) + .collect::>() + .join(","); + + write!(f, "{result}") + } +} + +#[cfg(test)] +mod tests { + use extensions::testing::UnwrapTesting; + + use super::*; + + // https://github.com/cosmos/cosmos-sdk/blob/d3f09c222243bb3da3464969f0366330dcb977a8/types/coin.go#L190-L205 + + #[test] + fn test_display_multiple_i32() { + let list = SimpleCoins::new([1, 2, 3]); + + assert_eq!("1,2,3", list.to_string()) + } + + #[test] + fn test_display_single_i32() { + let list = SimpleCoins::new([1]); + + assert_eq!("1", list.to_string()) + } + + #[test] + fn test_display_empty_i32() { + let list = SimpleCoins::::new([]); + + assert_eq!("", list.to_string()) + } + + #[test] + fn test_display_multiple_signed() { + let list = SimpleCoins::new([ + DecimalCoin::from_str("1uatom").unwrap_test(), + DecimalCoin::from_str("2uatom").unwrap_test(), + DecimalCoin::from_str("3uatom").unwrap_test(), + ]); + + assert_eq!("1uatom,2uatom,3uatom", list.to_string()) + } + + #[test] + fn test_display_single_signed() { + let list = SimpleCoins::new([DecimalCoin::from_str("1uatom").unwrap_test()]); + + assert_eq!("1uatom", list.to_string()) + } + + #[test] + fn test_display_empty_signed() { + let list = SimpleCoins::::new([]); + + assert_eq!("", list.to_string()) + } + + #[test] + fn test_display_multiple_unsigned() { + let list = SimpleCoins::new([ + UnsignedCoin::from_str("1uatom").unwrap_test(), + UnsignedCoin::from_str("2uatom").unwrap_test(), + UnsignedCoin::from_str("3uatom").unwrap_test(), + ]); + + assert_eq!("1uatom,2uatom,3uatom", list.to_string()) + } + + #[test] + fn test_display_single_unsigned() { + let list = SimpleCoins::new([UnsignedCoin::from_str("1uatom").unwrap_test()]); + + assert_eq!("1uatom", list.to_string()) + } + + #[test] + fn test_display_empty_unsigned() { + let list = SimpleCoins::::new([]); + + assert_eq!("", list.to_string()) + } +} From 60b640c6a3209b9a5c695ee71e9cf1d0cb5994ec Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Wed, 2 Oct 2024 11:40:01 +0300 Subject: [PATCH 21/33] correct serialization of coins for events --- gears/src/types/base/coins/simple.rs | 9 +++++++++ x/bank/src/keeper/bank.rs | 2 +- x/bank/src/keeper/mod.rs | 17 ++++------------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/gears/src/types/base/coins/simple.rs b/gears/src/types/base/coins/simple.rs index ce3c1912..596bd3d3 100644 --- a/gears/src/types/base/coins/simple.rs +++ b/gears/src/types/base/coins/simple.rs @@ -1,3 +1,5 @@ +use bytes::Bytes; + use crate::types::base::coin::{DecimalCoin, UnsignedCoin}; use super::*; @@ -5,6 +7,7 @@ use super::*; pub type SimpleDecimalCoins = SimpleCoins; pub type SimpleUnsignedCoins = SimpleCoins; +// TODO: Allow borrowed data #[derive(Debug, Clone)] pub struct SimpleCoins(Vec); @@ -14,6 +17,12 @@ impl SimpleCoins { } } +impl SimpleCoins { + pub fn to_string_bytes(&self) -> Bytes { + self.to_string().into_bytes().into() + } +} + impl From> for SimpleCoins { fn from(value: Vec) -> Self { Self(value) diff --git a/x/bank/src/keeper/bank.rs b/x/bank/src/keeper/bank.rs index 3a8261d5..c1e36425 100644 --- a/x/bank/src/keeper/bank.rs +++ b/x/bank/src/keeper/bank.rs @@ -88,7 +88,7 @@ impl< ), EventAttribute::new( "amount".as_bytes().to_owned().into(), - format!("{deposit:?}").into(), + SimpleCoins::new(deposit.inner()).to_string_bytes(), false, ), ], diff --git a/x/bank/src/keeper/mod.rs b/x/bank/src/keeper/mod.rs index c2240c7f..5a6809a1 100644 --- a/x/bank/src/keeper/mod.rs +++ b/x/bank/src/keeper/mod.rs @@ -14,7 +14,7 @@ use gears::store::StoreKey; use gears::tendermint::types::proto::event::{Event, EventAttribute}; use gears::types::address::AccAddress; use gears::types::base::coin::UnsignedCoin; -use gears::types::base::coins::UnsignedCoins; +use gears::types::base::coins::{SimpleCoins, UnsignedCoins}; use gears::types::denom::Denom; use gears::types::msg::send::MsgSend; use gears::types::store::gas::errors::GasStoreErrors; @@ -202,12 +202,9 @@ impl< String::from(address.clone()).into(), true, ), - // TODO: serialization of vector of coins EventAttribute::new( "amount".into(), - serde_json::to_string(&amount) - .unwrap_or(amount[0].amount.to_string()) - .into(), + SimpleCoins::new(amount).to_string_bytes(), true, ), ], @@ -492,12 +489,9 @@ impl< "coin_spent", [ EventAttribute::new("spender".into(), String::from(delegator_addr).into(), true), - // TODO: serialization of vector of coins EventAttribute::new( "amount".into(), - serde_json::to_string(&amount) - .unwrap_or(amount.inner()[0].amount.to_string()) - .into(), + SimpleCoins::new(amount.clone()).to_string_bytes(), true, ), ], @@ -573,12 +567,9 @@ impl< "coin_spent", [ EventAttribute::new("spender".into(), String::from(addr.clone()).into(), true), - // TODO: serialization of vector of coins EventAttribute::new( "amount".into(), - serde_json::to_string(&amount) - .unwrap_or(amount.inner()[0].amount.to_string()) - .into(), + SimpleCoins::new(amount.clone()).to_string_bytes(), true, ), ], From 8c4e9ed92613675003e4f14dcc550a0284f9cdc8 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Wed, 2 Oct 2024 12:16:02 +0300 Subject: [PATCH 22/33] refactor send_coins --- Makefile | 2 +- gaia-rs/tests/auth_query_accounts_base.rs | 5 +---- gaia-rs/tests/auth_query_accounts_module.rs | 5 +---- x/bank/src/keeper/mod.rs | 15 ++++++++------- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index bab9c65c..4990b0e6 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ run: cargo run -- run --min-gas-prices 0uatom test: - RUST_BACKTRACE=1 cargo test --features=macros_test,it --no-fail-fast + RUST_BACKTRACE=1 cargo test --features=it --no-fail-fast install: # "cargo install --path" ignores the lockfile, so we need to use "--locked" to ensure we use the same versions as in the lockfile diff --git a/gaia-rs/tests/auth_query_accounts_base.rs b/gaia-rs/tests/auth_query_accounts_base.rs index c0d5d2ea..abead10d 100644 --- a/gaia-rs/tests/auth_query_accounts_base.rs +++ b/gaia-rs/tests/auth_query_accounts_base.rs @@ -2,10 +2,7 @@ use auth::cli::query::{AccountsCommand, AuthCommands, AuthQueryCli, AuthQueryResponse}; use gaia_rs::{client::GaiaQueryCommands, query::GaiaQueryResponse}; -use gears::{ - cli::pagination::CliPaginationRequest, extensions::testing::UnwrapTesting, - types::account::Account, -}; +use gears::{extensions::testing::UnwrapTesting, types::account::Account}; use utilities::GaiaNode; #[path = "./utilities.rs"] diff --git a/gaia-rs/tests/auth_query_accounts_module.rs b/gaia-rs/tests/auth_query_accounts_module.rs index 5641e5f3..6968612d 100644 --- a/gaia-rs/tests/auth_query_accounts_module.rs +++ b/gaia-rs/tests/auth_query_accounts_module.rs @@ -2,10 +2,7 @@ use auth::cli::query::{AccountsCommand, AuthCommands, AuthQueryCli, AuthQueryResponse}; use gaia_rs::{client::GaiaQueryCommands, query::GaiaQueryResponse}; -use gears::{ - cli::pagination::CliPaginationRequest, extensions::testing::UnwrapTesting, - types::account::Account, -}; +use gears::{extensions::testing::UnwrapTesting, types::account::Account}; use utilities::GaiaNode; #[path = "./utilities.rs"] diff --git a/x/bank/src/keeper/mod.rs b/x/bank/src/keeper/mod.rs index 5a6809a1..967a7781 100644 --- a/x/bank/src/keeper/mod.rs +++ b/x/bank/src/keeper/mod.rs @@ -263,16 +263,15 @@ impl< fn send_coins>( &self, ctx: &mut CTX, - msg: MsgSend, + MsgSend { + from_address, + to_address, + amount, + }: MsgSend, ) -> Result<(), BankKeeperError> { - // TODO: refactor this to subtract all amounts before adding all amounts - let mut events = vec![]; - let from_address = msg.from_address; - let to_address = msg.to_address; - - for send_coin in msg.amount { + for send_coin in amount.inner() { let mut from_account_store = self.address_balances_store(ctx, &from_address); let from_balance = from_account_store .get(send_coin.denom.to_string().as_bytes())? @@ -304,7 +303,9 @@ impl< from_balance.encode_vec(), )?; } + } + for send_coin in amount.inner() { let mut to_account_store = self.address_balances_store(ctx, &to_address); let to_balance = to_account_store.get(send_coin.denom.to_string().as_bytes())?; From d71e7ec312aaf5d474314cad27cb045db111f58e Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Wed, 2 Oct 2024 12:54:14 +0300 Subject: [PATCH 23/33] init_genesis --- gears/src/types/base/coins/mod.rs | 2 +- x/bank/src/abci_handler.rs | 9 ++++++-- x/bank/src/keeper/mod.rs | 37 +++++++++++++++---------------- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/gears/src/types/base/coins/mod.rs b/gears/src/types/base/coins/mod.rs index 1421fb7c..3bc39d3a 100644 --- a/gears/src/types/base/coins/mod.rs +++ b/gears/src/types/base/coins/mod.rs @@ -100,7 +100,7 @@ impl> Coins { // denomination (i.e no duplicates). Otherwise, it returns an error. // A valid list of coins satisfies: // - Contains at least one coin - // - All amounts are positive + // - All amounts are positive(not zero) // - No duplicate denominations // - Sorted lexicographically pub fn new(coins: impl IntoIterator) -> Result { diff --git a/x/bank/src/abci_handler.rs b/x/bank/src/abci_handler.rs index 0b40d632..47b83bb3 100644 --- a/x/bank/src/abci_handler.rs +++ b/x/bank/src/abci_handler.rs @@ -153,9 +153,14 @@ impl< fn init_genesis( &self, ctx: &mut InitContext<'_, DB, Self::StoreKey>, - genesis: Self::Genesis, + Self::Genesis { + balances, + params, + denom_metadata, + }: Self::Genesis, ) -> Vec { - self.keeper.init_genesis(ctx, genesis); + self.keeper + .init_genesis(ctx, balances, params, denom_metadata); Vec::new() } diff --git a/x/bank/src/keeper/mod.rs b/x/bank/src/keeper/mod.rs index 967a7781..3727b606 100644 --- a/x/bank/src/keeper/mod.rs +++ b/x/bank/src/keeper/mod.rs @@ -1,4 +1,4 @@ -use crate::{BankParams, BankParamsKeeper, GenesisState}; +use crate::{Balance, BankParams, BankParamsKeeper}; use bytes::Bytes; use gears::application::keepers::params::ParamsKeeper; use gears::context::{init::InitContext, query::QueryContext}; @@ -92,16 +92,20 @@ impl< pub fn init_genesis( &self, ctx: &mut InitContext<'_, DB, SK>, - genesis: GenesisState, + mut balances: Vec, + params: BankParams, + denom_metadata: Vec, ) { - // TODO: - // 1. cosmos SDK sorts the balances first - // 2. Need to confirm that the SDK does not validate list of coins in each balance (validates order, denom etc.) - // 3. Need to set denom metadata - self.bank_params_keeper.set(ctx, genesis.params); + // 1. cosmos SDK sorts the balances first - Make sure that rust ordering gives same result + // 2. Need to confirm that the SDK does not validate list of coins in each balance (validates order, denom etc.) - Yes it does and our Coins type did it + // 3. Need to set denom metadata - dedicated cmd for it + self.bank_params_keeper.set(ctx, params); + + // Make sure that this 100% same as in cosmos(generally it should) + balances.sort_by_key(|this| this.address.clone()); let mut total_supply: HashMap = HashMap::new(); - for balance in genesis.balances { + for balance in balances { let prefix = create_denom_balance_prefix(balance.address); let mut denom_balance_store = ctx.kv_store_mut(&self.store_key).prefix_store_mut(prefix); @@ -114,19 +118,14 @@ impl< } } - // TODO: does the SDK sort these? - for coin in total_supply { - self.set_supply( - ctx, - UnsignedCoin { - denom: coin.0, - amount: coin.1, - }, - ) - .unwrap_gas(); + // does the SDK sort these? + // No. It uses ordering from balances https://github.com/cosmos/cosmos-sdk/blob/d3f09c222243bb3da3464969f0366330dcb977a8/x/bank/keeper/genesis.go#L32-L34 + for (denom, amount) in total_supply { + self.set_supply(ctx, UnsignedCoin { denom, amount }) + .unwrap_gas(); } - for denom_metadata in genesis.denom_metadata { + for denom_metadata in denom_metadata { self.set_denom_metadata(ctx, denom_metadata); } } From 2960fd6f20bbb012704e819e4098877a1ab768ff Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Wed, 2 Oct 2024 13:14:34 +0300 Subject: [PATCH 24/33] remove one todo --- x/bank/src/keeper/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/x/bank/src/keeper/mod.rs b/x/bank/src/keeper/mod.rs index 3727b606..ce3b237b 100644 --- a/x/bank/src/keeper/mod.rs +++ b/x/bank/src/keeper/mod.rs @@ -585,7 +585,6 @@ impl< &self, ctx: &CTX, addr: &AccAddress, - // TODO: consider to add struct Coins that can have empty coins list ) -> Result, BankKeeperError> { if let Some(_acc) = self.auth_keeper.get_account(ctx, addr)? { // vacc, ok := acc.(vestexported.VestingAccount) From f88ab30992fbec9a3faae7731a07ea3ac4e95d86 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Thu, 3 Oct 2024 09:13:07 +0300 Subject: [PATCH 25/33] use vec to preserve order --- x/bank/src/keeper/mod.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/x/bank/src/keeper/mod.rs b/x/bank/src/keeper/mod.rs index ce3b237b..5c009b2d 100644 --- a/x/bank/src/keeper/mod.rs +++ b/x/bank/src/keeper/mod.rs @@ -29,7 +29,7 @@ use gears::x::keepers::staking::StakingBankKeeper; use gears::x::module::Module; use std::marker::PhantomData; use std::ops::SubAssign; -use std::{collections::HashMap, str::FromStr}; +use std::str::FromStr; pub mod balances; pub mod bank; @@ -96,6 +96,7 @@ impl< params: BankParams, denom_metadata: Vec, ) { + // TODO // 1. cosmos SDK sorts the balances first - Make sure that rust ordering gives same result // 2. Need to confirm that the SDK does not validate list of coins in each balance (validates order, denom etc.) - Yes it does and our Coins type did it // 3. Need to set denom metadata - dedicated cmd for it @@ -104,7 +105,7 @@ impl< // Make sure that this 100% same as in cosmos(generally it should) balances.sort_by_key(|this| this.address.clone()); - let mut total_supply: HashMap = HashMap::new(); + let mut total_supply: Vec<(Denom, Uint256)> = Vec::with_capacity(balances.len()); for balance in balances { let prefix = create_denom_balance_prefix(balance.address); let mut denom_balance_store = @@ -113,8 +114,12 @@ impl< for coin in balance.coins { denom_balance_store.set(coin.denom.to_string().into_bytes(), coin.encode_vec()); let zero = Uint256::zero(); - let current_balance = total_supply.get(&coin.denom).unwrap_or(&zero); - total_supply.insert(coin.denom, coin.amount + current_balance); + let current_balance = total_supply + .iter() + .find(|(this, _)| this == &coin.denom) + .map(|(_, this)| this) + .unwrap_or(&zero); + total_supply.push((coin.denom, coin.amount + current_balance)); } } From 7494f2fc6943adbed14d9e0d2c5962650cc5e5d2 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Thu, 3 Oct 2024 11:03:14 +0300 Subject: [PATCH 26/33] revert usage of vec --- x/bank/src/keeper/mod.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/x/bank/src/keeper/mod.rs b/x/bank/src/keeper/mod.rs index 5c009b2d..ce3b237b 100644 --- a/x/bank/src/keeper/mod.rs +++ b/x/bank/src/keeper/mod.rs @@ -29,7 +29,7 @@ use gears::x::keepers::staking::StakingBankKeeper; use gears::x::module::Module; use std::marker::PhantomData; use std::ops::SubAssign; -use std::str::FromStr; +use std::{collections::HashMap, str::FromStr}; pub mod balances; pub mod bank; @@ -96,7 +96,6 @@ impl< params: BankParams, denom_metadata: Vec, ) { - // TODO // 1. cosmos SDK sorts the balances first - Make sure that rust ordering gives same result // 2. Need to confirm that the SDK does not validate list of coins in each balance (validates order, denom etc.) - Yes it does and our Coins type did it // 3. Need to set denom metadata - dedicated cmd for it @@ -105,7 +104,7 @@ impl< // Make sure that this 100% same as in cosmos(generally it should) balances.sort_by_key(|this| this.address.clone()); - let mut total_supply: Vec<(Denom, Uint256)> = Vec::with_capacity(balances.len()); + let mut total_supply: HashMap = HashMap::new(); for balance in balances { let prefix = create_denom_balance_prefix(balance.address); let mut denom_balance_store = @@ -114,12 +113,8 @@ impl< for coin in balance.coins { denom_balance_store.set(coin.denom.to_string().into_bytes(), coin.encode_vec()); let zero = Uint256::zero(); - let current_balance = total_supply - .iter() - .find(|(this, _)| this == &coin.denom) - .map(|(_, this)| this) - .unwrap_or(&zero); - total_supply.push((coin.denom, coin.amount + current_balance)); + let current_balance = total_supply.get(&coin.denom).unwrap_or(&zero); + total_supply.insert(coin.denom, coin.amount + current_balance); } } From 62ad1324342f2d7430141f3dbd3fcac488925624 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Thu, 3 Oct 2024 11:18:02 +0300 Subject: [PATCH 27/33] add todo --- x/bank/src/keeper/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/x/bank/src/keeper/mod.rs b/x/bank/src/keeper/mod.rs index ce3b237b..d7c29482 100644 --- a/x/bank/src/keeper/mod.rs +++ b/x/bank/src/keeper/mod.rs @@ -101,6 +101,7 @@ impl< // 3. Need to set denom metadata - dedicated cmd for it self.bank_params_keeper.set(ctx, params); + // TODO: This ordering is same as cosmos, but needs to add other constrains like `Coins` type, but with possible empty array // Make sure that this 100% same as in cosmos(generally it should) balances.sort_by_key(|this| this.address.clone()); From 65a7e98fa9b556961651df53adc003d7cdd4b650 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Thu, 3 Oct 2024 12:15:54 +0300 Subject: [PATCH 28/33] delete amount if zero --- x/bank/src/keeper/mod.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/x/bank/src/keeper/mod.rs b/x/bank/src/keeper/mod.rs index d7c29482..ecbf8305 100644 --- a/x/bank/src/keeper/mod.rs +++ b/x/bank/src/keeper/mod.rs @@ -359,10 +359,15 @@ impl< let bank_store = ctx.kv_store_mut(&self.store_key); let mut supply_store = bank_store.prefix_store_mut(SUPPLY_KEY); - supply_store.set( - coin.denom.to_string().into_bytes(), - coin.amount.to_string().into_bytes(), - ) + match coin.amount.is_zero() { + true => supply_store + .delete(coin.denom.to_string().as_bytes()) + .map(|_| ()), + false => supply_store.set( + coin.denom.to_string().into_bytes(), + coin.amount.to_string().into_bytes(), + ), + } } pub fn supply>( From c2861bff6ec46f08e9c308c8b03bb953deab22bd Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Thu, 3 Oct 2024 12:22:26 +0300 Subject: [PATCH 29/33] place todo --- x/bank/src/keeper/bank.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/x/bank/src/keeper/bank.rs b/x/bank/src/keeper/bank.rs index c1e36425..51fd332e 100644 --- a/x/bank/src/keeper/bank.rs +++ b/x/bank/src/keeper/bank.rs @@ -73,6 +73,7 @@ impl< // If no value found then new coin with zero balance, subtraction and call of set_supply which deletes coins with zero balance // We omitted it but if any issue arise be aware that maybe we should delete zero coins if we store any. if let Some(mut supply) = supply { + // TODO: overflow https://github.com/rumos-io/gears/issues/14 supply.amount.sub_assign(coin.amount); self.set_supply(ctx, supply)?; } From a5bf9a179fb6d3ec7bb8ce408a838b5181d67912 Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Thu, 3 Oct 2024 12:26:46 +0300 Subject: [PATCH 30/33] remove doc line --- gears/src/x/keepers/staking.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gears/src/x/keepers/staking.rs b/gears/src/x/keepers/staking.rs index 60633a5e..c164f60d 100644 --- a/gears/src/x/keepers/staking.rs +++ b/gears/src/x/keepers/staking.rs @@ -229,8 +229,7 @@ pub trait StakingBankKeeper: ) -> Result<(), BankKeeperError>; /// Method undelegates the unbonding coins and transfers - /// them from a module account to the delegator account. It will panic if the - /// module account does not exist or is unauthorized. + /// them from a module account to the delegator account. fn undelegate_coins_from_module_to_account>( &self, ctx: &mut CTX, From a95619e79af75c10cd50c439136c9e2a5ce8c9ae Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Thu, 3 Oct 2024 12:29:18 +0300 Subject: [PATCH 31/33] remove comment --- x/bank/src/keeper/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/x/bank/src/keeper/mod.rs b/x/bank/src/keeper/mod.rs index ecbf8305..20ff4550 100644 --- a/x/bank/src/keeper/mod.rs +++ b/x/bank/src/keeper/mod.rs @@ -354,8 +354,6 @@ impl< ctx: &mut CTX, coin: UnsignedCoin, ) -> Result<(), GasStoreErrors> { - // If there will be any issue with bank then delete coins with zero balance. See for more details: https://github.com/NYBACHOK/gears/blob/c79c50f60e40cee3fbc050002bf1ce63a72b67a3/x/bank/src/keeper/bank.rs#L70-L72 - let bank_store = ctx.kv_store_mut(&self.store_key); let mut supply_store = bank_store.prefix_store_mut(SUPPLY_KEY); From 3c116257c1fa12e196fbd2ef1587ca54ba2a0b5a Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Thu, 3 Oct 2024 12:31:28 +0300 Subject: [PATCH 32/33] edit comment --- x/bank/src/keeper/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/bank/src/keeper/mod.rs b/x/bank/src/keeper/mod.rs index 20ff4550..09e68db2 100644 --- a/x/bank/src/keeper/mod.rs +++ b/x/bank/src/keeper/mod.rs @@ -102,7 +102,7 @@ impl< self.bank_params_keeper.set(ctx, params); // TODO: This ordering is same as cosmos, but needs to add other constrains like `Coins` type, but with possible empty array - // Make sure that this 100% same as in cosmos(generally it should) + // TODO: check how it orders if balances are same balances.sort_by_key(|this| this.address.clone()); let mut total_supply: HashMap = HashMap::new(); From c3e3bf41fcc4331726bbfec221ac47fa0b59301d Mon Sep 17 00:00:00 2001 From: NYBACHOK Date: Thu, 3 Oct 2024 14:26:52 +0300 Subject: [PATCH 33/33] move genesis path to app layer --- gaia-rs/src/lib.rs | 4 +++- x/bank/src/aux/metadata.rs | 7 ++++--- x/bank/src/aux/mod.rs | 11 +++++++++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/gaia-rs/src/lib.rs b/gaia-rs/src/lib.rs index 581db2bf..a33dad0c 100644 --- a/gaia-rs/src/lib.rs +++ b/gaia-rs/src/lib.rs @@ -156,7 +156,9 @@ impl AuxHandler for GaiaCore { genutil::gentx::gentx_cmd(cmd, "bank", "staking", &EmptyNodeFetcher)?; } }, - GaiaAuxCmd::Bank(cmd) => bank::aux::handle_aux_cmd(cmd)?, + GaiaAuxCmd::Bank(cmd) => { + bank::aux::handle_aux_cmd(cmd, "/app_state/bank/denom_metadata")? + } } Ok(NilAux) diff --git a/x/bank/src/aux/metadata.rs b/x/bank/src/aux/metadata.rs index c8b9f177..e6a59403 100644 --- a/x/bank/src/aux/metadata.rs +++ b/x/bank/src/aux/metadata.rs @@ -20,6 +20,7 @@ pub fn add_coins_meta_to_genesis( dedup_input: bool, overwrite_dup: bool, dry: bool, + in_genesis_path: &str, ) -> anyhow::Result<()> { let metadata = { let mut metadata = metadata.into_iter().collect::>(); @@ -39,9 +40,9 @@ pub fn add_coins_meta_to_genesis( let mut genesis = serde_json::from_slice::(&std::fs::read(&genesis_path)?)?; let value = genesis - .pointer_mut("/app_state/bank/denom_metadata") + .pointer_mut(in_genesis_path) .ok_or(anyhow::anyhow!( - "`/app_state/bank/denom_metadata` not found. Check is genesis file is valid" + "`{in_genesis_path} not found. Check is genesis file is valid" ))? .take(); @@ -74,7 +75,7 @@ pub fn add_coins_meta_to_genesis( if !dry { *genesis - .pointer_mut("/app_state/bank/denom_metadata") + .pointer_mut(in_genesis_path) .expect("we checked that this exists") = serde_json::to_value( original_meta .into_iter() diff --git a/x/bank/src/aux/mod.rs b/x/bank/src/aux/mod.rs index 46a9ad92..d0d47030 100644 --- a/x/bank/src/aux/mod.rs +++ b/x/bank/src/aux/mod.rs @@ -10,7 +10,7 @@ pub enum BankAuxCmd { Genesis(CoinsMetaGenesisCmd), } -pub fn handle_aux_cmd(cmd: BankAuxCmd) -> anyhow::Result<()> { +pub fn handle_aux_cmd(cmd: BankAuxCmd, in_genesis_path: &str) -> anyhow::Result<()> { match cmd { BankAuxCmd::Genesis(CoinsMetaGenesisCmd { home, @@ -30,7 +30,14 @@ pub fn handle_aux_cmd(cmd: BankAuxCmd) -> anyhow::Result<()> { }, }; - metadata::add_coins_meta_to_genesis(home, metadata, dedup_input, overwrite_dup, dry) + metadata::add_coins_meta_to_genesis( + home, + metadata, + dedup_input, + overwrite_dup, + dry, + in_genesis_path, + ) } } }