github.com/Finschia/finschia-sdk@v0.49.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 err = sk2.ReleaseCapability(suite.ctx, cap2) 149 suite.Require().NoError(err) 150 suite.Require().False(sk2.AuthenticateCapability(suite.ctx, cap2, "bond")) 151 152 badCap := types.NewCapability(100) 153 suite.Require().False(sk1.AuthenticateCapability(suite.ctx, badCap, "transfer")) 154 suite.Require().False(sk2.AuthenticateCapability(suite.ctx, badCap, "bond")) 155 156 suite.Require().False(sk1.AuthenticateCapability(suite.ctx, cap1, " ")) 157 suite.Require().False(sk1.AuthenticateCapability(suite.ctx, nil, "transfer")) 158 } 159 160 func (suite *KeeperTestSuite) TestClaimCapability() { 161 sk1 := suite.keeper.ScopeToModule(banktypes.ModuleName) 162 sk2 := suite.keeper.ScopeToModule(stakingtypes.ModuleName) 163 sk3 := suite.keeper.ScopeToModule("foo") 164 165 cap, err := sk1.NewCapability(suite.ctx, "transfer") 166 suite.Require().NoError(err) 167 suite.Require().NotNil(cap) 168 169 suite.Require().Error(sk1.ClaimCapability(suite.ctx, cap, "transfer")) 170 suite.Require().NoError(sk2.ClaimCapability(suite.ctx, cap, "transfer")) 171 172 got, ok := sk1.GetCapability(suite.ctx, "transfer") 173 suite.Require().True(ok) 174 suite.Require().Equal(cap, got) 175 176 got, ok = sk2.GetCapability(suite.ctx, "transfer") 177 suite.Require().True(ok) 178 suite.Require().Equal(cap, got) 179 180 suite.Require().Error(sk3.ClaimCapability(suite.ctx, cap, " ")) 181 suite.Require().Error(sk3.ClaimCapability(suite.ctx, nil, "transfer")) 182 } 183 184 func (suite *KeeperTestSuite) TestGetOwners() { 185 sk1 := suite.keeper.ScopeToModule(banktypes.ModuleName) 186 sk2 := suite.keeper.ScopeToModule(stakingtypes.ModuleName) 187 sk3 := suite.keeper.ScopeToModule("foo") 188 189 sks := []keeper.ScopedKeeper{sk1, sk2, sk3} 190 191 cap, err := sk1.NewCapability(suite.ctx, "transfer") 192 suite.Require().NoError(err) 193 suite.Require().NotNil(cap) 194 195 suite.Require().NoError(sk2.ClaimCapability(suite.ctx, cap, "transfer")) 196 suite.Require().NoError(sk3.ClaimCapability(suite.ctx, cap, "transfer")) 197 198 expectedOrder := []string{banktypes.ModuleName, "foo", stakingtypes.ModuleName} 199 // Ensure all scoped keepers can get owners 200 for _, sk := range sks { 201 owners, ok := sk.GetOwners(suite.ctx, "transfer") 202 mods, gotCap, err := sk.LookupModules(suite.ctx, "transfer") 203 204 suite.Require().True(ok, "could not retrieve owners") 205 suite.Require().NotNil(owners, "owners is nil") 206 207 suite.Require().NoError(err, "could not retrieve modules") 208 suite.Require().NotNil(gotCap, "capability is nil") 209 suite.Require().NotNil(mods, "modules is nil") 210 suite.Require().Equal(cap, gotCap, "caps not equal") 211 212 suite.Require().Equal(len(expectedOrder), len(owners.Owners), "length of owners is unexpected") 213 for i, o := range owners.Owners { 214 // Require owner is in expected position 215 suite.Require().Equal(expectedOrder[i], o.Module, "module is unexpected") 216 suite.Require().Equal(expectedOrder[i], mods[i], "module in lookup is unexpected") 217 } 218 } 219 220 // foo module releases capability 221 err = sk3.ReleaseCapability(suite.ctx, cap) 222 suite.Require().Nil(err, "could not release capability") 223 224 // new expected order and scoped capabilities 225 expectedOrder = []string{banktypes.ModuleName, stakingtypes.ModuleName} 226 sks = []keeper.ScopedKeeper{sk1, sk2} 227 228 // Ensure all scoped keepers can get owners 229 for _, sk := range sks { 230 owners, ok := sk.GetOwners(suite.ctx, "transfer") 231 mods, cap, err := sk.LookupModules(suite.ctx, "transfer") 232 233 suite.Require().True(ok, "could not retrieve owners") 234 suite.Require().NotNil(owners, "owners is nil") 235 236 suite.Require().NoError(err, "could not retrieve modules") 237 suite.Require().NotNil(cap, "capability is nil") 238 suite.Require().NotNil(mods, "modules is nil") 239 240 suite.Require().Equal(len(expectedOrder), len(owners.Owners), "length of owners is unexpected") 241 for i, o := range owners.Owners { 242 // Require owner is in expected position 243 suite.Require().Equal(expectedOrder[i], o.Module, "module is unexpected") 244 suite.Require().Equal(expectedOrder[i], mods[i], "module in lookup is unexpected") 245 } 246 } 247 248 _, ok := sk1.GetOwners(suite.ctx, " ") 249 suite.Require().False(ok, "got owners from empty capability name") 250 } 251 252 func (suite *KeeperTestSuite) TestReleaseCapability() { 253 sk1 := suite.keeper.ScopeToModule(banktypes.ModuleName) 254 sk2 := suite.keeper.ScopeToModule(stakingtypes.ModuleName) 255 256 cap1, err := sk1.NewCapability(suite.ctx, "transfer") 257 suite.Require().NoError(err) 258 suite.Require().NotNil(cap1) 259 260 suite.Require().NoError(sk2.ClaimCapability(suite.ctx, cap1, "transfer")) 261 262 cap2, err := sk2.NewCapability(suite.ctx, "bond") 263 suite.Require().NoError(err) 264 suite.Require().NotNil(cap2) 265 266 suite.Require().Error(sk1.ReleaseCapability(suite.ctx, cap2)) 267 268 suite.Require().NoError(sk2.ReleaseCapability(suite.ctx, cap1)) 269 got, ok := sk2.GetCapability(suite.ctx, "transfer") 270 suite.Require().False(ok) 271 suite.Require().Nil(got) 272 273 suite.Require().NoError(sk1.ReleaseCapability(suite.ctx, cap1)) 274 got, ok = sk1.GetCapability(suite.ctx, "transfer") 275 suite.Require().False(ok) 276 suite.Require().Nil(got) 277 278 suite.Require().Error(sk1.ReleaseCapability(suite.ctx, nil)) 279 } 280 281 func (suite *KeeperTestSuite) TestRevertCapability() { 282 sk := suite.keeper.ScopeToModule(banktypes.ModuleName) 283 284 ms := suite.ctx.MultiStore() 285 286 msCache := ms.CacheMultiStore() 287 cacheCtx := suite.ctx.WithMultiStore(msCache) 288 289 capName := "revert" 290 // Create capability on cached context 291 cap, err := sk.NewCapability(cacheCtx, capName) 292 suite.Require().NoError(err, "could not create capability") 293 294 // Check that capability written in cached context 295 gotCache, ok := sk.GetCapability(cacheCtx, capName) 296 suite.Require().True(ok, "could not retrieve capability from cached context") 297 suite.Require().Equal(cap, gotCache, "did not get correct capability from cached context") 298 299 // Check that capability is NOT written to original context 300 got, ok := sk.GetCapability(suite.ctx, capName) 301 suite.Require().False(ok, "retrieved capability from original context before write") 302 suite.Require().Nil(got, "capability not nil in original store") 303 304 // Write to underlying memKVStore 305 msCache.Write() 306 307 got, ok = sk.GetCapability(suite.ctx, capName) 308 suite.Require().True(ok, "could not retrieve capability from context") 309 suite.Require().Equal(cap, got, "did not get correct capability from context") 310 } 311 312 func TestKeeperTestSuite(t *testing.T) { 313 suite.Run(t, new(KeeperTestSuite)) 314 }