test(server/v2/cometbft): Add Consensus query p2p, app, grpc (backport #22771) (#22773)

Co-authored-by: Hieu Vu <72878483+hieuvubk@users.noreply.github.com>
Co-authored-by: Julien Robert <julien@rbrt.fr>
This commit is contained in:
mergify[bot] 2024-12-05 12:30:54 +01:00 committed by GitHub
parent d183da281d
commit a565cf5c2a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 197 additions and 12 deletions

View File

@ -6,6 +6,7 @@ import (
"encoding/json"
"errors"
"io"
"reflect"
"strings"
"sync"
"testing"
@ -15,6 +16,7 @@ import (
abciproto "github.com/cometbft/cometbft/api/cometbft/abci/v1"
v1 "github.com/cometbft/cometbft/api/cometbft/types/v1"
"github.com/cosmos/gogoproto/proto"
gogoproto "github.com/cosmos/gogoproto/proto"
gogotypes "github.com/cosmos/gogoproto/types"
"github.com/stretchr/testify/require"
@ -33,6 +35,9 @@ import (
"cosmossdk.io/server/v2/stf/branch"
"cosmossdk.io/server/v2/stf/mock"
consensustypes "cosmossdk.io/x/consensus/types"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
)
var (
@ -53,7 +58,9 @@ var (
Msg: &gogotypes.BoolValue{Value: true},
GasLimit: 0,
}
actorName = []byte("cookies")
actorName = []byte("cookies")
testAcc = sdk.AccAddress([]byte("addr1_______________"))
versionStr = "0.0.0"
)
func getQueryRouterBuilder[T any, PT interface {
@ -583,11 +590,7 @@ func TestConsensus_Info(t *testing.T) {
require.Equal(t, res.LastBlockHeight, int64(1))
}
// TODO:
// - GRPC request
// - app request
// - p2p request
func TestConsensus_Query(t *testing.T) {
func TestConsensus_QueryStore(t *testing.T) {
c := setUpConsensus(t, 100_000, cometmock.MockMempool[mock.Tx]{})
// Write data to state storage
@ -648,11 +651,149 @@ func TestConsensus_Query(t *testing.T) {
require.Equal(t, res.Value, []byte(nil))
}
func TestConsensus_GRPCQuery(t *testing.T) {
c := setUpConsensus(t, 100_000, cometmock.MockMempool[mock.Tx]{})
_, err := c.InitChain(context.Background(), &abciproto.InitChainRequest{
Time: time.Now(),
ChainId: "test",
InitialHeight: 1,
})
require.NoError(t, err)
_, err = c.FinalizeBlock(context.Background(), &abciproto.FinalizeBlockRequest{
Time: time.Now(),
Height: 1,
Txs: [][]byte{mockTx.Bytes()},
Hash: emptyHash[:],
})
require.NoError(t, err)
// empty request
res, err := c.Query(context.Background(), &abciproto.QueryRequest{})
require.NoError(t, err)
require.Equal(t, res.Code, uint32(1))
require.Contains(t, res.Log, "no query path provided")
// query request not exist in handler map
invalidReq := testdata.EchoRequest{
Message: "echo",
}
invalidReqBz, err := invalidReq.Marshal()
require.NoError(t, err)
invalidQuery := abci.QueryRequest{
Data: invalidReqBz,
Path: "testpb.EchoRequest",
}
invalidRes, err := c.Query(context.TODO(), &invalidQuery)
require.Error(t, err)
require.Nil(t, invalidRes)
require.Contains(t, err.Error(), "no query handler found")
// Valid query
req := testdata.SayHelloRequest{Name: "foo"}
reqBz, err := req.Marshal()
require.NoError(t, err)
reqQuery := abci.QueryRequest{
Data: reqBz,
Path: "testpb.SayHelloRequest",
}
resQuery, err := c.Query(context.TODO(), &reqQuery)
require.NoError(t, err)
require.Equal(t, abci.CodeTypeOK, resQuery.Code, resQuery)
var response testdata.SayHelloResponse
require.NoError(t, response.Unmarshal(resQuery.Value))
require.Equal(t, "Hello foo!", response.Greeting)
}
func TestConsensus_P2PQuery(t *testing.T) {
c := setUpConsensus(t, 100_000, cometmock.MockMempool[mock.Tx]{})
_, err := c.InitChain(context.Background(), &abciproto.InitChainRequest{
Time: time.Now(),
ChainId: "test",
InitialHeight: 1,
})
require.NoError(t, err)
_, err = c.FinalizeBlock(context.Background(), &abciproto.FinalizeBlockRequest{
Time: time.Now(),
Height: 1,
Txs: [][]byte{mockTx.Bytes()},
Hash: emptyHash[:],
})
require.NoError(t, err)
// empty request
res, err := c.Query(context.Background(), &abciproto.QueryRequest{})
require.NoError(t, err)
require.Equal(t, res.Code, uint32(1))
require.Contains(t, res.Log, "no query path provided")
addrQuery := abci.QueryRequest{
Path: "/p2p/filter/addr/1.1.1.1:8000",
}
res, err = c.Query(context.TODO(), &addrQuery)
require.NoError(t, err)
require.Equal(t, uint32(3), res.Code)
idQuery := abci.QueryRequest{
Path: "/p2p/filter/id/testid",
}
res, err = c.Query(context.TODO(), &idQuery)
require.NoError(t, err)
require.Equal(t, uint32(4), res.Code)
}
func TestConsensus_AppQuery(t *testing.T) {
c := setUpConsensus(t, 100_000, cometmock.MockMempool[mock.Tx]{})
_, err := c.InitChain(context.Background(), &abciproto.InitChainRequest{
Time: time.Now(),
ChainId: "test",
InitialHeight: 1,
})
require.NoError(t, err)
_, err = c.FinalizeBlock(context.Background(), &abciproto.FinalizeBlockRequest{
Time: time.Now(),
Height: 1,
Txs: [][]byte{mockTx.Bytes()},
Hash: emptyHash[:],
})
require.NoError(t, err)
tx := mock.Tx{
Sender: testAcc,
Msg: &gogotypes.BoolValue{Value: true},
GasLimit: 1000,
}
txBytes := tx.Bytes()
// simulate by calling Query with encoded tx
query := abci.QueryRequest{
Path: "/app/simulate",
Data: txBytes,
}
queryResult, err := c.Query(context.TODO(), &query)
require.NoError(t, err)
require.True(t, queryResult.IsOK(), queryResult.Log)
// Query app version
res, err := c.Query(context.TODO(), &abci.QueryRequest{Path: "app/version"})
require.NoError(t, err)
require.True(t, res.IsOK())
require.Equal(t, versionStr, string(res.Value))
}
func setUpConsensus(t *testing.T, gasLimit uint64, mempool mempool.Mempool[mock.Tx]) *consensus[mock.Tx] {
t.Helper()
queryHandler := make(map[string]appmodulev2.Handler)
msgRouterBuilder := getMsgRouterBuilder(t, func(ctx context.Context, msg *gogotypes.BoolValue) (*gogotypes.BoolValue, error) {
return nil, nil
return msg, nil
})
queryRouterBuilder := getQueryRouterBuilder(t, func(ctx context.Context, q *consensustypes.QueryParamsRequest) (*consensustypes.QueryParamsResponse, error) {
@ -669,6 +810,32 @@ func setUpConsensus(t *testing.T, gasLimit uint64, mempool mempool.Mempool[mock.
}, nil
})
helloFooHandler := func(ctx context.Context, msg transaction.Msg) (msgResp transaction.Msg, err error) {
typedReq := msg.(*testdata.SayHelloRequest)
handler := testdata.QueryImpl{}
typedResp, err := handler.SayHello(ctx, typedReq)
if err != nil {
return nil, err
}
return typedResp, nil
}
queryRouterBuilder.RegisterHandler(
proto.MessageName(&testdata.SayHelloRequest{}),
helloFooHandler,
)
queryHandler[proto.MessageName(&testdata.SayHelloRequest{})] = appmodulev2.Handler{
Func: helloFooHandler,
MakeMsg: func() transaction.Msg {
return reflect.New(gogoproto.MessageType(proto.MessageName(&testdata.SayHelloRequest{})).Elem()).Interface().(transaction.Msg)
},
MakeMsgResp: func() transaction.Msg {
return reflect.New(gogoproto.MessageType(proto.MessageName(&testdata.SayHelloResponse{})).Elem()).Interface().(transaction.Msg)
},
}
s, err := stf.New(
log.NewNopLogger().With("module", "stf"),
msgRouterBuilder,
@ -709,6 +876,16 @@ func setUpConsensus(t *testing.T, gasLimit uint64, mempool mempool.Mempool[mock.
nil,
)
addrPeerFilter := func(info string) (*abci.QueryResponse, error) {
require.Equal(t, "1.1.1.1:8000", info)
return &abci.QueryResponse{Code: uint32(3)}, nil
}
idPeerFilter := func(id string) (*abci.QueryResponse, error) {
require.Equal(t, "testid", id)
return &abci.QueryResponse{Code: uint32(4)}, nil
}
return &consensus[mock.Tx]{
logger: log.NewNopLogger(),
appName: "testing-app",
@ -719,6 +896,10 @@ func setUpConsensus(t *testing.T, gasLimit uint64, mempool mempool.Mempool[mock.
txCodec: mock.TxCodec{},
chainID: "test",
getProtoRegistry: sync.OnceValues(proto.MergedRegistry),
queryHandlersMap: queryHandler,
addrPeerFilter: addrPeerFilter,
idPeerFilter: idPeerFilter,
version: versionStr,
}
}

View File

@ -190,6 +190,11 @@ func intoABCISimulationResponse(txRes server.TxResult, indexSet map[string]struc
msgResponses[i] = anyMsg
}
errMsg := ""
if txRes.Error != nil {
errMsg = txRes.Error.Error()
}
res := &sdk.SimulationResponse{
GasInfo: sdk.GasInfo{
GasWanted: txRes.GasWanted,
@ -197,7 +202,7 @@ func intoABCISimulationResponse(txRes server.TxResult, indexSet map[string]struc
},
Result: &sdk.Result{
Data: []byte{},
Log: txRes.Error.Error(),
Log: errMsg,
Events: abciEvents,
MsgResponses: msgResponses,
},
@ -284,7 +289,6 @@ func gRPCErrorToSDKError(err error) *abci.QueryResponse {
res.Log = err.Error()
}
return res
}
status, ok := grpcstatus.FromError(err)

View File

@ -256,7 +256,7 @@ replace (
cosmossdk.io/core/testing => cosmossdk.io/core/testing v0.0.0-20241119134933-d697a3de0f95 // main
cosmossdk.io/server/v2/cometbft => ../../server/v2/cometbft
// pseudo version lower than the latest tag
cosmossdk.io/store => cosmossdk.io/store v1.0.0-rc.0.0.20241119134933-d697a3de0f95 // main
cosmossdk.io/store => cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d // main
cosmossdk.io/tools/confix => ../../tools/confix
cosmossdk.io/x/accounts => ../../x/accounts
cosmossdk.io/x/accounts/defaults/base => ../../x/accounts/defaults/base

View File

@ -220,8 +220,8 @@ cosmossdk.io/server/v2/appmanager v0.0.0-20241203212527-7d117425d880 h1:0mtB8fSv
cosmossdk.io/server/v2/appmanager v0.0.0-20241203212527-7d117425d880/go.mod h1:elhlrldWtm+9U4PxE0G3wjz83yQwVVGVAOncXJPY1Xc=
cosmossdk.io/server/v2/stf v0.0.0-20241204101618-7fa2356c07aa h1:2V9nqgL50nw45HcQw1UBRQ/y0QBzrgfLIStPSxFnMtY=
cosmossdk.io/server/v2/stf v0.0.0-20241204101618-7fa2356c07aa/go.mod h1:4e9SzLyeGptQ3tSR6nKCNwCu7Ye4uUS2WIJih29dG2c=
cosmossdk.io/store v1.0.0-rc.0.0.20241119134933-d697a3de0f95 h1:5hIgRL6VsicdJ7FVK6AG7cSy1C8tiVbCp6W3Y+QQ5ko=
cosmossdk.io/store v1.0.0-rc.0.0.20241119134933-d697a3de0f95/go.mod h1:ceNwMZIU8ZIDoeUdA9+sGxz3GVt0orEGoVpkBfa/UtU=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d h1:KQM4Q6kjwlM4HuDZRV8/ZDXX3whjfStndYNTsRrbboQ=
cosmossdk.io/store v1.0.0-rc.0.0.20241204123127-eb3bf8b0469d/go.mod h1:oZBBY4BrkYnghr6MFL0MP5mGqpkPedHcWkXwXddd6tU=
cosmossdk.io/store/v2 v2.0.0-20241203212527-7d117425d880 h1:oQiiB1e2yg6/ttUCKLBAdbLuyUp9UYW2K8QGnCs7dWg=
cosmossdk.io/store/v2 v2.0.0-20241203212527-7d117425d880/go.mod h1:1DbksNgjyQ1XxlCYqkU82WqBGWcxmgciO5dBf6dRhKM=
cosmossdk.io/x/tx v1.0.0-alpha.2 h1:UW80FMm7B0fiAMsrfe5+HabSJ3XBg+tQa6/GK9prqWk=