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

BM-15: feat(epoching): add protobuf messages #10

Merged
merged 12 commits into from
Jun 20, 2022
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ require (
github.com/golang/protobuf v1.5.2
github.com/gorilla/mux v1.8.0
github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/pkg/errors v0.9.1
github.com/rakyll/statik v0.1.7
github.com/spf13/cast v1.4.1
github.com/spf13/cobra v1.4.0
github.com/spf13/viper v1.10.1
github.com/stretchr/testify v1.7.1
github.com/supranational/blst v0.3.8
github.com/tendermint/tendermint v0.34.19
github.com/tendermint/tm-db v0.6.6
google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd
Expand Down Expand Up @@ -85,7 +87,6 @@ require (
github.com/mtibben/percent v0.2.1 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.12.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
Expand All @@ -100,7 +101,6 @@ require (
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
github.com/supranational/blst v0.3.8 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca // indirect
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect
github.com/tendermint/btcd v0.1.1 // indirect
Expand Down
4 changes: 1 addition & 3 deletions proto/babylon/epoching/v1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ package babylon.epoching.v1;

import "gogoproto/gogo.proto";
import "babylon/epoching/v1/params.proto";
// this line is used by starport scaffolding # genesis/proto/import

option go_package = "github.com/babylonchain/babylon/x/epoching/types";

// GenesisState defines the epoching module's genesis state.
message GenesisState {
Params params = 1 [(gogoproto.nullable) = false];
// this line is used by starport scaffolding # genesis/proto/state
Params params = 1 [ (gogoproto.nullable) = false ];
}
4 changes: 2 additions & 2 deletions proto/babylon/epoching/v1/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ option go_package = "github.com/babylonchain/babylon/x/epoching/types";

// Params defines the parameters for the module.
message Params {
option (gogoproto.goproto_stringer) = false;

// epoch_interval is the number of consecutive blocks to form an epoch
uint64 epoch_interval = 1 [ (gogoproto.moretags) = "yaml:\"epoch_interval\"" ];
}
44 changes: 38 additions & 6 deletions proto/babylon/epoching/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,26 @@ import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
import "babylon/epoching/v1/params.proto";
// this line is used by starport scaffolding # 1
import "babylon/epoching/v1/queued_message.proto";

option go_package = "github.com/babylonchain/babylon/x/epoching/types";

// Query defines the gRPC querier service.
service Query {
// Parameters queries the parameters of the module.
// Params queries the parameters of the module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/babylonchain/babylon/epoching/params";
option (google.api.http).get = "/babylon/epoching/v1/params";
}

// CurrentEpoch queries the current epoch
rpc CurrentEpoch(QueryCurrentEpochRequest) returns (QueryCurrentEpochResponse) {
option (google.api.http).get = "/babylon/epoching/v1/current_epoch";
}

// EpochMsgs queries the messages of a given epoch
rpc EpochMsgs(QueryEpochMsgsRequest) returns (QueryEpochMsgsResponse) {
Comment on lines +24 to +25
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you intend this to hold on to these messages forever, or only until they are dequeued?

I think there is no reason to support query the messages that were enqueued for an epoch in the past, it just takes up space in the ledger. The other queues in the staking module are drained as well.

If we don't have to support historical queries, then I think we shouldn't need epoch_num in the query, since we will only have a single delayed queue, which we completely drain at the end of the current epoch iff we are in a position to do so. I suggested that if the checkpoint for the previous epoch is not stable yet than we don't process these request, and do another epoch with the same validator set. It would be easier to always just dequeue everything, rather than having to index/filter them by epoch number.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When there exists multiple epochs that haven't been checkpointed yet, the epoching module has to store messages queued in each of these epochs. Otherwise, without such indexing, if one of these uncheckpointed epochs becomes checkpointed, the epoching module cannot know which of the queued messages should be forwarded to the staking module.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, we understand things differently then: the delayed staking messages don't need a checkpoint before they can be forwarded to the staking module, we do that unconditionally at the end of the current epoch. Therefore we don't need indexing, as we always forward all of them at once.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, after the meeting this is clear to me now. Then this query will be returning msgs queued in the current epoch. This query can even be merged with CurrentEpoch, with an extra field on whether to return queued msgs. Will change accordingly next Monday. Thanks for pointing this out!

option (google.api.http).get = "/babylon/epoching/v1/epoch_msgs";
}
// this line is used by starport scaffolding # 2
}

// QueryParamsRequest is request type for the Query/Params RPC method.
Expand All @@ -24,7 +33,30 @@ message QueryParamsRequest {}
// QueryParamsResponse is response type for the Query/Params RPC method.
message QueryParamsResponse {
// params holds all the parameters of this module.
Params params = 1 [(gogoproto.nullable) = false];
babylon.epoching.v1.Params params = 1 [ (gogoproto.nullable) = false ];
}

// QueryCurrentEpochRequest is request type for the Query/CurrentEpoch RPC method
message QueryCurrentEpochRequest {}

// QueryCurrentEpochResponse is response type for the Query/CurrentEpoch RPC method
message QueryCurrentEpochResponse {
// current_epoch is the current epoch number
uint64 current_epoch = 1;
// epoch_boundary is the height of this epoch's last block
uint64 epoch_boundary = 2;
}

// this line is used by starport scaffolding # 3
// QueryEpochMsgsRequest is request type for the Query/EpochMsgs RPC method
message QueryEpochMsgsRequest {
// pagination defines whether to have the pagination in the response
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}

// QueryEpochMsgsResponse is response type for the Query/EpochMsgs RPC method
message QueryEpochMsgsResponse {
// msgs is the list of messages queued in the current epoch
repeated babylon.epoching.v1.QueuedMessage msgs = 1;
// pagination defines the pagination in the response
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
21 changes: 21 additions & 0 deletions proto/babylon/epoching/v1/queued_message.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
syntax = "proto3";
package babylon.epoching.v1;

import "gogoproto/gogo.proto";
import "cosmos/staking/v1beta1/tx.proto";

option go_package = "github.com/babylonchain/babylon/x/epoching/types";

// QueuedMessage is a message that can change the validator set and is delayed to the epoch boundary
message QueuedMessage {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can imagine that this will at some point require something like an "original transaction ID" so we have a way to emit an event that users can tie back to the transaction they sent.

// msg_id is the original message ID
bytes msg_id = 1;
// msg is the actual message that is sent by a user and is queued by the epoching module
oneof msg {
cosmos.staking.v1beta1.MsgCreateValidator msg_create_validator = 2;
cosmos.staking.v1beta1.MsgDelegate msg_delegate = 3;
cosmos.staking.v1beta1.MsgUndelegate msg_undelegate = 4;
cosmos.staking.v1beta1.MsgBeginRedelegate msg_begin_redelegate = 5;
// TODO: after we bump to Cosmos SDK v0.46, add MsgCancelUnbondingDelegation
}
}
8 changes: 1 addition & 7 deletions proto/babylon/epoching/v1/tx.proto
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
syntax = "proto3";
package babylon.epoching.v1;

// this line is used by starport scaffolding # proto/tx/import

option go_package = "github.com/babylonchain/babylon/x/epoching/types";

// Msg defines the Msg service.
service Msg {
// this line is used by starport scaffolding # proto/tx/rpc
}

// this line is used by starport scaffolding # proto/tx/message
service Msg {}
9 changes: 7 additions & 2 deletions x/btccheckpoint/types/query.pb.gw.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion x/btclightclient/types/query.pb.gw.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 28 additions & 1 deletion x/epoching/keeper/grpc_query.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,34 @@
package keeper

import (
"context"

"github.com/babylonchain/babylon/x/epoching/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

var _ types.QueryServer = Keeper{}
// Querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over keeper
type Querier struct {
Keeper
}

var _ types.QueryServer = Querier{}

func (k Keeper) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "invalid request")
}
ctx := sdk.UnwrapSDKContext(c)

return &types.QueryParamsResponse{Params: k.GetParams(ctx)}, nil
}

func (k Keeper) CurrentEpoch(c context.Context, req *types.QueryCurrentEpochRequest) (*types.QueryCurrentEpochResponse, error) {
panic("TODO: unimplemented")
}

func (k Keeper) EpochMsgs(c context.Context, req *types.QueryEpochMsgsRequest) (*types.QueryEpochMsgsResponse, error) {
panic("TODO: unimplemented")
}
19 changes: 0 additions & 19 deletions x/epoching/keeper/grpc_query_params.go

This file was deleted.

Loading