Skip to content

Commit

Permalink
ibc-transfer: sims updates (cosmos#7123)
Browse files Browse the repository at this point in the history
* ibc-transfer: sims updates

* params and genesis

* sim tests

* update module.go

* remove dontcover

* Update x/ibc-transfer/simulation/decoder.go

Co-authored-by: colin axnér <[email protected]>

Co-authored-by: colin axnér <[email protected]>
  • Loading branch information
fedekunze and colin-axner authored Aug 21, 2020
1 parent a6defab commit 0234ad3
Show file tree
Hide file tree
Showing 12 changed files with 233 additions and 18 deletions.
5 changes: 2 additions & 3 deletions types/simulation/rand_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"math/big"
"math/rand"
"time"
"unsafe"

sdk "github.com/cosmos/cosmos-sdk/types"
)
Expand All @@ -27,17 +28,15 @@ func RandStringOfLength(r *rand.Rand, n int) string {
if remain == 0 {
cache, remain = r.Int63(), letterIdxMax
}

if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
b[i] = letterBytes[idx]
i--
}

cache >>= letterIdxBits
remain--
}

return string(b)
return *(*string)(unsafe.Pointer(&b))
}

// RandPositiveInt get a rand positive sdk.Int
Expand Down
5 changes: 3 additions & 2 deletions x/bank/simulation/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import (
"github.com/cosmos/cosmos-sdk/x/bank/types"
)

