github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/staking/keeper/test_common.go (about) 1 package keeper 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "fmt" 7 "strconv" 8 "testing" 9 "time" 10 11 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/mpt" 12 13 types2 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec/types" 14 15 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/exported" 16 17 "github.com/fibonacci-chain/fbc/x/staking/types" 18 "github.com/stretchr/testify/require" 19 20 abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types" 21 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto" 22 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/ed25519" 23 "github.com/fibonacci-chain/fbc/libs/tendermint/libs/log" 24 tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types" 25 dbm "github.com/fibonacci-chain/fbc/libs/tm-db" 26 27 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec" 28 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store" 29 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 30 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth" 31 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank" 32 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/supply" 33 "github.com/fibonacci-chain/fbc/x/params" 34 //distr "github.com/fibonacci-chain/fbc/x/distribution" 35 ) 36 37 // dummy addresses used for testing 38 // nolint: unused deadcode 39 var ( 40 Addrs = createTestAddrs(500) 41 PKs = createTestPubKeys(500) 42 43 addrDels = []sdk.AccAddress{ 44 Addrs[0], 45 Addrs[1], 46 Addrs[2], 47 } 48 49 addrVals = []sdk.ValAddress{ 50 sdk.ValAddress(Addrs[3]), 51 sdk.ValAddress(Addrs[4]), 52 sdk.ValAddress(Addrs[5]), 53 sdk.ValAddress(Addrs[6]), 54 sdk.ValAddress(Addrs[7]), 55 } 56 57 SufficientInitBalance = int64(10000) 58 InitMsd2000 = sdk.NewDec(2000) 59 TestChainID = "stkchainid" 60 ) 61 62 type MockStakingKeeper struct { 63 Keeper 64 StoreKey sdk.StoreKey 65 TkeyStoreKey sdk.StoreKey 66 SupplyKeeper supply.Keeper 67 MountedStore store.MultiStore 68 AccKeeper auth.AccountKeeper 69 } 70 71 func NewMockStakingKeeper(k Keeper, keyStoreKey, tkeyStoreKey sdk.StoreKey, sKeeper supply.Keeper, 72 ms store.MultiStore, accKeeper auth.AccountKeeper) MockStakingKeeper { 73 return MockStakingKeeper{ 74 k, 75 keyStoreKey, 76 tkeyStoreKey, 77 sKeeper, 78 ms, 79 accKeeper, 80 } 81 } 82 83 //_______________________________________________________________________________________ 84 85 // MakeTestCodec creates a codec used only for testing 86 func MakeTestCodec() *codec.Codec { 87 var cdc = codec.New() 88 89 // Register Msgs 90 cdc.RegisterInterface((*sdk.Msg)(nil), nil) 91 cdc.RegisterConcrete(bank.MsgSend{}, "test/staking/Send", nil) 92 cdc.RegisterConcrete(types.MsgCreateValidator{}, "test/staking/CreateValidator", nil) 93 cdc.RegisterConcrete(types.MsgDestroyValidator{}, "test/staking/DestroyValidator", nil) 94 cdc.RegisterConcrete(types.MsgEditValidator{}, "test/staking/EditValidator", nil) 95 cdc.RegisterConcrete(types.MsgWithdraw{}, "test/staking/MsgWithdraw", nil) 96 cdc.RegisterConcrete(types.MsgAddShares{}, "test/staking/MsgAddShares", nil) 97 98 // Register AppAccount 99 cdc.RegisterInterface((*exported.Account)(nil), nil) 100 cdc.RegisterConcrete(&auth.BaseAccount{}, "test/staking/BaseAccount", nil) 101 supply.RegisterCodec(cdc) 102 codec.RegisterCrypto(cdc) 103 104 return cdc 105 } 106 107 // CreateTestInput returns all sorts of input required for testing 108 // initBalance is converted to an amount of tokens. 109 func CreateTestInput(t *testing.T, isCheckTx bool, initBalance int64) (sdk.Context, auth.AccountKeeper, MockStakingKeeper) { 110 111 // init storage 112 keyStaking := sdk.NewKVStoreKey(types.StoreKey) 113 tkeyStaking := sdk.NewTransientStoreKey(types.TStoreKey) 114 keyAcc := sdk.NewKVStoreKey(auth.StoreKey) 115 keyMpt := sdk.NewKVStoreKey(mpt.StoreKey) 116 keyParams := sdk.NewKVStoreKey(params.StoreKey) 117 tkeyParams := sdk.NewTransientStoreKey(params.TStoreKey) 118 keySupply := sdk.NewKVStoreKey(supply.StoreKey) 119 120 db := dbm.NewMemDB() 121 ms := store.NewCommitMultiStore(db) 122 ms.MountStoreWithDB(tkeyStaking, sdk.StoreTypeTransient, nil) 123 ms.MountStoreWithDB(keyStaking, sdk.StoreTypeIAVL, db) 124 ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db) 125 ms.MountStoreWithDB(keyMpt, sdk.StoreTypeMPT, db) 126 ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db) 127 ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db) 128 ms.MountStoreWithDB(keySupply, sdk.StoreTypeIAVL, db) 129 err := ms.LoadLatestVersion() 130 require.Nil(t, err) 131 132 // init context 133 ctx := sdk.NewContext(ms, abci.Header{ChainID: TestChainID}, isCheckTx, log.NewNopLogger()) 134 ctx.SetConsensusParams( 135 &abci.ConsensusParams{ 136 Validator: &abci.ValidatorParams{ 137 PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeEd25519}, 138 }, 139 }, 140 ) 141 ctx.SetBlockTime(time.Now()) 142 cdc := MakeTestCodec() 143 reg := types2.NewInterfaceRegistry() 144 cc := codec.NewProtoCodec(reg) 145 pro := codec.NewCodecProxy(cc, cdc) 146 147 feeCollectorAcc := supply.NewEmptyModuleAccount(auth.FeeCollectorName) 148 notBondedPool := supply.NewEmptyModuleAccount(types.NotBondedPoolName, supply.Burner, supply.Staking) 149 bondPool := supply.NewEmptyModuleAccount(types.BondedPoolName, supply.Burner, supply.Staking) 150 151 blacklistedAddrs := make(map[string]bool) 152 blacklistedAddrs[feeCollectorAcc.String()] = true 153 blacklistedAddrs[notBondedPool.String()] = true 154 blacklistedAddrs[bondPool.String()] = true 155 156 // init module keepers 157 pk := params.NewKeeper(cdc, keyParams, tkeyParams, log.NewNopLogger()) 158 159 accountKeeper := auth.NewAccountKeeper( 160 cdc, // amino codec 161 keyAcc, // target store 162 keyMpt, 163 pk.Subspace(auth.DefaultParamspace), 164 auth.ProtoBaseAccount, // prototype 165 ) 166 167 bk := bank.NewBaseKeeper( 168 accountKeeper, 169 pk.Subspace(bank.DefaultParamspace), 170 blacklistedAddrs, 171 ) 172 173 maccPerms := map[string][]string{ 174 auth.FeeCollectorName: nil, 175 types.NotBondedPoolName: {supply.Burner, supply.Staking}, 176 types.BondedPoolName: {supply.Burner, supply.Staking}, 177 } 178 supplyKeeper := supply.NewKeeper(cdc, keySupply, accountKeeper, bank.NewBankKeeperAdapter(bk), maccPerms) 179 180 initTokens := sdk.NewInt(initBalance) 181 initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens)) 182 totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens.MulRaw(int64(len(Addrs))))) 183 184 supplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply)) 185 186 keeper := NewKeeper(pro, keyStaking, supplyKeeper, pk.Subspace(DefaultParamspace)) 187 keeper.SetParams(ctx, types.DefaultParams()) 188 189 // set module accounts 190 supplyKeeper.SetModuleAccount(ctx, feeCollectorAcc) 191 supplyKeeper.SetModuleAccount(ctx, bondPool) 192 193 // fill all the addresses with some coins, set the loose pool tokens simultaneously 194 for _, addr := range Addrs { 195 _, err := bk.AddCoins(ctx, addr, initCoins) 196 if err != nil { 197 panic(err) 198 } 199 } 200 201 distrKeeper := mockDistributionKeeper{} 202 hooks := types.NewMultiStakingHooks(distrKeeper.Hooks()) 203 keeper.SetHooks(hooks) 204 205 mockKeeper := NewMockStakingKeeper(keeper, keyStaking, tkeyStaking, 206 supplyKeeper, ms, accountKeeper) 207 208 return ctx, accountKeeper, mockKeeper 209 } 210 211 func NewPubKey(pk string) (res crypto.PubKey) { 212 pkBytes, err := hex.DecodeString(pk) 213 if err != nil { 214 panic(err) 215 } 216 //res, err = crypto.PubKeyFromBytes(pkBytes) 217 var pkEd ed25519.PubKeyEd25519 218 copy(pkEd[:], pkBytes[:]) 219 return pkEd 220 } 221 222 // TestAddr is designed for incode address generation 223 func TestAddr(addr string, bech string) sdk.AccAddress { 224 225 res, err := sdk.AccAddressFromHex(addr) 226 if err != nil { 227 panic(err) 228 } 229 bechexpected := res.String() 230 if bech != bechexpected { 231 panic("Bech encoding doesn't match reference") 232 } 233 234 bechres, err := sdk.AccAddressFromBech32(bech) 235 if err != nil { 236 panic(err) 237 } 238 if !bytes.Equal(bechres, res) { 239 panic("Bech decode and hex decode don't match") 240 } 241 242 return res 243 } 244 245 func createTestAddrs(numAddrs int) []sdk.AccAddress { 246 var addresses []sdk.AccAddress 247 var buffer bytes.Buffer 248 249 // start at 100 so we can make up to 999 test addresses with valid test addresses 250 for i := 100; i < (numAddrs + 100); i++ { 251 numString := strconv.Itoa(i) 252 buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") //base address string 253 254 buffer.WriteString(numString) //adding on final two digits to make addresses unique 255 res, err := sdk.AccAddressFromHex(buffer.String()) 256 if err != nil { 257 fmt.Print("error") 258 } 259 bech := res.String() 260 addresses = append(addresses, TestAddr(buffer.String(), bech)) 261 buffer.Reset() 262 } 263 return addresses 264 } 265 266 // nolint: unparam 267 func createTestPubKeys(numPubKeys int) []crypto.PubKey { 268 var publicKeys []crypto.PubKey 269 var buffer bytes.Buffer 270 271 //start at 10 to avoid changing 1 to 01, 2 to 02, etc 272 for i := 100; i < (numPubKeys + 100); i++ { 273 numString := strconv.Itoa(i) 274 buffer.WriteString("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AF") //base pubkey string 275 buffer.WriteString(numString) //adding on final two digits to make pubkeys unique 276 publicKeys = append(publicKeys, NewPubKey(buffer.String())) 277 buffer.Reset() 278 } 279 return publicKeys 280 } 281 282 //_____________________________________________________________________________________ 283 284 // ValidatorByPowerIndexExists checks whether a certain by-power index record exist 285 func ValidatorByPowerIndexExists(ctx sdk.Context, keeper MockStakingKeeper, power []byte) bool { 286 store := ctx.KVStore(keeper.StoreKey) 287 return store.Has(power) 288 } 289 290 func NewTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, msdAmt sdk.Dec) types.MsgCreateValidator { 291 msd := sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, msdAmt) 292 293 return types.NewMsgCreateValidator(address, pubKey, 294 types.NewDescription("my moniker", "my identity", "my website", "my details"), msd, 295 ) 296 } 297 298 func NewTestMsgDeposit(delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt sdk.Dec) types.MsgDeposit { 299 amount := sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, amt) 300 return types.NewMsgDeposit(delAddr, amount) 301 } 302 303 func SimpleCheckValidator(t *testing.T, ctx sdk.Context, stkKeeper Keeper, vaAddr sdk.ValAddress, 304 expMsd sdk.Dec, expStatus sdk.BondStatus, expDlgShares sdk.Dec, expJailed bool) *types.Validator { 305 val, ok := stkKeeper.GetValidator(ctx, vaAddr) 306 require.True(t, ok) 307 require.True(t, val.GetMinSelfDelegation().Equal(expMsd), val.MinSelfDelegation.String(), expMsd.String()) 308 require.True(t, val.GetStatus().Equal(expStatus), val.GetStatus().String(), expStatus.String()) 309 require.True(t, val.GetDelegatorShares().Equal(expDlgShares), val.GetDelegatorShares().String(), expDlgShares.String()) 310 require.True(t, val.IsJailed() == expJailed) 311 312 return &val 313 } 314 315 // mockDistributionKeeper is supported to test Hooks 316 type mockDistributionKeeper struct{} 317 318 func (dk mockDistributionKeeper) Hooks() types.StakingHooks { return dk } 319 func (dk mockDistributionKeeper) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {} 320 func (dk mockDistributionKeeper) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {} 321 func (dk mockDistributionKeeper) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) { 322 } 323 func (dk mockDistributionKeeper) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) { 324 } 325 func (dk mockDistributionKeeper) AfterValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) { 326 } 327 func (dk mockDistributionKeeper) AfterValidatorDestroyed(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) { 328 }