github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/capability/keeper/keeper_test.go (about) 1 package keeper_test 2 3 import ( 4 "fmt" 5 "testing" 6 7 fbexchaincodec "github.com/fibonacci-chain/fbc/app/codec" 8 abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types" 9 tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types" 10 11 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 12 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability/keeper" 13 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability/types" 14 stakingtypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking/types" 15 "github.com/fibonacci-chain/fbc/libs/ibc-go/testing/simapp" 16 "github.com/stretchr/testify/suite" 17 ) 18 19 type KeeperTestSuite struct { 20 suite.Suite 21 22 ctx sdk.Context 23 app *simapp.SimApp 24 keeper *keeper.Keeper 25 } 26 27 func (suite *KeeperTestSuite) SetupTest() { 28 checkTx := false 29 app := simapp.Setup(checkTx) 30 //cdc := app.Codec() 31 codecProxy, _ := fbexchaincodec.MakeCodecSuit(simapp.ModuleBasics) 32 // create new keeper so we can define custom scoping before init and seal 33 keeper := keeper.NewKeeper(codecProxy, app.GetKey(types.StoreKey), app.GetMemKey(types.MemStoreKey)) 34 35 suite.app = app 36 suite.ctx = app.BaseApp.NewContext(checkTx, abci.Header{Height: 1}) 37 suite.keeper = keeper 38 } 39 40 func (suite *KeeperTestSuite) TestSeal() { 41 sk := suite.keeper.ScopeToModule("bank") 42 suite.Require().Panics(func() { 43 suite.keeper.ScopeToModule(" ") 44 }) 45 46 caps := make([]*types.Capability, 5) 47 // Get Latest Index before creating new ones to sychronize indices correctly 48 prevIndex := suite.keeper.GetLatestIndex(suite.ctx) 49 50 for i := range caps { 51 cap, err := sk.NewCapability(suite.ctx, fmt.Sprintf("transfer-%d", i)) 52 suite.Require().NoError(err) 53 suite.Require().NotNil(cap) 54 suite.Require().Equal(uint64(i)+prevIndex, cap.GetIndex()) 55 56 caps[i] = cap 57 } 58 59 for i, cap := range caps { 60 got, ok := sk.GetCapability(suite.ctx, fmt.Sprintf("transfer-%d", i)) 61 suite.Require().True(ok) 62 suite.Require().Equal(cap, got) 63 suite.Require().Equal(uint64(i)+prevIndex, got.GetIndex()) 64 } 65 } 66 67 func (suite *KeeperTestSuite) TestNewCapability() { 68 sk := suite.keeper.ScopeToModule("bank") 69 70 got, ok := sk.GetCapability(suite.ctx, "transfer") 71 suite.Require().False(ok) 72 suite.Require().Nil(got) 73 74 cap, err := sk.NewCapability(suite.ctx, "transfer") 75 suite.Require().NoError(err) 76 suite.Require().NotNil(cap) 77 78 got, ok = sk.GetCapability(suite.ctx, "transfer") 79 suite.Require().True(ok) 80 suite.Require().Equal(cap, got) 81 suite.Require().True(cap == got, "expected memory addresses to be equal") 82 83 got, ok = sk.GetCapability(suite.ctx, "invalid") 84 suite.Require().False(ok) 85 suite.Require().Nil(got) 86 87 got, ok = sk.GetCapability(suite.ctx, "transfer") 88 suite.Require().True(ok) 89 suite.Require().Equal(cap, got) 90 suite.Require().True(cap == got, "expected memory addresses to be equal") 91 92 cap2, err := sk.NewCapability(suite.ctx, "transfer") 93 suite.Require().Error(err) 94 suite.Require().Nil(cap2) 95 96 got, ok = sk.GetCapability(suite.ctx, "transfer") 97 suite.Require().True(ok) 98 suite.Require().Equal(cap, got) 99 suite.Require().True(cap == got, "expected memory addresses to be equal") 100 101 cap, err = sk.NewCapability(suite.ctx, " ") 102 suite.Require().Error(err) 103 suite.Require().Nil(cap) 104 } 105 106 func (suite *KeeperTestSuite) TestAuthenticateCapability() { 107 sk1 := suite.keeper.ScopeToModule("bank") 108 sk2 := suite.keeper.ScopeToModule(stakingtypes.ModuleName) 109 110 cap1, err := sk1.NewCapability(suite.ctx, "transfer") 111 suite.Require().NoError(err) 112 suite.Require().NotNil(cap1) 113 114 forgedCap := types.NewCapability(cap1.Index) // index should be the same index as the first capability 115 suite.Require().False(sk1.AuthenticateCapability(suite.ctx, forgedCap, "transfer")) 116 suite.Require().False(sk2.AuthenticateCapability(suite.ctx, forgedCap, "transfer")) 117 118 cap2, err := sk2.NewCapability(suite.ctx, "bond") 119 suite.Require().NoError(err) 120 suite.Require().NotNil(cap2) 121 122 got, ok := sk1.GetCapability(suite.ctx, "transfer") 123 suite.Require().True(ok) 124 125 suite.Require().True(sk1.AuthenticateCapability(suite.ctx, cap1, "transfer")) 126 suite.Require().True(sk1.AuthenticateCapability(suite.ctx, got, "transfer")) 127 suite.Require().False(sk1.AuthenticateCapability(suite.ctx, cap1, "invalid")) 128 suite.Require().False(sk1.AuthenticateCapability(suite.ctx, cap2, "transfer")) 129 130 suite.Require().True(sk2.AuthenticateCapability(suite.ctx, cap2, "bond")) 131 suite.Require().False(sk2.AuthenticateCapability(suite.ctx, cap2, "invalid")) 132 suite.Require().False(sk2.AuthenticateCapability(suite.ctx, cap1, "bond")) 133 134 sk2.ReleaseCapability(suite.ctx, cap2) 135 suite.Require().False(sk2.AuthenticateCapability(suite.ctx, cap2, "bond")) 136 137 badCap := types.NewCapability(100) 138 suite.Require().False(sk1.AuthenticateCapability(suite.ctx, badCap, "transfer")) 139 suite.Require().False(sk2.AuthenticateCapability(suite.ctx, badCap, "bond")) 140 141 suite.Require().False(sk1.AuthenticateCapability(suite.ctx, cap1, " ")) 142 suite.Require().False(sk1.AuthenticateCapability(suite.ctx, nil, "transfer")) 143 } 144 145 func (suite *KeeperTestSuite) TestClaimCapability() { 146 sk1 := suite.keeper.ScopeToModule("bank") 147 sk2 := suite.keeper.ScopeToModule(stakingtypes.ModuleName) 148 sk3 := suite.keeper.ScopeToModule("foo") 149 150 cap, err := sk1.NewCapability(suite.ctx, "transfer") 151 suite.Require().NoError(err) 152 suite.Require().NotNil(cap) 153 154 suite.Require().Error(sk1.ClaimCapability(suite.ctx, cap, "transfer")) 155 suite.Require().NoError(sk2.ClaimCapability(suite.ctx, cap, "transfer")) 156 157 got, ok := sk1.GetCapability(suite.ctx, "transfer") 158 suite.Require().True(ok) 159 suite.Require().Equal(cap, got) 160 161 got, ok = sk2.GetCapability(suite.ctx, "transfer") 162 suite.Require().True(ok) 163 suite.Require().Equal(cap, got) 164 165 suite.Require().Error(sk3.ClaimCapability(suite.ctx, cap, " ")) 166 suite.Require().Error(sk3.ClaimCapability(suite.ctx, nil, "transfer")) 167 } 168 169 func (suite *KeeperTestSuite) TestGetOwners() { 170 sk1 := suite.keeper.ScopeToModule("bank") 171 sk2 := suite.keeper.ScopeToModule(stakingtypes.ModuleName) 172 sk3 := suite.keeper.ScopeToModule("foo") 173 174 sks := []keeper.ScopedKeeper{sk1, sk2, sk3} 175 176 cap, err := sk1.NewCapability(suite.ctx, "transfer") 177 suite.Require().NoError(err) 178 suite.Require().NotNil(cap) 179 180 suite.Require().NoError(sk2.ClaimCapability(suite.ctx, cap, "transfer")) 181 suite.Require().NoError(sk3.ClaimCapability(suite.ctx, cap, "transfer")) 182 183 expectedOrder := []string{"bank", "foo", stakingtypes.ModuleName} 184 // Ensure all scoped keepers can get owners 185 for _, sk := range sks { 186 owners, ok := sk.GetOwners(suite.ctx, "transfer") 187 mods, gotCap, err := sk.LookupModules(suite.ctx, "transfer") 188 189 suite.Require().True(ok, "could not retrieve owners") 190 suite.Require().NotNil(owners, "owners is nil") 191 192 suite.Require().NoError(err, "could not retrieve modules") 193 suite.Require().NotNil(gotCap, "capability is nil") 194 suite.Require().NotNil(mods, "modules is nil") 195 suite.Require().Equal(cap, gotCap, "caps not equal") 196 197 suite.Require().Equal(len(expectedOrder), len(owners.Owners), "length of owners is unexpected") 198 for i, o := range owners.Owners { 199 // Require owner is in expected position 200 suite.Require().Equal(expectedOrder[i], o.Module, "module is unexpected") 201 suite.Require().Equal(expectedOrder[i], mods[i], "module in lookup is unexpected") 202 } 203 } 204 205 // foo module releases capability 206 err = sk3.ReleaseCapability(suite.ctx, cap) 207 suite.Require().Nil(err, "could not release capability") 208 209 // new expected order and scoped capabilities 210 expectedOrder = []string{"bank", stakingtypes.ModuleName} 211 sks = []keeper.ScopedKeeper{sk1, sk2} 212 213 // Ensure all scoped keepers can get owners 214 for _, sk := range sks { 215 owners, ok := sk.GetOwners(suite.ctx, "transfer") 216 mods, cap, err := sk.LookupModules(suite.ctx, "transfer") 217 218 suite.Require().True(ok, "could not retrieve owners") 219 suite.Require().NotNil(owners, "owners is nil") 220 221 suite.Require().NoError(err, "could not retrieve modules") 222 suite.Require().NotNil(cap, "capability is nil") 223 suite.Require().NotNil(mods, "modules is nil") 224 225 suite.Require().Equal(len(expectedOrder), len(owners.Owners), "length of owners is unexpected") 226 for i, o := range owners.Owners { 227 // Require owner is in expected position 228 suite.Require().Equal(expectedOrder[i], o.Module, "module is unexpected") 229 suite.Require().Equal(expectedOrder[i], mods[i], "module in lookup is unexpected") 230 } 231 } 232 233 _, ok := sk1.GetOwners(suite.ctx, " ") 234 suite.Require().False(ok, "got owners from empty capability name") 235 } 236 237 func (suite *KeeperTestSuite) TestReleaseCapability() { 238 sk1 := suite.keeper.ScopeToModule("bank") 239 sk2 := suite.keeper.ScopeToModule(stakingtypes.ModuleName) 240 241 cap1, err := sk1.NewCapability(suite.ctx, "transfer") 242 suite.Require().NoError(err) 243 suite.Require().NotNil(cap1) 244 245 suite.Require().NoError(sk2.ClaimCapability(suite.ctx, cap1, "transfer")) 246 247 cap2, err := sk2.NewCapability(suite.ctx, "bond") 248 suite.Require().NoError(err) 249 suite.Require().NotNil(cap2) 250 251 suite.Require().Error(sk1.ReleaseCapability(suite.ctx, cap2)) 252 253 suite.Require().NoError(sk2.ReleaseCapability(suite.ctx, cap1)) 254 got, ok := sk2.GetCapability(suite.ctx, "transfer") 255 suite.Require().False(ok) 256 suite.Require().Nil(got) 257 258 suite.Require().NoError(sk1.ReleaseCapability(suite.ctx, cap1)) 259 got, ok = sk1.GetCapability(suite.ctx, "transfer") 260 suite.Require().False(ok) 261 suite.Require().Nil(got) 262 263 suite.Require().Error(sk1.ReleaseCapability(suite.ctx, nil)) 264 } 265 266 func (suite KeeperTestSuite) TestRevertCapability() { 267 sk := suite.keeper.ScopeToModule("bank") 268 269 ms := suite.ctx.MultiStore() 270 271 msCache := ms.CacheMultiStore() 272 cacheCtx := *suite.ctx.SetMultiStore(msCache) 273 274 capName := "revert" 275 // Create capability on cached context 276 cap, err := sk.NewCapability(cacheCtx, capName) 277 suite.Require().NoError(err, "could not create capability") 278 279 // Check that capability written in cached context 280 gotCache, ok := sk.GetCapability(cacheCtx, capName) 281 suite.Require().True(ok, "could not retrieve capability from cached context") 282 suite.Require().Equal(cap, gotCache, "did not get correct capability from cached context") 283 284 // Write to underlying memKVStore 285 msCache.Write() 286 287 got, ok := sk.GetCapability(suite.ctx, capName) 288 suite.Require().True(ok, "could not retrieve capability from context") 289 suite.Require().Equal(cap, got, "did not get correct capability from context") 290 } 291 292 func (suite KeeperTestSuite) TestReloadFromStore() { 293 sk := suite.keeper.ScopeToModule("bank") 294 cap1 := types.NewCapability(1) 295 name1 := "name1" 296 297 got, ok := sk.GetCapability(suite.ctx, name1) 298 suite.Require().False(ok) 299 suite.Require().Nil(got) 300 301 err := sk.ClaimCapability(suite.ctx, cap1, name1) 302 suite.Require().NoError(err) 303 // refresh memstore 304 tmtypes.DownloadDelta = true 305 suite.keeper.InitMemStore(suite.ctx) 306 307 got, ok = sk.GetCapability(suite.ctx, name1) 308 suite.Require().True(ok) 309 suite.Require().NotNil(got) 310 } 311 312 func TestKeeperTestSuite(t *testing.T) { 313 suite.Run(t, new(KeeperTestSuite)) 314 }