type SupplyUnmarshaller interface {
// SupplyUnmarshaler defines the expected encoding store functions.
type SupplyUnmarshaler interface {
UnmarshalSupply([]byte) (exported.SupplyI, error)
}

// NewDecodeStore returns a function closure that unmarshals the KVPair's values
// to the corresponding types.
func NewDecodeStore(cdc SupplyUnmarshaller) func(kvA, kvB kv.Pair) string {
func NewDecodeStore(cdc SupplyUnmarshaler) func(kvA, kvB kv.Pair) string {
return func(kvA, kvB kv.Pair) string {
switch {
case bytes.Equal(kvA.Key[:1], types.SupplyKey):
Expand Down
35 changes: 35 additions & 0 deletions x/ibc-transfer/keeper/encoding.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package keeper

import (
"github.com/cosmos/cosmos-sdk/x/ibc-transfer/types"
)

// UnmarshalDenomTrace attempts to decode and return an DenomTrace object from
// raw encoded bytes.
func (k Keeper) UnmarshalDenomTrace(bz []byte) (types.DenomTrace, error) {
var denomTrace types.DenomTrace
if err := k.cdc.UnmarshalBinaryBare(bz, &denomTrace); err != nil {
return types.DenomTrace{}, err
}
return denomTrace, nil
}

// MustUnmarshalDenomTrace attempts to decode and return an DenomTrace object from
// raw encoded bytes. It panics on error.
func (k Keeper) MustUnmarshalDenomTrace(bz []byte) types.DenomTrace {
var denomTrace types.DenomTrace
k.cdc.MustUnmarshalBinaryBare(bz, &denomTrace)
return denomTrace
}

// MarshalDenomTrace attempts to encode an DenomTrace object and returns the
// raw encoded bytes.
func (k Keeper) MarshalDenomTrace(denomTrace types.DenomTrace) ([]byte, error) {
return k.cdc.MarshalBinaryBare(&denomTrace)
}

// MustMarshalDenomTrace attempts to encode an DenomTrace object and returns the
// raw encoded bytes. It panics on error.
func (k Keeper) MustMarshalDenomTrace(denomTrace types.DenomTrace) []byte {
return k.cdc.MustMarshalBinaryBare(&denomTrace)
}
4 changes: 2 additions & 2 deletions x/ibc-transfer/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ func (q Keeper) DenomTraces(c context.Context, req *types.QueryDenomTracesReques
store := prefix.NewStore(ctx.KVStore(q.storeKey), types.DenomTraceKey)

pageRes, err := query.Paginate(store, req.Pagination, func(_, value []byte) error {
var result types.DenomTrace
if err := q.cdc.UnmarshalBinaryBare(value, &result); err != nil {
result, err := q.UnmarshalDenomTrace(value)
if err != nil {
return err
}

Expand Down
9 changes: 3 additions & 6 deletions x/ibc-transfer/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,7 @@ func (k Keeper) GetDenomTrace(ctx sdk.Context, denomTraceHash tmbytes.HexBytes)
return types.DenomTrace{}, false
}

var denomTrace types.DenomTrace
k.cdc.MustUnmarshalBinaryBare(bz, &denomTrace)
denomTrace := k.MustUnmarshalDenomTrace(bz)
return denomTrace, true
}

Expand All @@ -141,7 +140,7 @@ func (k Keeper) HasDenomTrace(ctx sdk.Context, denomTraceHash tmbytes.HexBytes)
// SetDenomTrace sets a new {trace hash -> denom trace} pair to the store.
func (k Keeper) SetDenomTrace(ctx sdk.Context, denomTrace types.DenomTrace) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.DenomTraceKey)
bz := k.cdc.MustMarshalBinaryBare(&denomTrace)
bz := k.MustMarshalDenomTrace(denomTrace)
store.Set(denomTrace.Hash(), bz)
}

Expand All @@ -165,9 +164,7 @@ func (k Keeper) IterateDenomTraces(ctx sdk.Context, cb func(denomTrace types.Den
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {

var denomTrace types.DenomTrace
k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &denomTrace)

denomTrace := k.MustUnmarshalDenomTrace(iterator.Value())
if cb(denomTrace) {
break
}
Expand Down
9 changes: 5 additions & 4 deletions x/ibc-transfer/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,14 @@ func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedP
return nil
}

// RandomizedParams returns nil.
func (AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange {
return nil
// RandomizedParams creates randomized ibc-transfer param changes for the simulator.
func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange {
return simulation.ParamChanges(r)
}

// RegisterStoreDecoder registers a decoder for transfer module's types
func (am AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) {
func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
sdr[types.StoreKey] = simulation.NewDecodeStore(am.keeper)
}

// WeightedOperations returns the all the transfer module operations with their respective weights.
Expand Down
33 changes: 33 additions & 0 deletions x/ibc-transfer/simulation/decoder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package simulation

import (
"bytes"
"fmt"

"github.com/cosmos/cosmos-sdk/types/kv"
"github.com/cosmos/cosmos-sdk/x/ibc-transfer/types"
)

// TransferUnmarshaler defines the expected encoding store functions.
type TransferUnmarshaler interface {
MustUnmarshalDenomTrace([]byte) types.DenomTrace
}

// NewDecodeStore returns a decoder function closure that unmarshals the KVPair's
// Value to the corresponding DenomTrace type.
func NewDecodeStore(cdc TransferUnmarshaler) func(kvA, kvB kv.Pair) string {
return func(kvA, kvB kv.Pair) string {
switch {
case bytes.Equal(kvA.Key[:1], types.PortKey):
return fmt.Sprintf("Port A: %s\nPort B: %s", string(kvA.Value), string(kvB.Value))

case bytes.Equal(kvA.Key[:1], types.DenomTraceKey):
denomTraceA := cdc.MustUnmarshalDenomTrace(kvA.Value)
denomTraceB := cdc.MustUnmarshalDenomTrace(kvB.Value)
return fmt.Sprintf("DenomTrace A: %s\nDenomTrace B: %s", denomTraceA.IBCDenom(), denomTraceB.IBCDenom())

default:
panic(fmt.Sprintf("invalid %s key prefix %X", types.ModuleName, kvA.Key[:1]))
}
}
}
59 changes: 59 additions & 0 deletions x/ibc-transfer/simulation/decoder_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package simulation_test

import (
"fmt"
"testing"

"github.com/stretchr/testify/require"

"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/types/kv"
"github.com/cosmos/cosmos-sdk/x/ibc-transfer/simulation"
"github.com/cosmos/cosmos-sdk/x/ibc-transfer/types"
)

func TestDecodeStore(t *testing.T) {
app := simapp.Setup(false)
dec := simulation.NewDecodeStore(app.TransferKeeper)

trace := types.DenomTrace{
BaseDenom: "uatom",
Path: "transfer/channelToA",
}

kvPairs := kv.Pairs{
Pairs: []kv.Pair{
{
Key: types.PortKey,
Value: []byte(types.PortID),
},
{
Key: types.DenomTraceKey,
Value: app.TransferKeeper.MustMarshalDenomTrace(trace),
},
{
Key: []byte{0x99},
Value: []byte{0x99},
},
},
}
tests := []struct {
name string
expectedLog string
}{
{"PortID", fmt.Sprintf("Port A: %s\nPort B: %s", types.PortID, types.PortID)},
{"DenomTrace", fmt.Sprintf("DenomTrace A: %s\nDenomTrace B: %s", trace.IBCDenom(), trace.IBCDenom())},
{"other", ""},
}

for i, tt := range tests {
i, tt := i, tt
t.Run(tt.name, func(t *testing.T) {
if i == len(tests)-1 {
require.Panics(t, func() { dec(kvPairs.Pairs[i], kvPairs.Pairs[i]) }, tt.name)
} else {
require.Equal(t, tt.expectedLog, dec(kvPairs.Pairs[i], kvPairs.Pairs[i]), tt.name)
}
})
}
}
21 changes: 20 additions & 1 deletion x/ibc-transfer/simulation/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ import (
// Simulation parameter constants
const port = "port_id"

// RadomEnabled randomized send or receive enabled param with 75% prob of being true.
func RadomEnabled(r *rand.Rand) bool {
return r.Int63n(101) <= 75
}

// RandomizedGenState generates a random GenesisState for transfer.
func RandomizedGenState(simState *module.SimulationState) {
var portID string
Expand All @@ -22,8 +27,22 @@ func RandomizedGenState(simState *module.SimulationState) {
func(r *rand.Rand) { portID = strings.ToLower(simtypes.RandStringOfLength(r, 20)) },
)

var sendEnabled bool
simState.AppParams.GetOrGenerate(
simState.Cdc, string(types.KeySendEnabled), &sendEnabled, simState.Rand,
func(r *rand.Rand) { sendEnabled = RadomEnabled(r) },
)

var receiveEnabled bool
simState.AppParams.GetOrGenerate(
simState.Cdc, string(types.KeyReceiveEnabled), &receiveEnabled, simState.Rand,
func(r *rand.Rand) { receiveEnabled = RadomEnabled(r) },
)

transferGenesis := types.GenesisState{
PortId: portID,
PortId: portID,
DenomTraces: types.Traces{},
Params: types.NewParams(sendEnabled, receiveEnabled),
}

fmt.Printf("Selected randomly generated %s parameters:\n%s\n", types.ModuleName, codec.MustMarshalJSONIndent(simState.Cdc, &transferGenesis))
Expand Down
3 changes: 3 additions & 0 deletions x/ibc-transfer/simulation/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ func TestRandomizedGenState(t *testing.T) {
simState.Cdc.MustUnmarshalJSON(simState.GenState[types.ModuleName], &ibcTransferGenesis)

require.Equal(t, "euzxpfgkqegqiqwixnku", ibcTransferGenesis.PortId)
require.True(t, ibcTransferGenesis.Params.SendEnabled)
require.True(t, ibcTransferGenesis.Params.ReceiveEnabled)
require.Len(t, ibcTransferGenesis.DenomTraces, 0)

}

Expand Down
32 changes: 32 additions & 0 deletions x/ibc-transfer/simulation/params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package simulation

import (
"fmt"
"math/rand"

gogotypes "github.com/gogo/protobuf/types"

"github.com/cosmos/cosmos-sdk/x/simulation"

simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
"github.com/cosmos/cosmos-sdk/x/ibc-transfer/types"
)

// ParamChanges defines the parameters that can be modified by param change proposals
// on the simulation
func ParamChanges(r *rand.Rand) []simtypes.ParamChange {
return []simtypes.ParamChange{
simulation.NewSimParamChange(types.ModuleName, string(types.KeySendEnabled),
func(r *rand.Rand) string {
sendEnabled := RadomEnabled(r)
return fmt.Sprintf("%s", types.ModuleCdc.MustMarshalJSON(&gogotypes.BoolValue{Value: sendEnabled}))
},
),
simulation.NewSimParamChange(types.ModuleName, string(types.KeyReceiveEnabled),
func(r *rand.Rand) string {
receiveEnabled := RadomEnabled(r)
return fmt.Sprintf("%s", types.ModuleCdc.MustMarshalJSON(&gogotypes.BoolValue{Value: receiveEnabled}))
},
),
}
}
36 changes: 36 additions & 0 deletions x/ibc-transfer/simulation/params_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package simulation_test

import (
"math/rand"
"testing"

"github.com/stretchr/testify/require"

"github.com/cosmos/cosmos-sdk/x/ibc-transfer/simulation"
)

func TestParamChanges(t *testing.T) {
s := rand.NewSource(1)
r := rand.New(s)

expected := []struct {
composedKey string
key string
simValue string
subspace string
}{
{"transfer/SendEnabled", "SendEnabled", "false", "transfer"},
{"transfer/ReceiveEnabled", "ReceiveEnabled", "true", "transfer"},
}

paramChanges := simulation.ParamChanges(r)

require.Len(t, paramChanges, 2)

for i, p := range paramChanges {
require.Equal(t, expected[i].composedKey, p.ComposedKey())
require.Equal(t, expected[i].key, p.Key())
require.Equal(t, expected[i].simValue, p.SimValue()(r), p.Key())
require.Equal(t, expected[i].subspace, p.Subspace())
}
}

0 comments on commit 0234ad3

Please sign in to comment.