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-2: feat(checkpointing): init checkpointing module and define proto types #5

Merged
merged 7 commits into from
Jun 20, 2022

Conversation

gitferry
Copy link
Contributor

@gitferry gitferry commented Jun 10, 2022

This PR is to:

  • scaffold the module x/checkpointing

  • define msg and query protobuff

Future PRs will solve:

  • add a description of the data processing flows (interactions between modules, interaction between programs), the skeleton to x/checkpointing/spec.

  • develop and document the serializer/deserializer of other data structures (such as BTC related ones) that are not in protobuff

  • develop the keeper of the checkpointing module

@gitferry gitferry requested a review from aakoshh June 10, 2022 04:59
Copy link
Contributor

@aakoshh aakoshh left a comment

Choose a reason for hiding this comment

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

Nice work!

It might have been better to follow what the other's have done and check in just the boilerplate scaffolding first, and then the actual checkpointing specific content as a separate PR, so it doesn't get lost in the sea of similarity.

One thing I'm not quite sure about is that this module contains a query to return raw checkpoints, yet there's a separate #4 for an actual rawcheckpoint module. Wouldn't a query like that belong there?

What modules do we plan to have?

  • epoching
  • BTC header oracle
  • OP return oracle, i.e. BTC specific checkpoint module
  • raw checkpoint module
  • checkpoint module

That ☝️ looks redundant, there must be a duplicate among the last 3. Which one is this module?

proto/babylon/checkpointing/genesis.proto Outdated Show resolved Hide resolved
proto/babylon/checkpointing/genesis.proto Outdated Show resolved Hide resolved
proto/babylon/checkpointing/genesis.proto Outdated Show resolved Hide resolved
proto/babylon/checkpointing/genesis.proto Outdated Show resolved Hide resolved
proto/babylon/checkpointing/query.proto Outdated Show resolved Hide resolved
proto/babylon/checkpointing/query.proto Outdated Show resolved Hide resolved
proto/babylon/checkpointing/query.proto Outdated Show resolved Hide resolved
proto/babylon/checkpointing/tx.proto Outdated Show resolved Hide resolved
@gitferry
Copy link
Contributor Author

Thanks, @aakoshh for the comments. I addressed them and replied if I have concerns. Please review the PR again. Many thanks!

@gitferry
Copy link
Contributor Author

I had an issue when I tried to build proto code using Makefile. I used ignite serve chain instead.
@vitsalis Could you please tell me if I have done it right? I first ran make proto-update-deps to download third-party proto dependencies. I had the following error:

sed: 1: "third_party/proto/confi ...": undefined label 'hird_party/proto/confio/proofs.proto'

but I can see the third_party folder and proto files already existed.
Then, when I ran make-check-breaking, I had a bunch of errors as follows.

proto/babylon/checkpointing/checkpoint.proto:4:8:cosmos_proto/cosmos.proto: does not exist
proto/babylon/checkpointing/genesis.proto:4:8:gogoproto/gogo.proto: does not exist
proto/babylon/checkpointing/params.proto:4:8:gogoproto/gogo.proto: does not exist
proto/babylon/checkpointing/query.proto:4:8:cosmos/base/query/v1beta1/pagination.proto: does not exist
proto/babylon/checkpointing/tx.proto:4:8:gogoproto/gogo.proto: does not exist
third_party/proto/babylon_proto/babylon.proto:1:1:syntax error: unexpected int literal
third_party/proto/tendermint/abci/types.proto:8:8:tendermint/crypto/proof.proto: does not exist
third_party/proto/tendermint/crypto/keys.proto:6:8:gogoproto/gogo.proto: does not exist
third_party/proto/tendermint/crypto/proof.proto:6:8:gogoproto/gogo.proto: does not exist
third_party/proto/tendermint/p2p/types.proto:6:8:gogoproto/gogo.proto: does not exist
third_party/proto/tendermint/types/block.proto:6:8:gogoproto/gogo.proto: does not exist
third_party/proto/tendermint/types/evidence.proto:6:8:gogoproto/gogo.proto: does not exist
third_party/proto/tendermint/types/params.proto:6:8:gogoproto/gogo.proto: does not exist
third_party/proto/tendermint/types/types.proto:6:8:gogoproto/gogo.proto: does not exist
third_party/proto/tendermint/types/validator.proto:6:8:gogoproto/gogo.proto: does not exist
third_party/proto/tendermint/version/types.proto:6:8:gogoproto/gogo.proto: does not exist

@vitsalis
Copy link
Member

It seems that your commit history is jumbled up a little bit. More specifically, all commits from init checkpointing module to wraps up the scaffolding of checkpointing are duplicatd.

@vitsalis
Copy link
Member

In order to build proto code I use make proto-gen which seems to work in your branch (currently it has a bug in which you need to execute go mod tidy after make proto-gen). I haven't tried the commands that you mention, but I will investigate why they fail. Should not be a blocker for this PR though I believe.

@gitferry gitferry force-pushed the gai-checkpointing-module-setup branch 2 times, most recently from 3b505a8 to f0ad00f Compare June 12, 2022 11:25
@gitferry
Copy link
Contributor Author

