github.com/Finschia/finschia-sdk@v0.48.1/x/bankplus/keeper/keeper_test.go (about) 1 package keeper_test 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/suite" 7 tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 8 9 "github.com/Finschia/finschia-sdk/simapp" 10 sdk "github.com/Finschia/finschia-sdk/types" 11 sdkerrors "github.com/Finschia/finschia-sdk/types/errors" 12 authkeeper "github.com/Finschia/finschia-sdk/x/auth/keeper" 13 authtypes "github.com/Finschia/finschia-sdk/x/auth/types" 14 "github.com/Finschia/finschia-sdk/x/bank/types" 15 bankpluskeeper "github.com/Finschia/finschia-sdk/x/bankplus/keeper" 16 minttypes "github.com/Finschia/finschia-sdk/x/mint/types" 17 ) 18 19 const ( 20 initialPower = int64(100) 21 holder = "holder" 22 blocker = "blocker" 23 ) 24 25 var ( 26 holderAcc = authtypes.NewEmptyModuleAccount(holder) 27 blockedAcc = authtypes.NewEmptyModuleAccount(blocker) 28 burnerAcc = authtypes.NewEmptyModuleAccount(authtypes.Burner, authtypes.Burner) 29 30 initTokens = sdk.TokensFromConsensusPower(initialPower, sdk.DefaultPowerReduction) 31 initCoins = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens)) 32 ) 33 34 // nolint: interfacer 35 func getCoinsByName(ctx sdk.Context, bk bankpluskeeper.Keeper, ak types.AccountKeeper, moduleName string) sdk.Coins { 36 moduleAddress := ak.GetModuleAddress(moduleName) 37 macc := ak.GetAccount(ctx, moduleAddress) 38 if macc == nil { 39 return sdk.NewCoins() 40 } 41 42 return bk.GetAllBalances(ctx, macc.GetAddress()) 43 } 44 45 type IntegrationTestSuite struct { 46 suite.Suite 47 } 48 49 func (suite *IntegrationTestSuite) TestSupply_SendCoins() { 50 app := simapp.Setup(false) 51 ctx := app.BaseApp.NewContext(false, tmproto.Header{Height: 1}) 52 appCodec := app.AppCodec() 53 54 // add module accounts to supply keeper 55 maccPerms := simapp.GetMaccPerms() 56 maccPerms[holder] = nil 57 maccPerms[authtypes.Burner] = []string{authtypes.Burner} 58 maccPerms[authtypes.Minter] = []string{authtypes.Minter} 59 60 authKeeper := authkeeper.NewAccountKeeper( 61 appCodec, app.GetKey(types.StoreKey), app.GetSubspace(types.ModuleName), 62 authtypes.ProtoBaseAccount, maccPerms, 63 ) 64 keeper := bankpluskeeper.NewBaseKeeper( 65 appCodec, app.GetKey(types.StoreKey), authKeeper, 66 app.GetSubspace(types.ModuleName), make(map[string]bool), false, 67 ) 68 69 baseAcc := authKeeper.NewAccountWithAddress(ctx, authtypes.NewModuleAddress("baseAcc")) 70 71 // set initial balances 72 suite. 73 Require(). 74 NoError(keeper.MintCoins(ctx, minttypes.ModuleName, initCoins)) 75 76 suite. 77 Require(). 78 NoError(keeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, holderAcc.GetAddress(), initCoins)) 79 80 suite.Require().NoError(keeper.MintCoins(ctx, minttypes.ModuleName, initCoins)) 81 authKeeper.SetModuleAccount(ctx, holderAcc) 82 authKeeper.SetModuleAccount(ctx, burnerAcc) 83 authKeeper.SetAccount(ctx, baseAcc) 84 85 suite.Require().Panics(func() { 86 keeper.SendCoinsFromModuleToModule(ctx, "", holderAcc.GetName(), initCoins) // nolint:errcheck 87 }) 88 89 suite.Require().Panics(func() { 90 keeper.SendCoinsFromModuleToModule(ctx, authtypes.Burner, "", initCoins) // nolint:errcheck 91 }) 92 93 suite.Require().Panics(func() { 94 keeper.SendCoinsFromModuleToAccount(ctx, "", baseAcc.GetAddress(), initCoins) // nolint:errcheck 95 }) 96 97 // not enough balance (100stake - 200stake) 98 suite.Require().Error( 99 keeper.SendCoinsFromModuleToAccount(ctx, holderAcc.GetName(), baseAcc.GetAddress(), initCoins.Add(initCoins...)), 100 ) 101 102 suite.Require().NoError( 103 keeper.SendCoinsFromModuleToModule(ctx, holderAcc.GetName(), authtypes.Burner, initCoins), 104 ) 105 suite.Require().Equal(sdk.NewCoins().String(), getCoinsByName(ctx, keeper, authKeeper, holderAcc.GetName()).String()) 106 suite.Require().Equal(initCoins, getCoinsByName(ctx, keeper, authKeeper, authtypes.Burner)) 107 108 suite.Require().NoError( 109 keeper.SendCoinsFromModuleToAccount(ctx, authtypes.Burner, baseAcc.GetAddress(), initCoins), 110 ) 111 suite.Require().Equal(sdk.NewCoins().String(), getCoinsByName(ctx, keeper, authKeeper, authtypes.Burner).String()) 112 suite.Require().Equal(initCoins, keeper.GetAllBalances(ctx, baseAcc.GetAddress())) 113 114 suite.Require().NoError(keeper.SendCoinsFromAccountToModule(ctx, baseAcc.GetAddress(), authtypes.Burner, initCoins)) 115 suite.Require().Equal(sdk.NewCoins().String(), keeper.GetAllBalances(ctx, baseAcc.GetAddress()).String()) 116 suite.Require().Equal(initCoins, getCoinsByName(ctx, keeper, authKeeper, authtypes.Burner)) 117 } 118 119 func (suite *IntegrationTestSuite) TestInactiveAddrOfSendCoins() { 120 app := simapp.Setup(false) 121 ctx := app.BaseApp.NewContext(false, tmproto.Header{Height: 1}) 122 appCodec := app.AppCodec() 123 124 // add module accounts to supply keeper 125 maccPerms := simapp.GetMaccPerms() 126 maccPerms[holder] = nil 127 maccPerms[authtypes.Burner] = []string{authtypes.Burner} 128 maccPerms[authtypes.Minter] = []string{authtypes.Minter} 129 130 authKeeper := authkeeper.NewAccountKeeper( 131 appCodec, app.GetKey(types.StoreKey), app.GetSubspace(types.ModuleName), 132 authtypes.ProtoBaseAccount, maccPerms, 133 ) 134 135 keeper := bankpluskeeper.NewBaseKeeper( 136 appCodec, app.GetKey(types.StoreKey), authKeeper, 137 app.GetSubspace(types.ModuleName), make(map[string]bool), false, 138 ) 139 140 // set initial balances 141 suite. 142 Require(). 143 NoError(keeper.MintCoins(ctx, minttypes.ModuleName, initCoins)) 144 145 suite. 146 Require(). 147 NoError(keeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, holderAcc.GetAddress(), initCoins)) 148 149 suite.Require().NoError(keeper.MintCoins(ctx, minttypes.ModuleName, initCoins)) 150 suite.Require().Equal(initCoins, keeper.GetAllBalances(ctx, holderAcc.GetAddress())) 151 152 suite.Require().False(keeper.IsInactiveAddr(blockedAcc.GetAddress())) 153 154 // add blocked address 155 keeper.AddToInactiveAddr(ctx, blockedAcc.GetAddress()) 156 suite.Require().True(keeper.IsInactiveAddr(blockedAcc.GetAddress())) 157 158 err := keeper.SendCoins(ctx, holderAcc.GetAddress(), blockedAcc.GetAddress(), initCoins) 159 suite.Require().Contains(err.Error(), "is not allowed to receive funds") 160 suite.Require().Equal(initCoins, keeper.GetAllBalances(ctx, holderAcc.GetAddress())) 161 162 // delete blocked address 163 keeper.DeleteFromInactiveAddr(ctx, blockedAcc.GetAddress()) 164 suite.Require().False(keeper.IsInactiveAddr(blockedAcc.GetAddress())) 165 166 suite.Require().NoError(keeper.SendCoins(ctx, holderAcc.GetAddress(), blockedAcc.GetAddress(), initCoins)) 167 suite.Require().Equal(sdk.NewCoins().String(), keeper.GetAllBalances(ctx, holderAcc.GetAddress()).String()) 168 } 169 170 func (suite *IntegrationTestSuite) TestInitializeBankPlus() { 171 app := simapp.Setup(false) 172 ctx := app.BaseApp.NewContext(false, tmproto.Header{Height: 1}) 173 appCodec := app.AppCodec() 174 175 // add module accounts to supply keeper 176 maccPerms := simapp.GetMaccPerms() 177 maccPerms[holder] = nil 178 maccPerms[authtypes.Burner] = []string{authtypes.Burner} 179 maccPerms[authtypes.Minter] = []string{authtypes.Minter} 180 181 authKeeper := authkeeper.NewAccountKeeper( 182 appCodec, app.GetKey(types.StoreKey), app.GetSubspace(types.ModuleName), 183 authtypes.ProtoBaseAccount, maccPerms, 184 ) 185 186 { 187 keeper := bankpluskeeper.NewBaseKeeper( 188 appCodec, app.GetKey(types.StoreKey), authKeeper, 189 app.GetSubspace(types.ModuleName), make(map[string]bool), false, 190 ) 191 192 // add blocked address 193 keeper.AddToInactiveAddr(ctx, blockedAcc.GetAddress()) 194 suite.Require().True(keeper.IsInactiveAddr(blockedAcc.GetAddress())) 195 } 196 197 { 198 keeper := bankpluskeeper.NewBaseKeeper( 199 appCodec, app.GetKey(types.StoreKey), authKeeper, 200 app.GetSubspace(types.ModuleName), make(map[string]bool), false, 201 ) 202 keeper.InitializeBankPlus(ctx) 203 suite.Require().True(keeper.IsInactiveAddr(blockedAcc.GetAddress())) 204 } 205 } 206 207 func (suite *IntegrationTestSuite) TestSendCoinsFromModuleToAccount_Blacklist() { 208 app := simapp.Setup(false) 209 ctx := app.BaseApp.NewContext(false, tmproto.Header{Height: 1}) 210 appCodec := app.AppCodec() 211 212 // add module accounts to supply keeper 213 maccPerms := simapp.GetMaccPerms() 214 maccPerms[holder] = nil 215 maccPerms[authtypes.Burner] = []string{authtypes.Burner} 216 maccPerms[authtypes.Minter] = []string{authtypes.Minter} 217 218 addr1 := sdk.AccAddress([]byte("addr1_______________")) 219 220 authKeeper := authkeeper.NewAccountKeeper( 221 appCodec, app.GetKey(types.StoreKey), app.GetSubspace(types.ModuleName), 222 authtypes.ProtoBaseAccount, maccPerms, 223 ) 224 keeper := bankpluskeeper.NewBaseKeeper( 225 appCodec, app.GetKey(types.StoreKey), authKeeper, 226 app.GetSubspace(types.ModuleName), map[string]bool{addr1.String(): true}, false) 227 228 suite.Require().NoError(keeper.MintCoins(ctx, minttypes.ModuleName, initCoins)) 229 suite.Require().Error(keeper.SendCoinsFromModuleToAccount( 230 ctx, minttypes.ModuleName, addr1, initCoins, 231 )) 232 } 233 234 func (suite *IntegrationTestSuite) TestInputOutputCoins() { 235 app := simapp.Setup(false) 236 ctx := app.BaseApp.NewContext(false, tmproto.Header{Height: 1}) 237 appCodec := app.AppCodec() 238 239 // add module accounts to supply keeper 240 maccPerms := simapp.GetMaccPerms() 241 maccPerms[holder] = nil 242 maccPerms[authtypes.Burner] = []string{authtypes.Burner} 243 maccPerms[authtypes.Minter] = []string{authtypes.Minter} 244 245 authKeeper := authkeeper.NewAccountKeeper( 246 appCodec, app.GetKey(types.StoreKey), app.GetSubspace(types.ModuleName), 247 authtypes.ProtoBaseAccount, maccPerms, 248 ) 249 keeper := bankpluskeeper.NewBaseKeeper( 250 appCodec, app.GetKey(types.StoreKey), authKeeper, 251 app.GetSubspace(types.ModuleName), make(map[string]bool), false, 252 ) 253 254 baseAcc := authKeeper.NewAccountWithAddress(ctx, authtypes.NewModuleAddress("baseAcc")) 255 authKeeper.SetModuleAccount(ctx, holderAcc) 256 authKeeper.SetModuleAccount(ctx, burnerAcc) 257 authKeeper.SetAccount(ctx, baseAcc) 258 259 // set initial balances 260 suite. 261 Require(). 262 NoError(keeper.MintCoins(ctx, minttypes.ModuleName, initCoins)) 263 suite. 264 Require(). 265 NoError(keeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, baseAcc.GetAddress(), initCoins)) 266 suite. 267 Require(). 268 NoError(keeper.MintCoins(ctx, minttypes.ModuleName, initCoins)) 269 suite. 270 Require(). 271 NoError(keeper.SendCoinsFromModuleToModule(ctx, minttypes.ModuleName, holderAcc.GetName(), initCoins)) 272 273 input := []types.Input{types.NewInput(baseAcc.GetAddress(), initCoins), types.NewInput(holderAcc.GetAddress(), initCoins)} 274 output := []types.Output{types.NewOutput(burnerAcc.GetAddress(), initCoins), types.NewOutput(burnerAcc.GetAddress(), initCoins)} 275 276 targetKeeper := func(isDeact bool) bankpluskeeper.BaseKeeper { 277 return bankpluskeeper.NewBaseKeeper( 278 appCodec, app.GetKey(types.StoreKey), authKeeper, 279 app.GetSubspace(types.ModuleName), make(map[string]bool), isDeact, 280 ) 281 } 282 tcs := map[string]struct { 283 deactMultiSend bool 284 err error 285 }{ 286 "MultiSend Off": { 287 true, 288 sdkerrors.ErrNotSupported.Wrap("MultiSend was deactivated"), 289 }, 290 "MultiSend On": { 291 false, 292 nil, 293 }, 294 } 295 296 for name, tc := range tcs { 297 tc := tc 298 suite.T().Run(name, func(t *testing.T) { 299 if tc.err != nil { 300 suite.EqualError(targetKeeper(tc.deactMultiSend).InputOutputCoins(ctx, input, output), tc.err.Error()) 301 } else { 302 err := targetKeeper(tc.deactMultiSend).InputOutputCoins(ctx, input, output) 303 suite.Assert().NoError(err) 304 } 305 }) 306 } 307 } 308 309 func TestKeeperTestSuite(t *testing.T) { 310 suite.Run(t, new(IntegrationTestSuite)) 311 }