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  }