It seems that your commit history is jumbled up a little bit. More specifically, all commits from init checkpointing module to wraps up the scaffolding of checkpointing are duplicatd.

To @vitsalis, thanks for pointing it out. Sorry, the duplicate commits came from a bad rebase.
Also to @aakoshh, I dropped duplicate commits and squashed them, leaving two commits for now (one before fixing the comments, and another for after fixing the comments). I hope I did not create confusion. Thanks!

@gitferry gitferry force-pushed the gai-checkpointing-module-setup branch from f0ad00f to 59756c3 Compare June 12, 2022 11:34
@gitferry
Copy link
Contributor Author

In order to build proto code I use make proto-gen which seems to work in your branch (currently it has a bug in which you need to execute go mod tidy after make proto-gen). I haven't tried the commands that you mention, but I will investigate why they fail. Should not be a blocker for this PR though I believe.

@vitsalis I tried make proto-gen and it worked. Thanks!

Comment on lines 43 to 36
// can't find cosmos_proto.scalar when compiling
// string signer_address = 5 [(cosmos_proto.scalar) = "cosmos.AddressString"];
Copy link
Contributor

Choose a reason for hiding this comment

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

Try rebasing on #3
You will need that cosmos specific protoc plugin installed, which I think the script does before it runs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried make proto-gen uncommenting cosmos_proto.scalar but I still got errors. @vitsalis could you please take a look?

make proto-gen
Generating Protobuf files
proto/babylon/checkpointing/checkpoint.proto:44:30:field babylon.checkpointing.v1.BlsSig.signer_address: unknown extension cosmos_proto.scalar
proto/babylon/checkpointing/checkpoint.proto:44:30:field babylon.checkpointing.v1.BlsSig.signer_address: unknown extension cosmos_proto.scalar
proto/babylon/checkpointing/checkpoint.proto:44:30:field babylon.checkpointing.v1.BlsSig.signer_address: unknown extension cosmos_proto.scalar
make: *** [proto-gen] Error 100

Copy link
Member

@vitsalis vitsalis Jun 12, 2022

Choose a reason for hiding this comment

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

Seems like this feature does not exist in version 0.45.4 of cosmos. It was introduced by this commit:
cosmos/cosmos-sdk@94377f1

However, this commit only appears on versions 0.46.*. Searching for the word scalar under the proto directory on tag v0.45.4 does not produce any results

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I see. Thanks, @vitsalis for checking it. I guess I'll just use string for this PR and update it to scalar when we decide to use a newer version of cosmos.

@gitferry
Copy link
Contributor Author

@aakoshh Thanks for your second round of reviews. I fixed minor protobuf issues and replied to unaddressed ones. Thanks!

@gitferry
Copy link
Contributor Author

gitferry commented Jun 13, 2022

Hi @KonradStaniec, could you please review the proto files of this module? Especially the checkpoint.proto, which is quite relevant to the op_return module. Thanks!

@gitferry
Copy link
Contributor Author

I realized this PR is getting bigger. I'll not add more code except revision to this PR. And I'll replace this PR with smaller and more specific PRs after the review is over.

@gitferry gitferry force-pushed the gai-checkpointing-module-setup branch from 4325ace to 0ba412c Compare June 13, 2022 03:24
option go_package = "github.com/babylonchain/babylon/x/checkpointing/types";

