From f0db0ff26010d1192b5bd6a257d1dbbf196eff61 Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Thu, 21 Apr 2022 12:21:11 -0400 Subject: [PATCH] abci: streamline grpc application construction (#8383) In my mind this is "don't make grpc any weirder than it has to be." We definitely don't need to export this type: if you're using gRPC for ABCI you *probably* don't want to also depend on the huge swath of the code that The ideal case is you generate the proto yourself, standup a gRPC service on your own (presumably because your application has other gRPC services that you want to expose,) and then your application doesn't need to interact with the types package at all. This is definitely the case for anyone who uses gRPC and doesn't use Go (which is likely the predominant use case.) If you're using Go, and want to use tendermint's service runner for running your gRPC service, you can, but at this point (as before,) you're already importing the `types` package (and you were before,) I've just eliminated an intermediate type that you shouldn't need to think about. Reviewers: I think the change is pretty rote, but the logic/user-story above would definitely be better for being validated by someone other than me. :) --- abci/example/example_test.go | 4 +- abci/example/kvstore/kvstore_test.go | 3 +- abci/server/grpc_server.go | 91 +++++++++++++++++++++++- abci/server/server.go | 2 +- abci/types/application.go | 102 --------------------------- 5 files changed, 92 insertions(+), 110 deletions(-) diff --git a/abci/example/example_test.go b/abci/example/example_test.go index 9d9d1548f..6da090e9d 100644 --- a/abci/example/example_test.go +++ b/abci/example/example_test.go @@ -53,7 +53,7 @@ func TestGRPC(t *testing.T) { logger := log.NewNopLogger() t.Log("### Testing GRPC") - testGRPCSync(ctx, t, logger, types.NewGRPCApplication(types.NewBaseApplication())) + testGRPCSync(ctx, t, logger, types.NewBaseApplication()) } func testBulk(ctx context.Context, t *testing.T, logger log.Logger, app types.Application) { @@ -101,7 +101,7 @@ func dialerFunc(ctx context.Context, addr string) (net.Conn, error) { return tmnet.Connect(addr) } -func testGRPCSync(ctx context.Context, t *testing.T, logger log.Logger, app types.ABCIApplicationServer) { +func testGRPCSync(ctx context.Context, t *testing.T, logger log.Logger, app types.Application) { t.Helper() numDeliverTxs := 680000 socketFile := fmt.Sprintf("/tmp/test-%08x.sock", rand.Int31n(1<<30)) diff --git a/abci/example/kvstore/kvstore_test.go b/abci/example/kvstore/kvstore_test.go index 0b62bbc61..482e3d691 100644 --- a/abci/example/kvstore/kvstore_test.go +++ b/abci/example/kvstore/kvstore_test.go @@ -260,8 +260,7 @@ func makeGRPCClientServer( // Start the listener socket := fmt.Sprintf("unix://%s.sock", name) - gapp := types.NewGRPCApplication(app) - server := abciserver.NewGRPCServer(logger.With("module", "abci-server"), socket, gapp) + server := abciserver.NewGRPCServer(logger.With("module", "abci-server"), socket, app) if err := server.Start(ctx); err != nil { cancel() diff --git a/abci/server/grpc_server.go b/abci/server/grpc_server.go index c1446d17a..f3d454435 100644 --- a/abci/server/grpc_server.go +++ b/abci/server/grpc_server.go @@ -20,11 +20,11 @@ type GRPCServer struct { addr string server *grpc.Server - app types.ABCIApplicationServer + app types.Application } // NewGRPCServer returns a new gRPC ABCI server -func NewGRPCServer(logger log.Logger, protoAddr string, app types.ABCIApplicationServer) service.Service { +func NewGRPCServer(logger log.Logger, protoAddr string, app types.Application) service.Service { proto, addr := tmnet.ProtocolAndAddress(protoAddr) s := &GRPCServer{ logger: logger, @@ -44,7 +44,7 @@ func (s *GRPCServer) OnStart(ctx context.Context) error { } s.server = grpc.NewServer() - types.RegisterABCIApplicationServer(s.server, s.app) + types.RegisterABCIApplicationServer(s.server, &gRPCApplication{app: s.app}) s.logger.Info("Listening", "proto", s.proto, "addr", s.addr) go func() { @@ -62,3 +62,88 @@ func (s *GRPCServer) OnStart(ctx context.Context) error { // OnStop stops the gRPC server. func (s *GRPCServer) OnStop() { s.server.Stop() } + +//------------------------------------------------------- + +// gRPCApplication is a gRPC shim for Application +type gRPCApplication struct { + app types.Application +} + +func (app *gRPCApplication) Echo(_ context.Context, req *types.RequestEcho) (*types.ResponseEcho, error) { + return &types.ResponseEcho{Message: req.Message}, nil +} + +func (app *gRPCApplication) Flush(_ context.Context, req *types.RequestFlush) (*types.ResponseFlush, error) { + return &types.ResponseFlush{}, nil +} + +func (app *gRPCApplication) Info(_ context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) { + res := app.app.Info(*req) + return &res, nil +} + +func (app *gRPCApplication) CheckTx(_ context.Context, req *types.RequestCheckTx) (*types.ResponseCheckTx, error) { + res := app.app.CheckTx(*req) + return &res, nil +} + +func (app *gRPCApplication) Query(_ context.Context, req *types.RequestQuery) (*types.ResponseQuery, error) { + res := app.app.Query(*req) + return &res, nil +} + +func (app *gRPCApplication) Commit(_ context.Context, req *types.RequestCommit) (*types.ResponseCommit, error) { + res := app.app.Commit() + return &res, nil +} + +func (app *gRPCApplication) InitChain(_ context.Context, req *types.RequestInitChain) (*types.ResponseInitChain, error) { + res := app.app.InitChain(*req) + return &res, nil +} + +func (app *gRPCApplication) ListSnapshots(_ context.Context, req *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { + res := app.app.ListSnapshots(*req) + return &res, nil +} + +func (app *gRPCApplication) OfferSnapshot(_ context.Context, req *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { + res := app.app.OfferSnapshot(*req) + return &res, nil +} + +func (app *gRPCApplication) LoadSnapshotChunk(_ context.Context, req *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { + res := app.app.LoadSnapshotChunk(*req) + return &res, nil +} + +func (app *gRPCApplication) ApplySnapshotChunk(_ context.Context, req *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { + res := app.app.ApplySnapshotChunk(*req) + return &res, nil +} + +func (app *gRPCApplication) ExtendVote(_ context.Context, req *types.RequestExtendVote) (*types.ResponseExtendVote, error) { + res := app.app.ExtendVote(*req) + return &res, nil +} + +func (app *gRPCApplication) VerifyVoteExtension(_ context.Context, req *types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { + res := app.app.VerifyVoteExtension(*req) + return &res, nil +} + +func (app *gRPCApplication) PrepareProposal(_ context.Context, req *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { + res := app.app.PrepareProposal(*req) + return &res, nil +} + +func (app *gRPCApplication) ProcessProposal(_ context.Context, req *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { + res := app.app.ProcessProposal(*req) + return &res, nil +} + +func (app *gRPCApplication) FinalizeBlock(_ context.Context, req *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { + res := app.app.FinalizeBlock(*req) + return &res, nil +} diff --git a/abci/server/server.go b/abci/server/server.go index 2a6d50fd2..0e0173ca6 100644 --- a/abci/server/server.go +++ b/abci/server/server.go @@ -23,7 +23,7 @@ func NewServer(logger log.Logger, protoAddr, transport string, app types.Applica case "socket": s = NewSocketServer(logger, protoAddr, app) case "grpc": - s = NewGRPCServer(logger, protoAddr, types.NewGRPCApplication(app)) + s = NewGRPCServer(logger, protoAddr, app) default: err = fmt.Errorf("unknown server type %s", transport) } diff --git a/abci/types/application.go b/abci/types/application.go index 959311e3b..067c0cdba 100644 --- a/abci/types/application.go +++ b/abci/types/application.go @@ -1,9 +1,5 @@ package types -import ( - "context" -) - //go:generate ../../scripts/mockery_generate.sh Application // Application is an interface that enables any finite, deterministic state machine // to be driven by a blockchain-based replication engine via the ABCI. @@ -123,101 +119,3 @@ func (BaseApplication) FinalizeBlock(req RequestFinalizeBlock) ResponseFinalizeB TxResults: txs, } } - -//------------------------------------------------------- - -// GRPCApplication is a GRPC wrapper for Application -type GRPCApplication struct { - app Application -} - -func NewGRPCApplication(app Application) *GRPCApplication { - return &GRPCApplication{app} -} - -func (app *GRPCApplication) Echo(ctx context.Context, req *RequestEcho) (*ResponseEcho, error) { - return &ResponseEcho{Message: req.Message}, nil -} - -func (app *GRPCApplication) Flush(ctx context.Context, req *RequestFlush) (*ResponseFlush, error) { - return &ResponseFlush{}, nil -} - -func (app *GRPCApplication) Info(ctx context.Context, req *RequestInfo) (*ResponseInfo, error) { - res := app.app.Info(*req) - return &res, nil -} - -func (app *GRPCApplication) CheckTx(ctx context.Context, req *RequestCheckTx) (*ResponseCheckTx, error) { - res := app.app.CheckTx(*req) - return &res, nil -} - -func (app *GRPCApplication) Query(ctx context.Context, req *RequestQuery) (*ResponseQuery, error) { - res := app.app.Query(*req) - return &res, nil -} - -func (app *GRPCApplication) Commit(ctx context.Context, req *RequestCommit) (*ResponseCommit, error) { - res := app.app.Commit() - return &res, nil -} - -func (app *GRPCApplication) InitChain(ctx context.Context, req *RequestInitChain) (*ResponseInitChain, error) { - res := app.app.InitChain(*req) - return &res, nil -} - -func (app *GRPCApplication) ListSnapshots( - ctx context.Context, req *RequestListSnapshots) (*ResponseListSnapshots, error) { - res := app.app.ListSnapshots(*req) - return &res, nil -} - -func (app *GRPCApplication) OfferSnapshot( - ctx context.Context, req *RequestOfferSnapshot) (*ResponseOfferSnapshot, error) { - res := app.app.OfferSnapshot(*req) - return &res, nil -} - -func (app *GRPCApplication) LoadSnapshotChunk( - ctx context.Context, req *RequestLoadSnapshotChunk) (*ResponseLoadSnapshotChunk, error) { - res := app.app.LoadSnapshotChunk(*req) - return &res, nil -} - -func (app *GRPCApplication) ApplySnapshotChunk( - ctx context.Context, req *RequestApplySnapshotChunk) (*ResponseApplySnapshotChunk, error) { - res := app.app.ApplySnapshotChunk(*req) - return &res, nil -} - -func (app *GRPCApplication) ExtendVote( - ctx context.Context, req *RequestExtendVote) (*ResponseExtendVote, error) { - res := app.app.ExtendVote(*req) - return &res, nil -} - -func (app *GRPCApplication) VerifyVoteExtension( - ctx context.Context, req *RequestVerifyVoteExtension) (*ResponseVerifyVoteExtension, error) { - res := app.app.VerifyVoteExtension(*req) - return &res, nil -} - -func (app *GRPCApplication) PrepareProposal( - ctx context.Context, req *RequestPrepareProposal) (*ResponsePrepareProposal, error) { - res := app.app.PrepareProposal(*req) - return &res, nil -} - -func (app *GRPCApplication) ProcessProposal( - ctx context.Context, req *RequestProcessProposal) (*ResponseProcessProposal, error) { - res := app.app.ProcessProposal(*req) - return &res, nil -} - -func (app *GRPCApplication) FinalizeBlock( - ctx context.Context, req *RequestFinalizeBlock) (*ResponseFinalizeBlock, error) { - res := app.app.FinalizeBlock(*req) - return &res, nil -}