Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: simplify x/relationships store keys #838

Merged
merged 3 commits into from
Apr 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
type: fix
module: x/relationships
pull_request: 838
description: Replaced store keys to use less disk space
backward_compatible: false
date: 2022-04-22T12:01:24.865079216Z
7 changes: 7 additions & 0 deletions x/relationships/keeper/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"

v2 "github.com/desmos-labs/desmos/v3/x/relationships/legacy/v2"

profilesv4 "github.com/desmos-labs/desmos/v3/x/profiles/legacy/v4"

v1 "github.com/desmos-labs/desmos/v3/x/relationships/legacy/v1"
Expand All @@ -28,3 +30,8 @@ func NewMigrator(keeper Keeper, pk profilesv4.Keeper) Migrator {
func (m Migrator) Migrate1To2(ctx sdk.Context) error {
return v1.MigrateStore(ctx, m.pk, m.keeper.storeKey, m.keeper.cdc)
}

// Migrate1To2 migrates from version 2 to 3.
func (m Migrator) Migrate2To3(ctx sdk.Context) error {
return v2.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc)
}
45 changes: 45 additions & 0 deletions x/relationships/legacy/v1/keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package v1

// DONTCOVER

import (
subspacestypes "github.com/desmos-labs/desmos/v3/x/subspaces/types"
)

var (
RelationshipsStorePrefix = []byte("relationships")
UsersBlocksStorePrefix = []byte("users_blocks")
)

// SubspaceRelationshipsPrefix returns the prefix used to store all relationships for the given subspace
func SubspaceRelationshipsPrefix(subspaceID uint64) []byte {
return append(RelationshipsStorePrefix, subspacestypes.GetSubspaceIDBytes(subspaceID)...)
}

// UserRelationshipsSubspacePrefix returns the prefix used to store all the relationships created by the user
// with the given address for the subspace having the given id
func UserRelationshipsSubspacePrefix(subspace uint64, user string) []byte {
return append(SubspaceRelationshipsPrefix(subspace), []byte(user)...)
}

// RelationshipsStoreKey returns the store key used to store the relationships containing the given data
func RelationshipsStoreKey(user, counterparty string, subspace uint64) []byte {
return append(UserRelationshipsSubspacePrefix(subspace, user), []byte(counterparty)...)
}

// SubspaceBlocksPrefix returns the store prefix used to store the blocks for the given subspace
func SubspaceBlocksPrefix(subspaceID uint64) []byte {
return append(UsersBlocksStorePrefix, subspacestypes.GetSubspaceIDBytes(subspaceID)...)
}

// BlockerSubspacePrefix returns the store prefix used to store the blocks that the given blocker
// has created inside the specified subspace
func BlockerSubspacePrefix(subspaceID uint64, blocker string) []byte {
return append(SubspaceBlocksPrefix(subspaceID), []byte(blocker)...)
}

// UserBlockStoreKey returns the store key used to save the block made by the given blocker,
// inside the specified subspace and towards the given blocked user
func UserBlockStoreKey(blocker, blockedUser string, subspace uint64) []byte {
return append(BlockerSubspacePrefix(subspace, blocker), []byte(blockedUser)...)
}
103 changes: 103 additions & 0 deletions x/relationships/legacy/v2/store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package v2

import (
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"

v1 "github.com/desmos-labs/desmos/v3/x/relationships/legacy/v1"
"github.com/desmos-labs/desmos/v3/x/relationships/types"
)

// MigrateStore performs in-place store migrations from v1 to v2.
// The migration includes:
//
// - migrate all relationships keys to the new ones
// - migrate all user blocks keys to the new ones
func MigrateStore(ctx sdk.Context, storeKey sdk.StoreKey, cdc codec.BinaryCodec) error {
store := ctx.KVStore(storeKey)

err := migrateRelationships(store, cdc)
if err != nil {
return err
}

err = migrateUserBlocks(store, cdc)
if err != nil {
return err
}

return nil
}

// migrateRelationships migrates all the relationships from using the old key to using the new key
func migrateRelationships(store sdk.KVStore, cdc codec.BinaryCodec) error {
prefixStore := prefix.NewStore(store, v1.RelationshipsStorePrefix)
iterator := prefixStore.Iterator(nil, nil)

// Read all the existing relationships and the associated keys
var keys [][]byte
var relationships []types.Relationship
for ; iterator.Valid(); iterator.Next() {
keys = append(keys, append(v1.RelationshipsStorePrefix, iterator.Key()...))

var relationship types.Relationship
err := cdc.Unmarshal(iterator.Value(), &relationship)
if err != nil {
return err
}
relationships = append(relationships, relationship)
}
iterator.Close()

for i, relationship := range relationships {
// Delete the old key
store.Delete(keys[i])

bz, err := cdc.Marshal(&relationships[i])
if err != nil {
return err
}

// Store the relationship with the new key
store.Set(types.RelationshipsStoreKey(relationship.Creator, relationship.Counterparty, relationship.SubspaceID), bz)
}

return nil
}