// RawCheckpoint wraps the multi sig with meta data.
message RawCheckpoint {
Copy link
Collaborator

Choose a reason for hiding this comment

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

As I understand RawCheckpoint is a checkpoint structure which will be serialized into bytes and put into two op return transactions on btc chain ?

If yes then two questions:

  1. Why do we need status here ? Isn't status a internal state a checkpoint manager about current checkpoint status, so it does not need to appear in RawCheckpoint serialized form ?
  2. I wonder if it would be more optimal to define rawcheckpint as standard go struct with custom serialization, as from what I remember protobuf does not have concept of fixed length arrays, so each bytes field always have its length pr-pended so it add few bytes of over head and each byte cost. Then serialization of such struct would be just concatendation of last_commit_hash, bitmap, bls_multi_sig and epoch_num serialized as varInt

Copy link
Contributor

Choose a reason for hiding this comment

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

To be fair there's no actual field for Status, it's just a nested type. Maybe it will appear in its own collection in the Keeper.

Great point about the protobuf vs Go defined structure. FWIW I think what we need to avoid is rely on protobuf serialisation for hashing, as it has proven to be different across platforms. But defining stuff in protobuf that appears in API calls as well as on chain, like transaction messages themselves, seems to be the Tendermint/Cosmos way.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@KonradStaniec @aakoshh Thanks for the discussion. The RawCheckpoint struct will be returned to BTC relayer via queries. Having Status in the struct will help the relayer make decisions on which raw checkpoint to submit based on the status. The Status will not be included in OP_RETURN to BTC.

Copy link
Contributor

Choose a reason for hiding this comment

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

Just to clarify: there is currently no status in the struct, only a type that is namespaced, so you have a RawCheckpoint_Status type, but no field, see here.

But I think that's not a bad thing actually, you can always have a type like RawCheckpointWithStatus to couple to two for queries.

You would most likely have to store the status and the aggregated power somewhere else anyway. I think it would be nice if the RawCheckpoint corresponded to the information OP_RETURN as-is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just to clarify: there is currently no status in the struct, only a type that is namespaced, so you have a RawCheckpoint_Status type, but no field, see here.

But I think that's not a bad thing actually, you can always have a type like RawCheckpointWithStatus to couple to two for queries.

You would most likely have to store the status and the aggregated power somewhere else anyway. I think it would be nice if the RawCheckpoint corresponded to the information OP_RETURN as-is.

Sorry, I'm not sure I'm following this. The link you are referring seems the link of this page. I added an enum type called RawCheckpointStatus. Please correct me if I'm doing it wrong.

Copy link
Contributor

Choose a reason for hiding this comment

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

At the time the status = 5 field was missing, that's all. I agree with Konrad that it should not be part of the RawCheckpoint data structure, to have something that is really just the checkpoint, as it was created, and a separate wrapper type that attaches a status which can change. To decouple the static fields from the dynamic ones.

In the Kubernetes API they have a convention of everything having a spec and a status, where spec is what the user can set and status is a data structure that changes according to what is happening in the system. This is a similar case to that.

@gitferry gitferry force-pushed the gai-checkpointing-module-setup branch from 0ba412c to a65243e Compare June 14, 2022 02:24
@gitferry
Copy link
Contributor Author

@aakoshh I changed some protos according to our discussion and rebased the PR with the main branch. Please review it again. Many thanks!


// QueryRawCheckpointRequest is the request type for the Query/RawCheckpoint
// RPC method.
message QueryRawCheckpointRequest {
Copy link
Contributor

Choose a reason for hiding this comment

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

I looked for a long time until I spotted the difference between the name of this and QueryRawCheckpointsRequest. I wonder if the Cosmos SDK has a convention of lists. In the default gRPC naming guide there was Get vs List to make it obvious.

Copy link
Contributor Author

@gitferry gitferry Jun 15, 2022

Choose a reason for hiding this comment

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

Well, I was following the staking module which has validator vs. validators. See here. But I agree that it is confusing. I think we should follow the default gRPC naming guide and use List for multiple items. Thanks for pointing it out @aakoshh

Copy link
Contributor

@aakoshh aakoshh Jun 19, 2022

Choose a reason for hiding this comment

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

Thanks for the link to the staking module. If they do it like that as well then fine, we'll just have to strain our eyes a bit 8-)

option (google.api.http).get = "/babylon/checkpointing/v1/raw_checkpoint/{epoch_num}";
}

// LatestCheckpoint queries the latest checkpoint.
Copy link
Contributor

Choose a reason for hiding this comment

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

What does "latest" mean exactly? For example if for any reason there are multiple ones that haven't collected all signatures?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added docstring to describe that it queries the checkpoint with the highest epoch number.

For example if for any reason there are multiple ones that haven't collected all signatures?

I don't think this situation would happen because a checkpoint is only generated when sufficient bls-sigs are collected. Did I miss anything? Also, if there are multiple checkpoints generated at the same epoch, the system would panic.

// RPC method.
message QueryRawCheckpointsRequest {
// status defines the status of the raw checkpoints of the query
string status = 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
string status = 1;
RawCheckpoint.Status status = 1;

// QueryBlsPublicKeysResponse is the response type for the Query/BlsPublicKeys
// RPC method.
message QueryBlsPublicKeysResponse {
repeated bytes bls_pub_keys = 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this contain the validator address as well, so that I can look up the voting power they had at the time?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hm, did you add signer_address in response to this comment?

If so, I'm sorry, I should have been more specific. What I meant was that the response should contain (validator-address, bls-pub-key) pairs, so that we have a way to figure out what power they have. Something like message ValidatorWithBlsKey, it could even contain the power, to make it easier to use the API. So instead of repeated bytes bls_pub_keys it would be repeated ValidatorWithBlsKey validator_bls_keys = 1; or something similar.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, yes you are right. I added ValidatorWithBlsKey

@gitferry
Copy link
Contributor Author

@aakoshh I changed the query proto according to the comments, but I'm not sure I'm doing it right regarding on the status. Please review it again. Many thanks!

@gitferry gitferry changed the title BM-2: feat(checkpointing): Checkpointing module setup BM-2: feat(checkpointing): init checkpointing module and define proto types Jun 16, 2022
@gitferry
Copy link
Contributor Author

Hi @aakoshh, I added ValidatorWithBlsKey according to your comment. Please review it. Thanks!

Copy link
Contributor

@aakoshh aakoshh left a comment

Choose a reason for hiding this comment

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

Thanks for the changes. I don't see any blockers. I expect this may not be the final form of RawCheckpoint, but we can revisit it later if a consensus arises.

@gitferry gitferry force-pushed the gai-checkpointing-module-setup branch from 8f8ccb0 to 1d751a2 Compare June 20, 2022 13:42
@gitferry gitferry merged commit bebdd3f into main Jun 20, 2022
@gitferry gitferry deleted the gai-checkpointing-module-setup branch June 20, 2022 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants