Skip to content
Open
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 @@
* Migrated hold module to collections for state storage [#2419](https://github.com/provenance-io/provenance/issues/2419).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Issue number in changelog does not match the PR's linked issue.

The changelog filename and content both reference issue #2419, but the PR description states it closes issue #2491. Please verify and correct the issue number (the filename would also need renaming to match).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.changelog/unreleased/features/2419-hold-module-collections.md at line 1,
The changelog entry references issue `#2419` but the PR closes `#2491`; update the
changelog file so both the filename and the issue link inside the content use
the correct issue number (change the "2419" in the filename and the
"[`#2419`](...)" text to "2491" and adjust the URL to /issues/2491) so the
filename, the markdown text "Migrated hold module to collections for state
storage", and the linked issue number are consistent with the PR.

2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ func New(
)

app.HoldKeeper = holdkeeper.NewKeeper(
appCodec, keys[hold.StoreKey], app.AccountKeeper, app.BankKeeper,
appCodec, runtime.NewKVStoreService(keys[hold.StoreKey]), app.AccountKeeper, app.BankKeeper,
)

app.RegistryKeeper = registrykeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[registrytypes.StoreKey]), app.NFTKeeper, app.MetadataKeeper)
Expand Down
156 changes: 156 additions & 0 deletions x/hold/codec.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package hold

import (
"encoding/json"
"fmt"

"cosmossdk.io/collections"
sdkmath "cosmossdk.io/math"

cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/gogoproto/proto"
Expand All @@ -11,3 +17,153 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) {
copy(messages, AllRequestMsgs)
registry.RegisterImplementations((*sdk.Msg)(nil), messages...)
}

// Custom value codec for sdkmath.Int
type IntValueCodec struct{}

func (c IntValueCodec) Encode(value sdkmath.Int) ([]byte, error) {
return value.Marshal()
}

func (c IntValueCodec) Decode(b []byte) (sdkmath.Int, error) {
if len(b) == 0 {
return sdkmath.ZeroInt(), nil
}
var i sdkmath.Int
err := i.Unmarshal(b)
return i, err
}

func (c IntValueCodec) EncodeJSON(value sdkmath.Int) ([]byte, error) {
return value.MarshalJSON()
}

func (c IntValueCodec) DecodeJSON(b []byte) (sdkmath.Int, error) {
var i sdkmath.Int
err := i.UnmarshalJSON(b)
return i, err
}

func (c IntValueCodec) Stringify(value sdkmath.Int) string {
return value.String()
}

func (c IntValueCodec) ValueType() string {
return "sdkmath.Int"
}

// Custom key codec for address with 1-byte length prefix
type AddressKeyCodec struct{}

func (AddressKeyCodec) Encode(buffer []byte, addr sdk.AccAddress) (int, error) {
if addr == nil {
return 0, fmt.Errorf("cannot encode nil address")
}
if len(buffer) == 0 {
return 0, fmt.Errorf("buffer is empty")
}
if len(addr) > 255 {
return 0, collections.ErrEncoding
}
buffer[0] = byte(len(addr))
copy(buffer[1:], addr)
return 1 + len(addr), nil
}

func (AddressKeyCodec) Decode(buffer []byte) (int, sdk.AccAddress, error) {
if len(buffer) == 0 {
return 0, nil, collections.ErrEncoding
}
length := int(buffer[0])
if len(buffer) < 1+length {
return 0, nil, collections.ErrEncoding
}
addr := make(sdk.AccAddress, length)
copy(addr, buffer[1:1+length])
return 1 + length, addr, nil
}

func (AddressKeyCodec) Size(key sdk.AccAddress) int {
return 1 + len(key)
}

func (AddressKeyCodec) EncodeJSON(value sdk.AccAddress) ([]byte, error) {
return json.Marshal(value.String())
}

func (AddressKeyCodec) DecodeJSON(b []byte) (sdk.AccAddress, error) {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return nil, err
}
return sdk.AccAddressFromBech32(s)
}

func (AddressKeyCodec) Stringify(key sdk.AccAddress) string {
return key.String()
}

func (AddressKeyCodec) KeyType() string {
return "addressKeyCodec"
}

func (AddressKeyCodec) EncodeNonTerminal(buffer []byte, key sdk.AccAddress) (int, error) {
return AddressKeyCodec{}.Encode(buffer, key)
}

func (AddressKeyCodec) DecodeNonTerminal(buffer []byte) (int, sdk.AccAddress, error) {
return AddressKeyCodec{}.Decode(buffer)
}

func (AddressKeyCodec) SizeNonTerminal(key sdk.AccAddress) int {
return AddressKeyCodec{}.Size(key)
}

// Custom key codec for denom (raw bytes, no length prefix)
type DenomKeyCodec struct{}

func (DenomKeyCodec) Encode(buffer []byte, denom string) (int, error) {
denomBytes := []byte(denom)
if len(buffer) < len(denomBytes) {
return 0, collections.ErrEncoding
}
return copy(buffer, denomBytes), nil
}

