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

feat: add genmsg module #1495

Merged
merged 20 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from 17 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* [#1500](https://github.com/NibiruChain/nibiru/pull/1500) - refactor(perp): clean up reverse market order mechanics
* [#1506](https://github.com/NibiruChain/nibiru/pull/1506) - refactor(oracle): Implement OrderedMap and use it for iterating through maps in x/oracle
* [#1502](https://github.com/NibiruChain/nibiru/pull/1502) - feat: add ledger build support
* [#1495](https://github.com/NibiruChain/nibiru/pull/1495) - feat: add genmsg module
* [#1517](https://github.com/NibiruChain/nibiru/pull/1517) - test: add more tests to x/hooks
* [#1518](https://github.com/NibiruChain/nibiru/pull/1518) - test: add more tests to x/perp

Expand Down
8 changes: 3 additions & 5 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"os"
"path/filepath"

"github.com/NibiruChain/nibiru/x/genmsg"

"github.com/NibiruChain/nibiru/x/sudo/keeper"

sudotypes "github.com/NibiruChain/nibiru/x/sudo/types"
Expand Down Expand Up @@ -123,11 +125,6 @@ const (
DisplayDenom = "NIBI"
)

// IBC application testing ports
const (
MockFeePort string = ibcmock.ModuleName + ibcfeetypes.ModuleName
)

var (
// DefaultNodeHome default home directories for the application daemon
DefaultNodeHome string
Expand Down Expand Up @@ -172,6 +169,7 @@ var (
sudo.AppModuleBasic{},
wasm.AppModuleBasic{},
ibcfee.AppModuleBasic{},
genmsg.AppModule{},
)

// module account permissions
Expand Down
7 changes: 7 additions & 0 deletions app/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package app
import (
"path/filepath"

"github.com/NibiruChain/nibiru/x/genmsg"

"github.com/NibiruChain/nibiru/x/sudo/keeper"

sudotypes "github.com/NibiruChain/nibiru/x/sudo/types"
Expand Down Expand Up @@ -490,6 +492,7 @@ func (app *NibiruApp) AppModules(
app.InflationKeeper, app.AccountKeeper, *app.stakingKeeper,
)
sudoModule := sudo.NewAppModule(appCodec, app.SudoKeeper)
genMsgModule := genmsg.NewAppModule(app.MsgServiceRouter())

return []module.AppModule{
genutil.NewAppModule(
Expand Down Expand Up @@ -519,6 +522,7 @@ func (app *NibiruApp) AppModules(
inflationModule,
sudoModule,
perpv2Module,
genMsgModule,

// ibc
evidence.NewAppModule(app.evidenceKeeper),
Expand Down Expand Up @@ -587,6 +591,9 @@ func OrderedModuleNames() []string {
// --------------------------------------------------------------------
// CosmWasm
wasm.ModuleName,

// Should be before genmsg
genmsg.ModuleName,
}
}

Expand Down
2 changes: 2 additions & 0 deletions contrib/make/post-genesis.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
post-genesis:
./contrib/scripts/post-genesis.sh
jgimeno marked this conversation as resolved.
Show resolved Hide resolved
11 changes: 6 additions & 5 deletions contrib/scripts/localnet.sh
Original file line number Diff line number Diff line change
Expand Up @@ -281,12 +281,13 @@ else
fi

# set validator as sudoer
$BINARY genesis add-sudo-root-account "$val_address"
add_genesis_param '.app_state.sudo.sudoers.root = "'"$val_address"'"'

# set local oracle params
add_genesis_param '.app_state.oracle.params.twap_lookback_window = "900s"'
add_genesis_param '.app_state.oracle.params.vote_period = "10"'
add_genesis_param '.app_state.oracle.params.min_voters = "1"'
# hack for localnet since we don't have a pricefeeder yet
add_genesis_param '.app_state.oracle.exchange_rates[0].pair = "ubtc:unusd"'
add_genesis_param '.app_state.oracle.exchange_rates[0].exchange_rate = "'"$price_btc"'"'
add_genesis_param '.app_state.oracle.exchange_rates[1].pair = "ueth:unusd"'
add_genesis_param '.app_state.oracle.exchange_rates[1].exchange_rate = "'"$price_eth"'"'

# Start the network
echo_info "Starting $CHAIN_ID in $CHAIN_DIR..."
Expand Down
2 changes: 1 addition & 1 deletion x/epochs/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

// GetQueryCmd returns the cli query commands for this module.
func GetQueryCmd(queryRoute string) *cobra.Command {
func GetQueryCmd() *cobra.Command {
// Group epochs queries under a subcommand
cmd := &cobra.Command{
Use: types.ModuleName,
Expand Down
2 changes: 1 addition & 1 deletion x/epochs/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func (a AppModuleBasic) GetTxCmd() *cobra.Command {

// GetQueryCmd returns the capability module's root query command.
func (AppModuleBasic) GetQueryCmd() *cobra.Command {
return cli.GetQueryCmd(types.StoreKey)
return cli.GetQueryCmd()
}

// ----------------------------------------------------------------------------
Expand Down
69 changes: 69 additions & 0 deletions x/genmsg/genesis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package genmsg

import (
"fmt"

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

v1 "github.com/NibiruChain/nibiru/x/genmsg/v1"
)

func anyToMsg(ir types.InterfaceRegistry, anyMsg *types.Any) (sdk.Msg, error) {
var sdkMsg sdk.Msg
err := ir.UnpackAny(anyMsg, &sdkMsg)
if err != nil {
return nil, err
}
if err = sdkMsg.ValidateBasic(); err != nil {
return nil, err
}
return sdkMsg, nil
}

func validateGenesis(cdc codec.JSONCodec, genesis *v1.GenesisState) error {
interfaceRegistryProvider, ok := cdc.(interface {
InterfaceRegistry() types.InterfaceRegistry
})
if !ok {
return fmt.Errorf("codec does not implement InterfaceRegistry")
}
interfaceRegistry := interfaceRegistryProvider.InterfaceRegistry()
// check if all messages are known by the codec
for i, anyMsg := range genesis.Messages {
if _, err := anyToMsg(interfaceRegistry, anyMsg); err != nil {
return fmt.Errorf("at index %d: %w", i, err)
}
}
return nil
}

func initGenesis(context sdk.Context, cdc codec.JSONCodec, router MessageRouter, genesis *v1.GenesisState) error {
interfaceRegistryProvider, ok := cdc.(interface {
InterfaceRegistry() types.InterfaceRegistry
})
if !ok {
return fmt.Errorf("codec does not implement InterfaceRegistry")
}
interfaceRegistry := interfaceRegistryProvider.InterfaceRegistry()

// execute all messages in order
for i, anyMsg := range genesis.Messages {
msg, err := anyToMsg(interfaceRegistry, anyMsg)
if err != nil {
return fmt.Errorf("at index %d: message decoding: %w", i, err)
}
handler := router.Handler(msg)
if handler == nil {
return fmt.Errorf("at index %d: no handler for message %T %s", i, msg, msg)
}
// resp, err := handler(context, msg)
_, err = handler(context, msg)
if err != nil {
return fmt.Errorf("at index %d: message processing: %w", i, err)
}
// log.Printf("message %d processed %s: %s", i, msg, resp.String())
jgimeno marked this conversation as resolved.
Show resolved Hide resolved
}
return nil
}
111 changes: 111 additions & 0 deletions x/genmsg/genesis_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package genmsg

import (
"testing"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/require"

v1 "github.com/NibiruChain/nibiru/x/genmsg/v1"
)

type mockRouter struct {
handler func(msg sdk.Msg) baseapp.MsgServiceHandler
}

func (m mockRouter) Handler(msg sdk.Msg) baseapp.MsgServiceHandler { return m.handler(msg) }

func makeCodec(_ *testing.T) codec.JSONCodec {
ir := types.NewInterfaceRegistry()
cdc := codec.NewProtoCodec(ir)
ir.RegisterInterface(sdk.MsgInterfaceProtoName, (*sdk.Msg)(nil), &banktypes.MsgSend{})
return cdc
}

func newGenesisFromMsgs(t *testing.T, cdc codec.JSONCodec, msgs ...proto.Message) *v1.GenesisState {
genesis := new(v1.GenesisState)
for _, msg := range msgs {
anyProto, err := types.NewAnyWithValue(msg)
require.NoError(t, err)
genesis.Messages = append(genesis.Messages, anyProto)
}
genesisJSON, err := cdc.MarshalJSON(genesis)
require.NoError(t, err)
genesis = new(v1.GenesisState)
require.NoError(t, cdc.UnmarshalJSON(genesisJSON, genesis))
return genesis
}

func Test_initGenesis(t *testing.T) {
cdc := makeCodec(t)
ctx := sdk.Context{}

t.Run("works - no msgs", func(t *testing.T) {
r := mockRouter{func(msg sdk.Msg) baseapp.MsgServiceHandler {
return func(ctx sdk.Context, req sdk.Msg) (*sdk.Result, error) {
return &sdk.Result{}, nil
}
}}

err := initGenesis(ctx, cdc, r, newGenesisFromMsgs(t, cdc))
require.NoError(t, err)
})

t.Run("works - with message", func(t *testing.T) {
called := false
r := mockRouter{func(msg sdk.Msg) baseapp.MsgServiceHandler {
return func(ctx sdk.Context, req sdk.Msg) (*sdk.Result, error) {
called = true
return &sdk.Result{}, nil
}
}}

err := initGenesis(ctx, cdc, r, newGenesisFromMsgs(t, cdc, &banktypes.MsgSend{
FromAddress: sdk.AccAddress("a").String(),
ToAddress: sdk.AccAddress("b").String(),
Amount: sdk.NewCoins(sdk.NewInt64Coin("test", 1000)),
}))
require.NoError(t, err)
require.True(t, called)
})

t.Run("fails - handler is nil", func(t *testing.T) {
r := mockRouter{func(msg sdk.Msg) baseapp.MsgServiceHandler {
return nil
}}

err := initGenesis(ctx, cdc, r, newGenesisFromMsgs(t, cdc, &banktypes.MsgSend{
FromAddress: sdk.AccAddress("a").String(),
ToAddress: sdk.AccAddress("b").String(),
Amount: sdk.NewCoins(sdk.NewInt64Coin("test", 1000)),
}))
require.Error(t, err)
})
}

func Test_validateGenesis(t *testing.T) {
cdc := makeCodec(t)
t.Run("works - empty", func(t *testing.T) {
err := validateGenesis(cdc, &v1.GenesisState{})
require.NoError(t, err)
})
t.Run("works - with messages", func(t *testing.T) {
genesis := newGenesisFromMsgs(t, cdc, &banktypes.MsgSend{
FromAddress: sdk.AccAddress("sender").String(),
ToAddress: sdk.AccAddress("receiver").String(),
Amount: sdk.NewCoins(sdk.NewInt64Coin("test", 1000)),
})
err := validateGenesis(cdc, genesis)
require.NoError(t, err)
})
t.Run("fails - validate basic", func(t *testing.T) {
genesis := newGenesisFromMsgs(t, cdc, &banktypes.MsgSend{})
err := validateGenesis(cdc, genesis)
require.Error(t, err)
})
}
27 changes: 27 additions & 0 deletions x/genmsg/integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package genmsg_test

import (
"testing"
)

func TestIntegration(t *testing.T) {
//recvAddr := sdk.AccAddress("recv")
jgimeno marked this conversation as resolved.
Show resolved Hide resolved
//chain := e2eTesting.NewTestChain(t, 1, e2eTesting.WithDummyTestAddress(), e2eTesting.WithGenDefaultCoinBalance("100000000000000000000000000000000000"), e2eTesting.TestChainGenesisOption(func(cdc codec.Codec, genesis app.GenesisState) {
// testMsg := &banktypes.MsgSend{
// FromAddress: e2eTesting.TestAccountAddr.String(),
// ToAddress: recvAddr.String(),
// Amount: sdk.NewCoins(sdk.NewInt64Coin("stake", 1000)),
// }
// anyMsg, err := codectypes.NewAnyWithValue(testMsg)
// require.NoError(t, err)
// genesis[genmsg.ModuleName] = cdc.MustMarshalJSON(&v1.GenesisState{Messages: []*codectypes.Any{anyMsg}})
//}))
//bankQuery := banktypes.NewQueryClient(chain.Client())
//resp, err := bankQuery.Balance(sdk.WrapSDKContext(chain.GetContext()), &banktypes.QueryBalanceRequest{
// Address: recvAddr.String(),
// Denom: "stake",
//})
//
//require.NoError(t, err)
//t.Log(resp)
}
Loading
Loading