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  }