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

Audit/ Subaccount Fixes and cleanup #291

Merged
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
3 changes: 3 additions & 0 deletions x/subaccount/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
case *types.MsgWithdrawUnlockedBalances:
res, err := msgServer.WithdrawUnlockedBalances(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgWager:
res, err := msgServer.Wager(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgHouseDeposit:
res, err := msgServer.HouseDeposit(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
Expand Down
9 changes: 4 additions & 5 deletions x/subaccount/keeper/balance.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package keeper

import (
"fmt"

sdkerrors "cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -76,13 +75,13 @@ func (k Keeper) SetBalance(ctx sdk.Context, subAccountAddress sdk.AccAddress, ac
store := ctx.KVStore(k.storeKey)

bz := k.cdc.MustMarshal(&accountSummary)
store.Set(types.BalanceKey(subAccountAddress), bz)
store.Set(types.AccountSummaryKey(subAccountAddress), bz)
}

// GetBalance returns the balance of an account.
func (k Keeper) GetBalance(ctx sdk.Context, subAccountAddress sdk.AccAddress) (types.AccountSummary, bool) {
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.BalanceKey(subAccountAddress))
bz := store.Get(types.AccountSummaryKey(subAccountAddress))
if bz == nil {
return types.AccountSummary{}, false
}
Expand Down Expand Up @@ -120,7 +119,7 @@ func (k Keeper) TopUp(ctx sdk.Context, creator, subAccOwnerAddr string,

err = k.sendCoinsToSubaccount(ctx, creatorAddr, subAccAddr, moneyToAdd)
if err != nil {
return "", fmt.Errorf("unable to send coins: %w", err)
return "", sdkerrors.Wrapf(types.ErrSendCoinError, "%s", err)
}
return subAccAddr.String(), nil
}
Expand Down
7 changes: 6 additions & 1 deletion x/subaccount/module.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package subaccount

import (
"context"
"encoding/json"
"fmt"

Expand Down Expand Up @@ -68,7 +69,11 @@ func (AppModuleBasic) ValidateGenesis(
func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {}

// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module.
func (AppModuleBasic) RegisterGRPCGatewayRoutes(_ client.Context, _ *runtime.ServeMux) {}
func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {
if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil {
panic(err)
}
}

// GetTxCmd returns the module's root tx command.
func (AppModuleBasic) GetTxCmd() *cobra.Command { return cli.GetTxCmd() }
Expand Down
45 changes: 45 additions & 0 deletions x/subaccount/simulation/decoder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package simulation

import (
"bytes"
"fmt"

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

"github.com/sge-network/sge/x/subaccount/types"
)

// NewDecodeStore returns a decoder function closure that unmarshal the KVPair's
// Value to the corresponding house type.
func NewDecodeStore(cdc codec.BinaryCodec) func(kvA, kvB kv.Pair) string {
return func(kvA, kvB kv.Pair) string {
switch {
case bytes.Equal(kvA.Key, types.SubaccountIDPrefix):
idA := sdk.BigEndianToUint64(kvA.Value)
idB := sdk.BigEndianToUint64(kvB.Value)
return fmt.Sprintf("%v\n%v", idA, idB)
case bytes.Equal(kvA.Key, types.SubAccountOwnerPrefix):
idA := sdk.AccAddress(kvA.Value)
idB := sdk.AccAddress(kvB.Value)
return fmt.Sprintf("%v\n%v", idA, idB)
case bytes.Equal(kvA.Key, types.SubAccountOwnerReversePrefix):
idA := sdk.AccAddress(kvA.Value)
idB := sdk.AccAddress(kvB.Value)
return fmt.Sprintf("%v\n%v", idA, idB)
case bytes.Equal(kvA.Key, types.LockedBalancePrefix):
var lockedBalanceA, lockedBalanceB types.LockedBalance
cdc.MustUnmarshal(kvA.Value, &lockedBalanceA)
cdc.MustUnmarshal(kvB.Value, &lockedBalanceB)
return fmt.Sprintf("%v\n%v", lockedBalanceA, lockedBalanceB)
case bytes.Equal(kvA.Key, types.AccountSummaryPrefix):
var accSumA, accSumB types.AccountSummary
cdc.MustUnmarshal(kvA.Value, &accSumA)
cdc.MustUnmarshal(kvB.Value, &accSumB)
return fmt.Sprintf("%v\n%v", accSumA, accSumB)
default:
panic(fmt.Sprintf(errTextInvalidHouseKey, kvA.Key))
}
}
}
71 changes: 71 additions & 0 deletions x/subaccount/simulation/decoder_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package simulation_test

import (
"fmt"
"testing"

sdkmath "cosmossdk.io/math"
"github.com/stretchr/testify/require"

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

"github.com/sge-network/sge/app"
"github.com/sge-network/sge/testutil/sample"
"github.com/sge-network/sge/x/subaccount/simulation"
"github.com/sge-network/sge/x/subaccount/types"
)

func TestDecodeStore(t *testing.T) {
cdc := app.MakeEncodingConfig().Marshaler
dec := simulation.NewDecodeStore(cdc)

subID := 100
address := sample.NativeAccAddress()

lockedBalance := types.LockedBalance{
UnlockTS: 100,
Amount: sdkmath.NewInt(100),
}

accSummary := types.AccountSummary{
DepositedAmount: sdkmath.NewInt(100),
SpentAmount: sdkmath.NewInt(0),
WithdrawnAmount: sdkmath.ZeroInt(),
LostAmount: sdkmath.ZeroInt(),
}

kvPairs := kv.Pairs{
Pairs: []kv.Pair{
{Key: types.SubaccountIDPrefix, Value: sdk.Uint64ToBigEndian(uint64(subID))},
{Key: types.SubAccountOwnerPrefix, Value: address},
{Key: types.SubAccountOwnerReversePrefix, Value: address},
{Key: types.LockedBalancePrefix, Value: cdc.MustMarshal(&lockedBalance)},
{Key: types.AccountSummaryPrefix, Value: cdc.MustMarshal(&accSummary)},
{Key: []byte{0x99}, Value: []byte{0x99}},
},
}
tests := []struct {
name string
expectedLog string
}{
{"subID", fmt.Sprintf("%d\n%d", subID, subID)},
{"address", fmt.Sprintf("%d\n%d", address, address)},
{"reverseAddress", fmt.Sprintf("%d\n%d", address, address)},
{"lockedBalances", fmt.Sprintf("%v\n%v", lockedBalance, lockedBalance)},
{"accsum", fmt.Sprintf("%v\n%v", accSummary, accSummary)},
{"other", ""},
}

for i, tt := range tests {
i, tt := i, tt
t.Run(tt.name, func(t *testing.T) {
switch i {
case len(tests) - 1:
require.Panics(t, func() { dec(kvPairs.Pairs[i], kvPairs.Pairs[i]) }, tt.name)
default:
require.Equal(t, tt.expectedLog, dec(kvPairs.Pairs[i], kvPairs.Pairs[i]), tt.name)
}
})
}
}
5 changes: 5 additions & 0 deletions x/subaccount/simulation/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package simulation

const (
errTextInvalidHouseKey = "invalid house key %X"
)
57 changes: 57 additions & 0 deletions x/subaccount/simulation/genesis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package simulation

// DONTCOVER

import (
"encoding/json"
//#nosec
"math/rand"

"github.com/spf13/cast"

sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"

"github.com/sge-network/sge/x/subaccount/types"
)

// Simulation parameter constants
const (
HouseParticipationFee = "HouseParticipationFee"
MinDeposit = "MinDeposit"
)

// GenHouseParticipationFee randomized batch settlement count
func GenHouseParticipationFee(r *rand.Rand) sdk.Dec {
return sdk.NewDec(cast.ToInt64(r.Intn(99)))
}

// GenMinDeposit randomized house by uid query count
func GenMinDeposit(r *rand.Rand) sdkmath.Int {
return sdkmath.NewInt(cast.ToInt64(r.Intn(99)))
}

// RandomizedGenState generates a random GenesisState for house
func RandomizedGenState(simState *module.SimulationState) {
var houseParticipationFee sdk.Dec
simState.AppParams.GetOrGenerate(
simState.Cdc, HouseParticipationFee, &houseParticipationFee, simState.Rand,
func(r *rand.Rand) { houseParticipationFee = GenHouseParticipationFee(r) },
)

var minDeposit sdkmath.Int
simState.AppParams.GetOrGenerate(
simState.Cdc, MinDeposit, &minDeposit, simState.Rand,
func(r *rand.Rand) { minDeposit = GenMinDeposit(r) },
)

defaultGenesis := types.DefaultGenesis()

_, err := json.MarshalIndent(&defaultGenesis, "", " ")
if err != nil {
panic(err)
}

simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(defaultGenesis)
}
73 changes: 73 additions & 0 deletions x/subaccount/simulation/genesis_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package simulation_test

import (
"encoding/json"
//#nosec
"math/rand"
"testing"

"github.com/stretchr/testify/require"

sdkmath "cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/types/module"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"

"github.com/sge-network/sge/x/subaccount/simulation"
"github.com/sge-network/sge/x/subaccount/types"
)

// TestRandomizedGenState tests the normal scenario of applying RandomizedGenState.
// Abnormal scenarios are not tested here.
func TestRandomizedGenState(t *testing.T) {
interfaceRegistry := codectypes.NewInterfaceRegistry()
cdc := codec.NewProtoCodec(interfaceRegistry)

s := rand.NewSource(1)
//#nosec
r := rand.New(s)

simState := module.SimulationState{
AppParams: make(simtypes.AppParams),
Cdc: cdc,
Rand: r,
NumBonded: 3,
Accounts: simtypes.RandomAccounts(r, 3),
InitialStake: sdkmath.NewInt(1000),
GenState: make(map[string]json.RawMessage),
}

simulation.RandomizedGenState(&simState)

var houseGenesis types.GenesisState
simState.Cdc.MustUnmarshalJSON(simState.GenState[types.ModuleName], &houseGenesis)
}

// TestRandomizedGenState tests abnormal scenarios of applying RandomizedGenState.
func TestRandomizedGenState1(t *testing.T) {
interfaceRegistry := codectypes.NewInterfaceRegistry()
cdc := codec.NewProtoCodec(interfaceRegistry)

s := rand.NewSource(1)
//#nosec
r := rand.New(s)
// all these tests will panic
tests := []struct {
simState module.SimulationState
panicMsg string
}{
{ // panic => reason: incomplete initialization of the simState
module.SimulationState{}, "invalid memory address or nil pointer dereference"},
{ // panic => reason: incomplete initialization of the simState
module.SimulationState{
AppParams: make(simtypes.AppParams),
Cdc: cdc,
Rand: r,
}, "assignment to entry in nil map"},
}

for _, tt := range tests {
require.Panicsf(t, func() { simulation.RandomizedGenState(&tt.simState) }, tt.panicMsg)
}
}
15 changes: 15 additions & 0 deletions x/subaccount/simulation/simap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package simulation

import (
sdk "github.com/cosmos/cosmos-sdk/types"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
)

// FindAccount find a specific address from an account list
func FindAccount(accs []simtypes.Account, address string) (simtypes.Account, bool) {
creator, err := sdk.AccAddressFromBech32(address)
if err != nil {
panic(err)
}
return simtypes.FindAccount(accs, creator)
}
1 change: 1 addition & 0 deletions x/subaccount/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ var (
ErrSubaccountDoesNotExist = sdkerrors.Register(ModuleName, 3, "sub account does not exist")
ErrNothingToWithdraw = sdkerrors.Register(ModuleName, 4, "nothing to withdraw")
ErrInvalidLockedBalance = sdkerrors.Register(ModuleName, 5, "invalid locked balance")
ErrSendCoinError = sdkerrors.Register(ModuleName, 6, "send coin error")
)
8 changes: 4 additions & 4 deletions x/subaccount/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ var (
// LockedBalancePrefix is the key used to store the locked balance in the keeper KVStore
LockedBalancePrefix = []byte{0x03}

// BalancePrefix saves the balance of an account.
BalancePrefix = []byte{0x04}
// AccountSummaryPrefix saves the balance of an account.
AccountSummaryPrefix = []byte{0x04}
)

func SubAccountOwnerKey(address sdk.AccAddress) []byte {
Expand All @@ -55,6 +55,6 @@ func LockedBalancePrefixKey(subAccountAddress sdk.AccAddress) []byte {
return append(LockedBalancePrefix, address.MustLengthPrefix(subAccountAddress)...)
}

func BalanceKey(address sdk.AccAddress) []byte {
return append(BalancePrefix, address.Bytes()...)
func AccountSummaryKey(address sdk.AccAddress) []byte {
return append(AccountSummaryPrefix, address.Bytes()...)
}
Loading