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