Co-authored-by: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Co-authored-by: Julien Robert <julien@rbrt.fr>
This commit is contained in:
parent
d183da281d
commit
a565cf5c2a
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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=
|
||||
|
||||
Loading…
Reference in New Issue
Block a user