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

[backports]: v0.40.0-rc2 Cherry-picks #7734

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0fc0b34
shutdown gracefully without os.Exit (#7480)
yihuang Oct 14, 2020
1db641d
Remove ClientType func and update consensus state path (#7573)
colin-axner Oct 19, 2020
95f4fc8
Refactor x/staking Validation and Delegation tests based on MsgCreate…
robert-zaremba Oct 19, 2020
2bc7fa8
fix sequence checks in solomachine (#7586)
bluele Oct 19, 2020
eab96fe
Bugfix gov votes querier to use votes params (#7589)
yun-yeo Oct 20, 2020
64c8cf7
Use InterfaceRegistry as AnyResolver for grpc-gateway (#7646)
aaronc Oct 23, 2020
d7dded3
Use any as validator pubkey (#7597)
robert-zaremba Oct 23, 2020
d488a18
Fix IBC Query cmds (#7648)
colin-axner Oct 23, 2020
c0ae5c9
IBC: panic on GetSignBytes and remove SubModuleCdc (#7645)
colin-axner Oct 23, 2020
e715a91
Return an unsigned tx in legacy GET /tx endpoint when signature conve…
aaronc Oct 23, 2020
4c4e255
Create separate Write-Ack Event (#7683)
AdityaSripal Oct 27, 2020
d5c6011
Wrap ProtoCodec in interface (#7637)
jackzampolin Oct 27, 2020
7d0c0be
ibc: refactor proto files (#7689)
fedekunze Oct 27, 2020
2e52ba2
simapp: rename MakeEncodingConfig to MakeTestEncodingConfig (#7681)
robert-zaremba Oct 27, 2020
cd21a47
Fix Optimistic Channel Handshake bugs (#7678)
colin-axner Oct 27, 2020
564687d
update core IBC docs (#7560)
colin-axner Oct 27, 2020
48fb155
ibc: Connection Version changed from string to proto definition (#7644)
fedekunze Oct 28, 2020
acc4d46
Rename RegisterGRPCRoutes (#7696)
anilcse Oct 28, 2020
7f275d5
docs: Basic/App-anatomy explains Msg Service by default (#7670)
amaury1093 Oct 28, 2020
9c64301
Fix panic in context when setting nodeURI (#7699)
colin-axner Oct 28, 2020
9d35a32
init: Implement ADR 032 typed events (#7564)
akhilkumarpilli Oct 28, 2020
ca621d3
msg_service_router: reduce code complexity (#7570)
robert-zaremba Oct 16, 2020
f33dced
RegisterInterfaces registers service Msg type_urls (#7671)
amaury1093 Oct 28, 2020
5a46012
Sort validators like tendermint in HistoricalInfo (#7691)
AdityaSripal Oct 29, 2020
e1c7d02
Add Deprecation headers for legacy rest endpoints (#7686)
clevinson Oct 29, 2020
c06a2a4
remove proof path from IBC queries (#7725)
colin-axner Oct 29, 2020
6ae3a94
Throw an error on duplicate registration (#7729)
amaury1093 Oct 29, 2020
778c37b
Add function to query ack proofs (#7732)
jackzampolin Oct 29, 2020
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
11 changes: 9 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ Ref: https://keepachangelog.com/en/1.0.0/
### API Breaking

* (AppModule) [\#7518](https://github.com/cosmos/cosmos-sdk/pull/7518) [\#7584](https://github.com/cosmos/cosmos-sdk/pull/7584) Rename `AppModule.RegisterQueryServices` to `AppModule.RegisterServices`, as this method now registers multiple services (the gRPC query service and the protobuf Msg service). A `Configurator` struct is used to hold the different services.
* (x/staking/types) [\#7447](https://github.com/cosmos/cosmos-sdk/issues/7447) Remove bech32 PubKey support:
* `ValidatorI` interface update. `GetConsPubKey` renamed to `TmConsPubKey` (consensus public key must be a tendermint key). `TmConsPubKey`, `GetConsAddr` methods return error.
* `Validator` update. Methods changed in `ValidatorI` (as described above) and `ToTmValidator` return error.
* `Validator.ConsensusPubkey` type changed from `string` to `codectypes.Any`.
* `MsgCreateValidator.Pubkey` type changed from `string` to `codectypes.Any`.
* Deprecating and renaming `MakeEncodingConfig` to `MakeTestEncodingConfig` (both in `simapp` and `simapp/params` packages).

### Features

Expand All @@ -68,6 +74,7 @@ define a `Msg` protobuf service.
### Bug Fixes

* (kvstore) [\#7415](https://github.com/cosmos/cosmos-sdk/pull/7415) Allow new stores to be registered during on-chain upgrades.
* (client) [\#7699](https://github.com/cosmos/cosmos-sdk/pull/7699) Fix panic in context when setting invalid nodeURI. `WithNodeURI` does not set the `Client` in the context.

### Improvements

Expand Down Expand Up @@ -184,7 +191,7 @@ of the Cosmos SDK since launch. Please read through this changelog and [release
* `NewAnteHandler` and `NewSigVerificationDecorator` both now take a `SignModeHandler` parameter.
* `SignatureVerificationGasConsumer` now has the signature: `func(meter sdk.GasMeter, sig signing.SignatureV2, params types.Params) error`.
* The `SigVerifiableTx` interface now has a `GetSignaturesV2() ([]signing.SignatureV2, error)` method and no longer has the `GetSignBytes` method.

### State Machine Breaking

* __General__
Expand Down Expand Up @@ -377,7 +384,7 @@ falling below their minimum self-delegation and never having been bonded. The va

* (x/auth) [\#6861](https://github.com/cosmos/cosmos-sdk/pull/6861) Remove public key Bech32 encoding for all account types for JSON serialization, instead relying on direct Amino encoding. In addition, JSON serialization utilizes Amino instead of the Go stdlib, so integers are treated as strings.

### Improvements
### Improvements

* (client) [\#6853](https://github.com/cosmos/cosmos-sdk/pull/6853) Add --unsafe-cors flag.

Expand Down
20 changes: 19 additions & 1 deletion baseapp/grpcrouter.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,31 @@ func (qrt *GRPCQueryRouter) Route(path string) GRPCQueryHandler {
}

// RegisterService implements the gRPC Server.RegisterService method. sd is a gRPC
// service description, handler is an object which implements that gRPC service
// service description, handler is an object which implements that gRPC service/
//
// This functions PANICS:
// - if a protobuf service is registered twice.
func (qrt *GRPCQueryRouter) RegisterService(sd *grpc.ServiceDesc, handler interface{}) {
// adds a top-level query handler based on the gRPC service name
for _, method := range sd.Methods {
fqName := fmt.Sprintf("/%s/%s", sd.ServiceName, method.MethodName)
methodHandler := method.Handler

// Check that each service is only registered once. If a service is
// registered more than once, then we should error. Since we can't
// return an error (`Server.RegisterService` interface restriction) we
// panic (at startup).
_, found := qrt.routes[fqName]
if found {
panic(
fmt.Errorf(
"gRPC query service %s has already been registered. Please make sure to only register each service once. "+
"This usually means that there are conflicting modules registering the same gRPC query service",
fqName,
),
)
}

qrt.routes[fqName] = func(ctx sdk.Context, req abci.RequestQuery) (abci.ResponseQuery, error) {
// call the method handler from the service description with the handler object,
// a wrapped sdk.Context with proto-unmarshaled data from the ABCI request data
Expand Down
6 changes: 3 additions & 3 deletions baseapp/grpcrouter_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
// service client.
type QueryServiceTestHelper struct {
*GRPCQueryRouter
ctx sdk.Context
Ctx sdk.Context
}

var (
Expand All @@ -31,7 +31,7 @@ var (
func NewQueryServerTestHelper(ctx sdk.Context, interfaceRegistry types.InterfaceRegistry) *QueryServiceTestHelper {
qrt := NewGRPCQueryRouter()
qrt.SetInterfaceRegistry(interfaceRegistry)
return &QueryServiceTestHelper{GRPCQueryRouter: qrt, ctx: ctx}
return &QueryServiceTestHelper{GRPCQueryRouter: qrt, Ctx: ctx}
}

// Invoke implements the grpc ClientConn.Invoke method
Expand All @@ -45,7 +45,7 @@ func (q *QueryServiceTestHelper) Invoke(_ gocontext.Context, method string, args
return err
}

res, err := querier(q.ctx, abci.RequestQuery{Data: reqBz})
res, err := querier(q.Ctx, abci.RequestQuery{Data: reqBz})
if err != nil {
return err
}
Expand Down
38 changes: 34 additions & 4 deletions baseapp/grpcrouter_test.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
package baseapp
package baseapp_test

import (
"context"
"os"
"testing"

"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/log"
dbm "github.com/tendermint/tm-db"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
)

func TestGRPCRouter(t *testing.T) {
qr := NewGRPCQueryRouter()
qr := baseapp.NewGRPCQueryRouter()
interfaceRegistry := testdata.NewTestInterfaceRegistry()
qr.SetInterfaceRegistry(interfaceRegistry)
testdata.RegisterQueryServer(qr, testdata.QueryImpl{})
helper := &QueryServiceTestHelper{
helper := &baseapp.QueryServiceTestHelper{
GRPCQueryRouter: qr,
ctx: sdk.Context{}.WithContext(context.Background()),
Ctx: sdk.Context{}.WithContext(context.Background()),
}
client := testdata.NewQueryClient(helper)

Expand All @@ -44,3 +49,28 @@ func TestGRPCRouter(t *testing.T) {
require.NotNil(t, res3)
require.Equal(t, spot, res3.HasAnimal.Animal.GetCachedValue())
}

func TestRegisterQueryServiceTwice(t *testing.T) {
// Setup baseapp.
db := dbm.NewMemDB()
encCfg := simapp.MakeTestEncodingConfig()
app := baseapp.NewBaseApp("test", log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, encCfg.TxConfig.TxDecoder())
app.SetInterfaceRegistry(encCfg.InterfaceRegistry)
testdata.RegisterInterfaces(encCfg.InterfaceRegistry)

// First time registering service shouldn't panic.
require.NotPanics(t, func() {
testdata.RegisterQueryServer(
app.GRPCQueryRouter(),
testdata.QueryImpl{},
)
})

// Second time should panic.
require.Panics(t, func() {
testdata.RegisterQueryServer(
app.GRPCQueryRouter(),
testdata.QueryImpl{},
)
})
}
72 changes: 46 additions & 26 deletions baseapp/msg_service_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import (
"context"
"fmt"

"github.com/gogo/protobuf/proto"

gogogrpc "github.com/gogo/protobuf/grpc"
"github.com/gogo/protobuf/proto"
"google.golang.org/grpc"

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// MsgServiceRouter routes fully-qualified Msg service methods to their handler.
Expand Down Expand Up @@ -39,48 +39,66 @@ func (msr *MsgServiceRouter) Handler(methodName string) MsgServiceHandler {

// RegisterService implements the gRPC Server.RegisterService method. sd is a gRPC
// service description, handler is an object which implements that gRPC service.
//
// This function PANICs:
// - if it is called before the service `Msg`s have been registered using
// RegisterInterfaces,
// - or if a service is being registered twice.
func (msr *MsgServiceRouter) RegisterService(sd *grpc.ServiceDesc, handler interface{}) {
// Adds a top-level query handler based on the gRPC service name.
for _, method := range sd.Methods {
fqMethod := fmt.Sprintf("/%s/%s", sd.ServiceName, method.MethodName)
methodHandler := method.Handler

// NOTE: This is how we pull the concrete request type for each handler for registering in the InterfaceRegistry.
// This approach is maybe a bit hacky, but less hacky than reflecting on the handler object itself.
// We use a no-op interceptor to avoid actually calling into the handler itself.
_, _ = methodHandler(nil, context.Background(), func(i interface{}) error {
msg, ok := i.(proto.Message)
if !ok {
// We panic here because there is no other alternative and the app cannot be initialized correctly
// this should only happen if there is a problem with code generation in which case the app won't
// work correctly anyway.
panic(fmt.Errorf("can't register request type %T for service method %s", i, fqMethod))
}
// Check that the service Msg fully-qualified method name has already
// been registered (via RegisterInterfaces). If the user registers a
// service without registering according service Msg type, there might be
// some unexpected behavior down the road. Since we can't return an error
// (`Server.RegisterService` interface restriction) we panic (at startup).
serviceMsg, err := msr.interfaceRegistry.Resolve(fqMethod)
if err != nil || serviceMsg == nil {
panic(
fmt.Errorf(
"type_url %s has not been registered yet. "+
"Before calling RegisterService, you must register all interfaces by calling the `RegisterInterfaces` "+
"method on module.BasicManager. Each module should call `msgservice.RegisterMsgServiceDesc` inside its "+
"`RegisterInterfaces` method with the `_Msg_serviceDesc` generated by proto-gen",
fqMethod,
),
)
}

msr.interfaceRegistry.RegisterCustomTypeURL((*sdk.MsgRequest)(nil), fqMethod, msg)
return nil
}, func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
return nil, nil
})
// Check that each service is only registered once. If a service is
// registered more than once, then we should error. Since we can't
// return an error (`Server.RegisterService` interface restriction) we
// panic (at startup).
_, found := msr.routes[fqMethod]
if found {
panic(
fmt.Errorf(
"msg service %s has already been registered. Please make sure to only register each service once. "+
"This usually means that there are conflicting modules registering the same msg service",
fqMethod,
),
)
}

msr.routes[fqMethod] = func(ctx sdk.Context, req sdk.MsgRequest) (*sdk.Result, error) {
ctx = ctx.WithEventManager(sdk.NewEventManager())

// Call the method handler from the service description with the handler object.
res, err := methodHandler(handler, sdk.WrapSDKContext(ctx), func(_ interface{}) error {
// We don't do any decoding here because the decoding was already done.
return nil
}, func(goCtx context.Context, _ interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
interceptor := func(goCtx context.Context, _ interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
goCtx = context.WithValue(goCtx, sdk.SdkContextKey, ctx)
return handler(goCtx, req)
})
}
// Call the method handler from the service description with the handler object.
// We don't do any decoding here because the decoding was already done.
res, err := methodHandler(handler, sdk.WrapSDKContext(ctx), noopDecoder, interceptor)
if err != nil {
return nil, err
}

resMsg, ok := res.(proto.Message)
if !ok {
return nil, fmt.Errorf("can't proto encode %T", resMsg)
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "Expecting proto.Message, got %T", resMsg)
}

return sdk.WrapServiceResult(ctx, resMsg, err)
Expand All @@ -92,3 +110,5 @@ func (msr *MsgServiceRouter) RegisterService(sd *grpc.ServiceDesc, handler inter
func (msr *MsgServiceRouter) SetInterfaceRegistry(interfaceRegistry codectypes.InterfaceRegistry) {
msr.interfaceRegistry = interfaceRegistry
}

func noopDecoder(_ interface{}) error { return nil }
58 changes: 53 additions & 5 deletions baseapp/msg_service_router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,73 @@ import (
"os"
"testing"

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

tmproto "github.com/tendermint/tendermint/proto/tendermint/types"

"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
dbm "github.com/tendermint/tm-db"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
)

func TestRegisterMsgService(t *testing.T) {
db := dbm.NewMemDB()

// Create an encoding config that doesn't register testdata Msg services.
encCfg := simapp.MakeTestEncodingConfig()
app := baseapp.NewBaseApp("test", log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, encCfg.TxConfig.TxDecoder())
app.SetInterfaceRegistry(encCfg.InterfaceRegistry)
require.Panics(t, func() {
testdata.RegisterMsgServer(
app.MsgServiceRouter(),
testdata.MsgServerImpl{},
)
})

// Register testdata Msg services, and rerun `RegisterService`.
testdata.RegisterInterfaces(encCfg.InterfaceRegistry)
require.NotPanics(t, func() {
testdata.RegisterMsgServer(
app.MsgServiceRouter(),
testdata.MsgServerImpl{},
)
})
}

func TestRegisterMsgServiceTwice(t *testing.T) {
// Setup baseapp.
db := dbm.NewMemDB()
encCfg := simapp.MakeTestEncodingConfig()
app := baseapp.NewBaseApp("test", log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, encCfg.TxConfig.TxDecoder())
app.SetInterfaceRegistry(encCfg.InterfaceRegistry)
testdata.RegisterInterfaces(encCfg.InterfaceRegistry)

// First time registering service shouldn't panic.
require.NotPanics(t, func() {
testdata.RegisterMsgServer(
app.MsgServiceRouter(),
testdata.MsgServerImpl{},
)
})

// Second time should panic.
require.Panics(t, func() {
testdata.RegisterMsgServer(
app.MsgServiceRouter(),
testdata.MsgServerImpl{},
)
})
}

func TestMsgService(t *testing.T) {
priv, _, _ := testdata.KeyTestPubAddr()
encCfg := simapp.MakeEncodingConfig()
encCfg := simapp.MakeTestEncodingConfig()
testdata.RegisterInterfaces(encCfg.InterfaceRegistry)
db := dbm.NewMemDB()
app := baseapp.NewBaseApp("test", log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, encCfg.TxConfig.TxDecoder())
app.SetInterfaceRegistry(encCfg.InterfaceRegistry)
Expand Down
8 changes: 8 additions & 0 deletions client/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/tendermint/tendermint/libs/cli"
rpchttp "github.com/tendermint/tendermint/rpc/client/http"

"github.com/cosmos/cosmos-sdk/client/flags"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -131,6 +132,13 @@ func ReadPersistentCommandFlags(clientCtx Context, flagSet *pflag.FlagSet) (Cont
rpcURI, _ := flagSet.GetString(flags.FlagNode)
if rpcURI != "" {
clientCtx = clientCtx.WithNodeURI(rpcURI)

client, err := rpchttp.New(rpcURI, "/websocket")
if err != nil {
return clientCtx, err
}

clientCtx = clientCtx.WithClient(client)
}
}

Expand Down
7 changes: 0 additions & 7 deletions client/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/gogo/protobuf/proto"
"github.com/pkg/errors"
rpcclient "github.com/tendermint/tendermint/rpc/client"
rpchttp "github.com/tendermint/tendermint/rpc/client/http"

"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
Expand Down Expand Up @@ -95,12 +94,6 @@ func (ctx Context) WithOutputFormat(format string) Context {
// WithNodeURI returns a copy of the context with an updated node URI.
func (ctx Context) WithNodeURI(nodeURI string) Context {
ctx.NodeURI = nodeURI
client, err := rpchttp.New(nodeURI, "/websocket")
if err != nil {
panic(err)
}

ctx.Client = client
return ctx
}

Expand Down
Loading