// migrateUserBlocks migrates all the user blocks from using the old key to using the new key
func migrateUserBlocks(store sdk.KVStore, cdc codec.BinaryCodec) error {
prefixStore := prefix.NewStore(store, v1.UsersBlocksStorePrefix)
iterator := prefixStore.Iterator(nil, nil)

// Read all the existing blocks and the associated keys
var keys [][]byte
var blocks []types.UserBlock
for ; iterator.Valid(); iterator.Next() {
keys = append(keys, append(v1.UsersBlocksStorePrefix, iterator.Key()...))

var block types.UserBlock
err := cdc.Unmarshal(iterator.Value(), &block)
if err != nil {
return err
}
blocks = append(blocks, block)
}
iterator.Close()

for i, block := range blocks {
// Delete the old key
store.Delete(keys[i])

bz, err := cdc.Marshal(&blocks[i])
if err != nil {
return err
}

// Store the block with the new key
store.Set(types.UserBlockStoreKey(block.Blocker, block.Blocked, block.SubspaceID), bz)
}

return nil
}
115 changes: 115 additions & 0 deletions x/relationships/legacy/v2/store_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package v2_test

import (
"testing"

v2 "github.com/desmos-labs/desmos/v3/x/relationships/legacy/v2"

"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"

"github.com/desmos-labs/desmos/v3/app"
v1 "github.com/desmos-labs/desmos/v3/x/relationships/legacy/v1"
"github.com/desmos-labs/desmos/v3/x/relationships/types"
)

func TestMigrateStore(t *testing.T) {
cdc, _ := app.MakeCodecs()
storeKey := sdk.NewKVStoreKey(types.StoreKey)
testCases := []struct {
name string
store func(ctx sdk.Context)
shouldErr bool
check func(ctx sdk.Context)
}{
{
name: "relationships are migrated properly",
store: func(ctx sdk.Context) {
store := ctx.KVStore(storeKey)

relBz := cdc.MustMarshal(&types.Relationship{
Creator: "user",
Counterparty: "counterparty",
SubspaceID: 1,
})
store.Set(v1.RelationshipsStoreKey("user", "counterparty", 1), relBz)
},
shouldErr: false,
check: func(ctx sdk.Context) {
store := ctx.KVStore(storeKey)

// Make sure the old keys are deleted properly
v1Key := v1.RelationshipsStoreKey("user", "counterparty", 1)
require.False(t, store.Has(v1Key))

v2Key := types.RelationshipsStoreKey("user", "counterparty", 1)
require.True(t, store.Has(v2Key))

var stored types.Relationship
err := cdc.Unmarshal(store.Get(v2Key), &stored)
require.NoError(t, err)
require.Equal(t, types.Relationship{
Creator: "user",
Counterparty: "counterparty",
SubspaceID: 1,
}, stored)
},
},
{
name: "user blocks are migrated properly",
store: func(ctx sdk.Context) {
store := ctx.KVStore(storeKey)

blockBz := cdc.MustMarshal(&types.UserBlock{
Blocker: "blocker",
Blocked: "blocked",
Reason: "reason",
SubspaceID: 1,
})
store.Set(v1.UserBlockStoreKey("blocker", "blocked", 1), blockBz)
},
shouldErr: false,
check: func(ctx sdk.Context) {
store := ctx.KVStore(storeKey)

// Make sure the old keys are deleted properly
v1Key := v1.UserBlockStoreKey("blocker", "blocked", 1)
require.False(t, store.Has(v1Key))

v2Key := types.UserBlockStoreKey("blocker", "blocked", 1)
require.True(t, store.Has(v2Key))

var stored types.UserBlock
err := cdc.Unmarshal(store.Get(v2Key), &stored)
require.NoError(t, err)
require.Equal(t, types.UserBlock{
Blocker: "blocker",
Blocked: "blocked",
Reason: "reason",
SubspaceID: 1,
}, stored)
},
},
}

for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
ctx := testutil.DefaultContext(storeKey, sdk.NewTransientStoreKey("test"))
if tc.store != nil {
tc.store(ctx)
}

err := v2.MigrateStore(ctx, storeKey, cdc)
if tc.shouldErr {
require.Error(t, err)
} else {
require.NoError(t, err)
if tc.check != nil {
tc.check(ctx)
}
}
})
}
}
6 changes: 5 additions & 1 deletion x/relationships/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import (
)

const (
consensusVersion = 2
consensusVersion = 3
)

// type check to ensure the interface is properly implemented
Expand Down Expand Up @@ -118,6 +118,10 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
if err != nil {
panic(err)
}
err = cfg.RegisterMigration(types.ModuleName, 2, m.Migrate2To3)
if err != nil {
panic(err)
}
}

// NewAppModule creates a new AppModule Object
Expand Down
4 changes: 2 additions & 2 deletions x/relationships/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ const (
)

var (
RelationshipsStorePrefix = []byte("relationships")
UsersBlocksStorePrefix = []byte("users_blocks")
RelationshipsStorePrefix = []byte{0x01}
UsersBlocksStorePrefix = []byte{0x02}
)

// SubspaceRelationshipsPrefix returns the prefix used to store all relationships for the given subspace
Expand Down