func (DenomKeyCodec) Decode(buffer []byte) (int, string, error) {
return len(buffer), string(buffer), nil
}

func (DenomKeyCodec) Size(key string) int {
return len(key)
}

func (DenomKeyCodec) EncodeJSON(value string) ([]byte, error) {
return json.Marshal(value)
}

func (DenomKeyCodec) DecodeJSON(b []byte) (string, error) {
var s string
err := json.Unmarshal(b, &s)
return s, err
}

func (DenomKeyCodec) Stringify(key string) string {
return key
}

func (DenomKeyCodec) KeyType() string {
return "denomKeyCodec"
}

func (DenomKeyCodec) EncodeNonTerminal(buffer []byte, key string) (int, error) {
return DenomKeyCodec{}.Encode(buffer, key)
}

func (DenomKeyCodec) DecodeNonTerminal(buffer []byte) (int, string, error) {
return DenomKeyCodec{}.Decode(buffer)
}
Comment thread
nagarajdivine marked this conversation as resolved.

func (DenomKeyCodec) SizeNonTerminal(key string) int {
return DenomKeyCodec{}.Size(key)
}
13 changes: 3 additions & 10 deletions x/hold/keeper/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package keeper

import (
sdkmath "cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/provenance-io/provenance/x/hold"
Expand All @@ -27,17 +25,12 @@ func (k Keeper) WithAccountKeeper(ak hold.AccountKeeper) Keeper {
return k
}

// GetStoreKey exposes this keeper's storekey for unit tests.
func (k Keeper) GetStoreKey() storetypes.StoreKey {
return k.storeKey
}

// SetHoldCoinAmount exposes this keeper's setHoldCoinAmount function for unit tests.
func (k Keeper) SetHoldCoinAmount(store storetypes.KVStore, addr sdk.AccAddress, denom string, amount sdkmath.Int) error {
return k.setHoldCoinAmount(store, addr, denom, amount)
func (k Keeper) SetHoldCoinAmount(ctx sdk.Context, addr sdk.AccAddress, denom string, amount sdkmath.Int) error {
return k.setHoldCoinAmount(ctx, addr, denom, amount)
}

// GetSpendableForDenoms exposes this keeper's getSpendableForDenoms function for unit tests.
func (k Keeper) GetSpendableForDenoms(ctx sdk.Context, addr sdk.AccAddress, funds sdk.Coins) sdk.Coins {
return k.getSpendableForDenoms(ctx, addr, funds)
}
}
13 changes: 6 additions & 7 deletions x/hold/keeper/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ package keeper_test
import (
"sort"

storetypes "cosmossdk.io/store/types"

"cosmossdk.io/core/store"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/provenance-io/provenance/x/hold"
Expand Down Expand Up @@ -151,7 +150,7 @@ func (s *TestSuite) TestKeeper_ExportGenesis() {

tests := []struct {
name string
setup func(*TestSuite, storetypes.KVStore)
setup func(*TestSuite, store.KVStore)
expGenState *hold.GenesisState
expPanic []string
}{
Expand All @@ -161,14 +160,14 @@ func (s *TestSuite) TestKeeper_ExportGenesis() {
},
{
name: "one entry: good",
setup: func(s *TestSuite, store storetypes.KVStore) {
setup: func(s *TestSuite, store store.KVStore) {
s.requireSetHoldCoinAmount(store, s.addr1, "banana", s.int(99))
},
expGenState: genStateWithHolds(accHold(s.addr1, "99banana")),
},
{
name: "one entry: bad",
setup: func(s *TestSuite, store storetypes.KVStore) {
setup: func(s *TestSuite, store store.KVStore) {
s.setHoldCoinAmountRaw(store, s.addr1, "badcoin", "badvalue")
s.requireSetHoldCoinAmount(store, s.addr1, "banana", s.int(99))
},
Expand All @@ -179,7 +178,7 @@ func (s *TestSuite) TestKeeper_ExportGenesis() {
},
{
name: "five addrs: all good",
setup: func(suite *TestSuite, store storetypes.KVStore) {
setup: func(suite *TestSuite, store store.KVStore) {
s.requireSetHoldCoinAmount(store, s.addr1, "banana", s.int(99))
s.requireSetHoldCoinAmount(store, s.addr1, "cucumber", s.int(3))
s.requireSetHoldCoinAmount(store, s.addr1, "durian", s.int(8))
Expand All @@ -203,7 +202,7 @@ func (s *TestSuite) TestKeeper_ExportGenesis() {
},
{
name: "five addrs: several bad",
setup: func(suite *TestSuite, store storetypes.KVStore) {
setup: func(suite *TestSuite, store store.KVStore) {
s.requireSetHoldCoinAmount(store, s.addr1, "banana", s.int(99))
s.requireSetHoldCoinAmount(store, s.addr1, "cucumber", s.int(3))
s.requireSetHoldCoinAmount(store, s.addr1, "durian", s.int(8))
Expand Down
Loading
Loading