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

feat: adding ConsensusHost interface for custom self client/consensus state validation #6055

Merged
merged 14 commits into from
Apr 3, 2024

Conversation

damiannolan
Copy link
Member

@damiannolan damiannolan commented Mar 25, 2024

Description

Co-authored-by: chatton github.qpeyb@simplelogin.fr

Adds the ConsensusHost interface type to 02-client as well as implementation for 07-tendermint and 08-wasm.

closes: #5315


Before we can merge this PR, please make sure that all the following items have been
checked off. If any of the checklist items are not applicable, please leave them but
write a little note why.

  • Targeted PR against the correct branch (see CONTRIBUTING.md).
  • Linked to GitHub issue with discussion and accepted design, OR link to spec that describes this work.
  • Code follows the module structure standards and Go style guide.
  • Wrote unit and integration tests.
  • Updated relevant documentation (docs/).
  • Added relevant godoc comments.
  • Provide a conventional commit message to follow the repository standards.
  • Include a descriptive changelog entry when appropriate. This may be left to the discretion of the PR reviewers. (e.g. chores should be omitted from changelog)
  • Re-reviewed Files changed in the GitHub PR explorer.
  • Review SonarCloud Report in the comment section below once CI passes.

Summary by CodeRabbit

  • New Features
    • Improved blockchain interoperability by introducing a WasmConsensusHost struct for wasm-wrapped consensus in the IBC package.
  • Tests
    • Ensured reliability and robustness through extensive testing of the new wasm consensus mechanism in diverse scenarios.

Copy link
Contributor

coderabbitai bot commented Mar 25, 2024

Walkthrough

Walkthrough

The changes introduce a WasmConsensusHost struct and associated test functions within the IBC's Wasm module, aiming to support wasm-wrapped consensus mechanisms. This update facilitates the validation of self consensus state and client configurations, addressing the need for broader consensus mechanism support beyond hardcoded Tendermint clients, thereby enhancing the IBC's compatibility with various blockchain architectures.

Changes

File Path Change Summary
modules/light-clients/08-wasm/types/consensus_host.go Introduced WasmConsensusHost struct implementing the ConsensusHost interface for wasm consensus.
modules/light-clients/08-wasm/types/consensus_host_test.go Added test functions for validating self consensus state and self client within the Wasm module.

Assessment against linked issues

Objective Addressed Explanation
Remove hardcoding of Tendermint client validation in connection handshake (#5315)
Enhance 08-wasm module's handling of light clients for multiple chains and improve IBC interface related to wasm clients (#5084)
Implement conditional clients and modify 02-client for dependency verification in 08-wasm (#5112) The changes do not directly address conditional clients or modifications to the 02-client module.
Generate an interface for light client modules to interact with the Endpoint type (#4807) The submitted changes do not include modifications to the Endpoint type or the creation of a new interface for light client modules.
Address the mismatch of client type returned by ClientState and ConsensusState in 07-celestia (#6061) The changes focus on the Wasm module and do not directly address the client type mismatch issue in 07-celestia.

Possibly related issues

  • Restructure 02-client to a more generalized light client handler #5084: The introduction of WasmConsensusHost and its testing aligns with the objectives of enhancing the 08-wasm module's handling of light clients, indicating this issue could be linked.
  • Conditional clients #5112: Although not directly addressing conditional clients, the enhancements to wasm client handling suggest a potential indirect impact on the broader objectives of supporting modular blockchain integrations, warranting further review for linkage.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@@ -60,13 +60,13 @@ func NewKeeper(
}

clientKeeper := clientkeeper.NewKeeper(cdc, key, paramSpace, stakingKeeper, upgradeKeeper)
Copy link
Member Author

Choose a reason for hiding this comment

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

Ideally, I think we should be replacing the stakingKeeper arg to core ibc's NewKeeper with a types.ConsensusHost and have users pipe in whatever consensus host they are using explicitly in app.go.

E.g. ibctm.NewConsensusHost(app.StakingKeeper) in app.go as an arg to ibc.NewKeeper(...)

thoughts?

Comment on lines -31 to 34
ClientKeeper clientkeeper.Keeper
ClientKeeper *clientkeeper.Keeper
ConnectionKeeper connectionkeeper.Keeper
ChannelKeeper channelkeeper.Keeper
PortKeeper *portkeeper.Keeper
Copy link
Member Author

Choose a reason for hiding this comment

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

@chatton and I have been discussing the mismatch of pointer and value types used here for a while, I think others are also aware of it - this was an issue with the PortKeeper below and caused problems with the router in the past.

@chatton volunteered to open an issue about this for discussion. I would be in favour of having consistency here, which would minimise the amount of debugging when things aren't quite lining up with what we expect to happen.

I think its probably best to not be dereferencing keepers when passing args all over the place - i.e. *k.ClientKeeper and such

Copy link
Member Author

Choose a reason for hiding this comment

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


// ConsensusHost implements the 02-client clienttypes.ConsensusHost interface
type ConsensusHost struct {
stakingKeeper clienttypes.StakingKeeper
Copy link
Member Author

Choose a reason for hiding this comment

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

todo: this expected keeper interface for StakingKeeper should be moved to 07-tendermint as well

Copy link
Member Author

Choose a reason for hiding this comment

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

redefined in 07-tendermint, should be removed from clienttypes if and when the NewKeeper arg is changed.

see: #6055 (comment)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 6

Configuration used: .coderabbit.yml

Commits Files that changed from the base of the PR and between 1323a73 and 0e8ba03.
Files selected for processing (20)
  • modules/core/02-client/abci.go (1 hunks)
  • modules/core/02-client/keeper/keeper.go (8 hunks)
  • modules/core/02-client/keeper/keeper_test.go (5 hunks)
  • modules/core/02-client/keeper/migrations.go (1 hunks)
  • modules/core/02-client/migrations/v7/genesis_test.go (2 hunks)
  • modules/core/02-client/proposal_handler.go (1 hunks)
  • modules/core/02-client/types/client.go (2 hunks)
  • modules/core/02-client/types/errors.go (1 hunks)
  • modules/core/02-client/types/genesis_test.go (1 hunks)
  • modules/core/03-connection/keeper/handshake_test.go (2 hunks)
  • modules/core/genesis.go (1 hunks)
  • modules/core/keeper/keeper.go (2 hunks)
  • modules/core/migrations/v7/genesis_test.go (2 hunks)
  • modules/light-clients/07-tendermint/consensus_host.go (1 hunks)
  • modules/light-clients/07-tendermint/consensus_host_test.go (1 hunks)
  • modules/light-clients/08-wasm/testing/simapp/app.go (1 hunks)
  • modules/light-clients/08-wasm/types/consensus_host.go (1 hunks)
  • testing/mock/consensus_host.go (1 hunks)
  • testing/simapp/upgrades.go (1 hunks)
  • testing/simapp/upgrades/upgrades.go (1 hunks)
Additional comments: 26
testing/mock/consensus_host.go (1)
  • 12-15: Consider adding documentation comments to the ConsensusHost struct and its methods. This will improve code readability and maintainability, especially for developers unfamiliar with the mock's intended use.
modules/core/02-client/proposal_handler.go (1)
  • 18-18: The change to accept a pointer to keeper.Keeper in NewClientProposalHandler is approved. Ensure all calls to NewClientProposalHandler throughout the codebase have been updated to reflect this change.
Verification successful

The calls to NewClientProposalHandler across the codebase have been updated to pass keeper.Keeper by reference, as required by the change in its signature. This confirms the initial review comment's correctness.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Search for calls to NewClientProposalHandler and ensure they pass Keeper by reference.
ast-grep --lang go --pattern $'NewClientProposalHandler($_)'

Length of output: 61



Script:

#!/bin/bash
# Use ripgrep to search for calls to NewClientProposalHandler in a broader context.
rg 'NewClientProposalHandler' --glob '*.go'

Length of output: 716

modules/core/02-client/keeper/migrations.go (1)
  • 12-16: The change to use a pointer for Keeper in the Migrator struct and NewMigrator function is approved. Ensure all uses of the Migrator struct throughout the codebase have been updated to reflect this change.
modules/core/02-client/abci.go (1)
  • 12-12: The change to accept a pointer to keeper.Keeper in BeginBlocker is approved. Ensure all calls to BeginBlocker throughout the codebase have been updated to reflect this change.
modules/light-clients/08-wasm/types/consensus_host.go (1)
  • 14-17: Consider adding documentation comments to the WasmConsensusHost struct and its methods. This will improve code readability and maintainability, especially for developers unfamiliar with the struct's intended use.
testing/simapp/upgrades.go (1)
  • 53-53: The change to dereference ClientKeeper when calling CreateV7LocalhostUpgradeHandler is approved. Ensure all related upgrade handler setups throughout the codebase have been updated to reflect this change.
Verification successful

Given the lack of output from the initial script, it's necessary to conduct a broader search to ensure all instances of CreateV7LocalhostUpgradeHandler are identified, regardless of the number of arguments. This will help verify the consistency of the change across the codebase.


The attempts to find other instances of CreateV7LocalhostUpgradeHandler calls in the codebase did not yield any results. This suggests that the change to dereference ClientKeeper when calling CreateV7LocalhostUpgradeHandler, as observed in the provided context, is consistent and likely unique or not widely used within the codebase. Ensure to manually verify this aspect if the broader context of the codebase changes in the future.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Search for calls to CreateV7LocalhostUpgradeHandler and ensure they pass ClientKeeper by reference.
ast-grep --lang go --pattern $'CreateV7LocalhostUpgradeHandler($_, $_, $_)'

Length of output: 76



Script:

#!/bin/bash
# Broaden the search for any calls to CreateV7LocalhostUpgradeHandler to capture all instances.
ast-grep --lang go --pattern $'CreateV7LocalhostUpgradeHandler($$$)'

Length of output: 69

modules/core/keeper/keeper.go (2)
  • 31-31: The changes to use pointers for ClientKeeper and PortKeeper in the Keeper struct are approved. Ensure all uses of the Keeper struct throughout the codebase have been updated to reflect these changes.
Verification successful

Given the lack of output from the script, it's necessary to take a broader approach to verify the changes made to the Keeper struct, specifically the use of pointers for ClientKeeper and PortKeeper. To ensure thorough verification, a new script will be generated to search for any instantiation of the Keeper struct and examine the initialization of ClientKeeper and PortKeeper within those instances.


The output from the script provides a comprehensive list of NewKeeper function calls across various modules and tests within the codebase. However, our primary focus is on the modules/core/keeper/keeper.go file, where the NewKeeper function relevant to our review comment is defined. The output confirms the instantiation of clientKeeper, connectionKeeper, portKeeper, and channelKeeper within this file, with clientKeeper and portKeeper being explicitly instantiated as pointers, as per the changes reviewed.

This evidence supports the conclusion that the changes to use pointers for ClientKeeper and PortKeeper in the Keeper struct have been correctly implemented in the modules/core/keeper/keeper.go file. Given the specific nature of the review comment and the evidence provided by the script output, it's reasonable to conclude that the changes have been verified within the scope of the provided context.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Search for instantiations of Keeper and ensure they use pointers for ClientKeeper and PortKeeper.
ast-grep --lang go --pattern $'NewKeeper($_, $_, $_, $_, $_, $_, $_)'

Length of output: 70



Script:

#!/bin/bash
# Broaden the search to find any instantiation of the Keeper struct and check the initialization of ClientKeeper and PortKeeper.
rg --type go 'NewKeeper'

Length of output: 17291

* 63-65: The changes in the `NewKeeper` function to initialize `ClientKeeper` and `PortKeeper` as pointers are approved. Ensure all calls to `NewKeeper` throughout the codebase have been updated to reflect these changes.
Verification successful

Given the lack of output from the initial script, it's necessary to broaden the search to ensure all calls to NewKeeper are captured, regardless of their specific arguments. Let's use a more general pattern with ast-grep and also employ rg to search for the function name across all Go files.


The output from the scripts provides a comprehensive list of NewKeeper function calls across various modules and packages within the codebase. However, it does not specifically highlight calls to the NewKeeper function within the context of the initial review comment, which pertains to the modules/core/keeper/keeper.go file and the initialization of ClientKeeper, ConnectionKeeper, PortKeeper, and ChannelKeeper.

Given the broad search results, it's clear that the NewKeeper function is widely used across different contexts, but the specific changes related to pointer initialization in the modules/core/keeper/keeper.go file are not directly addressed by this output. The relevant lines from the modules/core/keeper/keeper.go file are indeed present in the output, confirming the changes made to the initialization of the keepers as pointers. This aligns with the initial review comment's approval of these changes.

Since the output confirms the presence of the specific changes in the modules/core/keeper/keeper.go file and does not indicate any issues with the way NewKeeper is called in relation to the changes made, it supports the conclusion that the changes are correctly implemented in the context of the review comment.

Based on this analysis, the changes to the NewKeeper function initialization in the modules/core/keeper/keeper.go file are verified to be correctly implemented as per the review comment's approval.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Search for calls to NewKeeper and ensure they initialize ClientKeeper and PortKeeper as pointers.
ast-grep --lang go --pattern $'NewKeeper($_, $_, $_, $_, $_, $_, $_)'

Length of output: 70



Script:

#!/bin/bash
# Use a more general pattern with ast-grep to find calls to NewKeeper
ast-grep --lang go --pattern $'NewKeeper($$$)'

# Use rg to search for the function name across all Go files to ensure no calls are missed
rg 'NewKeeper' --type go

Length of output: 17339

modules/core/02-client/types/errors.go (1)
  • 40-40: The addition of ErrClientTypeNotSupported with a unique error code and descriptive message is appropriate for handling unsupported client types. This aligns well with the PR's objectives to enhance flexibility in client and consensus state validation.
modules/core/02-client/types/client.go (1)
  • 25-29: The introduction of the ConsensusHost interface with methods for consensus state validation is a significant enhancement. It provides a clear and flexible contract for implementing custom validation logic, supporting the PR's goal of extending IBC's compatibility with various consensus mechanisms.
testing/simapp/upgrades/upgrades.go (1)
  • 82-82: Passing clientKeeper as a pointer in the PruneExpiredConsensusStates function call is correctly aligned with the updated function signature. This ensures the function operates as intended with the provided clientKeeper.
modules/core/02-client/migrations/v7/genesis_test.go (2)
  • 36-36: Dereferencing ClientKeeper in the ExportGenesis function call is correctly done to match the updated function signature. This ensures the function is called with the appropriate argument type.
  • 111-111: Dereferencing ClientKeeper in the ExportGenesis function call is correctly done to match the updated function signature. This ensures the function is called with the appropriate argument type.
modules/light-clients/07-tendermint/consensus_host.go (1)
  • 24-39: The introduction of the ConsensusHost struct and StakingKeeper interface for the Tendermint light client, along with the implementation of the ConsensusHost interface methods, is well-executed. These additions provide the necessary functionality for custom validation logic in the Tendermint light client, aligning with the PR's objectives.
modules/core/migrations/v7/genesis_test.go (2)
  • 64-64: Dereferencing ClientKeeper in the ExportGenesis function call is correctly done to match the updated function signature. This ensures the function is called with the appropriate argument type.
  • 138-138: Dereferencing ClientKeeper in the ExportGenesis function call is correctly done to match the updated function signature. This ensures the function is called with the appropriate argument type.
modules/light-clients/07-tendermint/consensus_host_test.go (2)
  • 16-105: The tests for the GetSelfConsensusState method of the ConsensusHost struct are comprehensive, covering various scenarios including zero height, height greater than the latest height, and custom consensus host logic. This thorough testing ensures the method's functionality is correctly validated.
  • 107-241: The tests for the ValidateSelfClient method of the ConsensusHost struct are comprehensive, covering success cases, error cases such as frozen client and incorrect chainID, and custom self validator logic. This thorough testing ensures the method's functionality is correctly validated.
modules/core/02-client/types/genesis_test.go (1)
  • 35-35: The change to dereference suite.chainA.App.GetIBCKeeper().ClientKeeper when passing it to ExportGenesis seems appropriate, assuming the ExportGenesis function's signature now expects a ClientKeeper object directly instead of a pointer. Please ensure this change aligns with the updated function signature.
modules/core/02-client/keeper/keeper.go (3)
  • 30-30: The addition of the consensusHost field to the Keeper struct is a significant change. It's crucial to ensure that this new field is properly documented to explain its purpose and how it's used within the Keeper methods.

Consider adding a comment above the consensusHost field in the Keeper struct to explain its role, especially how it enables custom validation logic for different consensus mechanisms.

  • 315-315: The use of k.consensusHost.GetSelfConsensusState within GetSelfConsensusState method is a good implementation of the ConsensusHost interface. However, ensure that there's a fallback or error handling in case consensusHost is nil, which could happen if it's not set explicitly after the keeper is initialized.
Verification successful

The analysis of the provided script output and the surrounding context in handshake.go suggests that while there are no explicit nil checks for consensusHost immediately before the calls to GetSelfConsensusState, the architectural design and initialization patterns of the application likely ensure that clientKeeper and its components, including consensusHost, are non-nil when these methods are called. This is inferred from the operations performed on clientKeeper before the calls to GetSelfConsensusState, which would not be possible if clientKeeper were nil. Therefore, the original review comment's concern about ensuring a fallback or error handling for a nil consensusHost may be mitigated by the application's design and initialization process.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that all code paths that call GetSelfConsensusState ensure consensusHost is not nil.
grep -rn "GetSelfConsensusState" . --include=*.go | grep -v "keeper.go"

Length of output: 2752



Script:

#!/bin/bash
# Examine the relevant sections in handshake.go for nil checking or architectural guarantees regarding consensusHost
grep -A 10 -B 10 "GetSelfConsensusState" ./modules/core/03-connection/keeper/handshake.go

Length of output: 2104

* 323-323: The `ValidateSelfClient` method correctly delegates the validation logic to the `consensusHost`, aligning with the PR's objective to support diverse consensus mechanisms. This approach enhances modularity and extensibility.
modules/core/03-connection/keeper/handshake_test.go (1)
  • 222-236: The addition of the test case "override self consensus host" is a valuable contribution to ensuring the new ConsensusHost functionality behaves as expected when a custom validation logic is provided. This test case effectively simulates a scenario where the self consensus host's validation logic fails, which is crucial for testing the flexibility and extensibility of the IBC connection handshake process.
modules/core/02-client/keeper/keeper_test.go (2)
  • 47-47: Consolidating variable declarations for testClientHeight improves readability and maintainability by grouping related declarations together. This change aligns with best practices for code organization.
  • 84-84: Updating the assignment of suite.keeper in the SetupTest function to use the app.IBCKeeper.ClientKeeper directly is a good practice. It ensures that the test suite uses the same keeper instance as the application, which can help avoid inconsistencies and makes the test setup more straightforward.
modules/light-clients/08-wasm/testing/simapp/app.go (1)
  • 421-421: The addition of a blank line in the NewSimApp function is a minor formatting change and does not impact the functionality of the code. However, it's essential to maintain consistent formatting throughout the codebase for readability and maintainability.

modules/core/02-client/types/genesis_test.go Show resolved Hide resolved
modules/core/02-client/keeper/keeper.go Show resolved Hide resolved
modules/core/02-client/keeper/keeper.go Show resolved Hide resolved
modules/core/genesis.go Show resolved Hide resolved
modules/core/genesis.go Show resolved Hide resolved
modules/light-clients/08-wasm/types/consensus_host.go Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 0

Configuration used: .coderabbit.yml

Commits Files that changed from the base of the PR and between 0e8ba03 and ef6c625.
Files selected for processing (1)
  • modules/light-clients/08-wasm/types/consensus_host.go (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • modules/light-clients/08-wasm/types/consensus_host.go

@crodriguezvega crodriguezvega added priority PRs that need prompt reviews backport-to-v8.2.x labels Mar 26, 2024
Copy link
Contributor

@crodriguezvega crodriguezvega 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 pulling out these changes from the feat branch, @damiannolan and @chatton. I will review more thoroughly later today, but the changes are looking good to me.

There are theoretically several API breaking changes, but I wonder if we need to document all of them, since I am not sure the changes are in functions that users will use? Like for example the change in BeginBlocker or in the client keeper NewMigrator function... What do you guys think? And do you think it will be manageable to revert these API breaking changes when back porting to v8.2?

I can also start working on adding docs for this and open a separate PR for it.

We should also add changelog for this PR. :)

Copy link
Member

@AdityaSripal AdityaSripal left a comment

Choose a reason for hiding this comment

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

Approved, will the work on routing and client modules remove the need for a separate 08-wasm consensus host?

Ideally a tendermint chain can support counterparty clients being implemented in go or wasm

@damiannolan
Copy link
Member Author

Approved, will the work on routing and client modules remove the need for a separate 08-wasm consensus host?

Ideally a tendermint chain can support counterparty clients being implemented in go or wasm

Pasting what I wrote in dms for documenting purposes:

I’ll try to refresh my head a bit around the wasm client state wrapper a bit more, but looking briefly - its because the wrapped type (envelope) still contains the crucial part of info we need for instantiating the contract - the checksum. And currently, even with the changes we’ve made for client routing, we don’t have a way to plumb through this “secondary level routing info” through the client APIs.
However, I think the wrapper is only technically needed for this routing in the beginning with Initialize / instatiateContract.
The relayer can probably always pass the envelope on CreateClient but the contract could then technically store its own client state as the unwrapped client. (I think it would still need to be marshalled to an Any tho, in order to conform to the rest of the ibc code - e.g. I think this is important for UpgradeClient)

At the moment, contracts are actually prevented from storing whatever they want due to this function (so this would need to be modified): https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/08-wasm/types/vm.go#L235-L263

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review Status

Configuration used: .coderabbit.yml

Commits Files that changed from the base of the PR and between fc4d349 and 437adda.
Files selected for processing (1)
  • modules/light-clients/07-tendermint/consensus_host_test.go (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • modules/light-clients/07-tendermint/consensus_host_test.go

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Review Status

Configuration used: .coderabbit.yml

Commits Files that changed from the base of the PR and between 437adda and cf239f5.
Files selected for processing (1)
  • modules/light-clients/08-wasm/types/consensus_host_test.go (1 hunks)
Additional Context Used
GitHub Check Runs (1)
lint failure (5)

modules/light-clients/08-wasm/types/consensus_host_test.go: [failure] 5-5:
File is not gci-ed with --skip-generated -s standard -s default -s blank -s dot -s prefix(cosmossdk.io) -s prefix(github.com/cosmos/cosmos-sdk) -s prefix(github.com/cometbft/cometbft) -s prefix(github.com/cosmos/ibc-go) --custom-order (gci)


modules/light-clients/08-wasm/types/consensus_host_test.go: [failure] 15-15:
File is not gofumpt-ed (gofumpt)


modules/light-clients/08-wasm/types/consensus_host_test.go: [warning] 14-14:
unused-receiver: method receiver 'suite' is not referenced in method's body, consider removing or renaming it as _ (revive)

Path-based Instructions (1)
modules/light-clients/08-wasm/types/consensus_host_test.go (2)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.


Pattern **/*_test.go: "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request"

Additional comments not posted (2)
modules/light-clients/08-wasm/types/consensus_host_test.go (2)

15-15: Format the file with gofumpt to adhere to the Golang style guide.


18-97: Ensure comprehensive test coverage for the ConsensusHost interface, particularly focusing on the various failure and success scenarios outlined. It's crucial to validate the behavior of the interface under different conditions to ensure robustness and reliability of the IBC protocol enhancements.

Additionally, consider adding more detailed test cases that cover edge cases and more complex scenarios, especially those involving interactions with the WASM clients and the Tendermint consensus mechanism. This will help in ensuring that the ConsensusHost interface works as expected across a wide range of situations and client types.


import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
Copy link
Contributor

Choose a reason for hiding this comment

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

Apply the recommended import order to conform with the Golang style guide.

import (
+	"github.com/cosmos/cosmos-sdk/codec"
+	sdk "github.com/cosmos/cosmos-sdk/types"
+	wasmtesting "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/testing"
+	"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"
+	clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
+	"github.com/cosmos/ibc-go/v8/modules/core/exported"
+	ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint"
+	"github.com/cosmos/ibc-go/v8/testing/mock"
-	"github.com/cosmos/cosmos-sdk/codec"
-	sdk "github.com/cosmos/cosmos-sdk/types"
-	wasmtesting "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/testing"
-	"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"
-	clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
-	"github.com/cosmos/ibc-go/v8/modules/core/exported"
-	ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint"
-	"github.com/cosmos/ibc-go/v8/testing/mock"
)

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
sdk "github.com/cosmos/cosmos-sdk/types"
import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
wasmtesting "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/testing"
"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"
clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
"github.com/cosmos/ibc-go/v8/modules/core/exported"
ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint"
"github.com/cosmos/ibc-go/v8/testing/mock"
)

Copy link
Contributor

@charleenfei charleenfei left a comment

Choose a reason for hiding this comment

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

super nice work @chatton @damiannolan <3

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Review Status

Configuration used: .coderabbit.yml

Commits Files that changed from the base of the PR and between cf239f5 and afb3de2.
Files selected for processing (2)
  • modules/light-clients/08-wasm/types/consensus_host.go (1 hunks)
  • modules/light-clients/08-wasm/types/consensus_host_test.go (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • modules/light-clients/08-wasm/types/consensus_host_test.go
Additional Context Used
Path-based Instructions (1)
modules/light-clients/08-wasm/types/consensus_host.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

Comment on lines +15 to +21
// WasmConsensusHost implements the 02-client types.ConsensusHost interface.
type WasmConsensusHost struct {
cdc codec.BinaryCodec
delegate clienttypes.ConsensusHost
}

var _ clienttypes.ConsensusHost = (*WasmConsensusHost)(nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider documenting the WasmConsensusHost struct and its methods to improve code readability and maintainability.

+ // WasmConsensusHost wraps a delegate ConsensusHost to provide wasm-specific logic for consensus state and client validation.
  type WasmConsensusHost struct {
+   // cdc is the codec used for marshaling and unmarshaling data.
    cdc      codec.BinaryCodec
+   // delegate is the underlying ConsensusHost that performs the actual consensus state and client validation logic.
    delegate clienttypes.ConsensusHost
  }

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
// WasmConsensusHost implements the 02-client types.ConsensusHost interface.
type WasmConsensusHost struct {
cdc codec.BinaryCodec
delegate clienttypes.ConsensusHost
}
var _ clienttypes.ConsensusHost = (*WasmConsensusHost)(nil)
// WasmConsensusHost wraps a delegate ConsensusHost to provide wasm-specific logic for consensus state and client validation.
type WasmConsensusHost struct {
// cdc is the codec used for marshaling and unmarshaling data.
cdc codec.BinaryCodec
// delegate is the underlying ConsensusHost that performs the actual consensus state and client validation logic.
delegate clienttypes.ConsensusHost
}
var _ clienttypes.ConsensusHost = (*WasmConsensusHost)(nil)

Comment on lines +24 to +37
func NewWasmConsensusHost(cdc codec.BinaryCodec, delegate clienttypes.ConsensusHost) (*WasmConsensusHost, error) {
if cdc == nil {
return nil, fmt.Errorf("wasm consensus host codec is nil")
}

if delegate == nil {
return nil, fmt.Errorf("wasm delegate consensus host is nil")
}

return &WasmConsensusHost{
cdc: cdc,
delegate: delegate,
}, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Ensure error messages are consistent and informative. Consider including more context in the error messages for NewWasmConsensusHost.

-		return nil, fmt.Errorf("wasm consensus host codec is nil")
+		return nil, fmt.Errorf("cannot create WasmConsensusHost: codec is nil")
-		return nil, fmt.Errorf("wasm delegate consensus host is nil")
+		return nil, fmt.Errorf("cannot create WasmConsensusHost: delegate consensus host is nil")

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
func NewWasmConsensusHost(cdc codec.BinaryCodec, delegate clienttypes.ConsensusHost) (*WasmConsensusHost, error) {
if cdc == nil {
return nil, fmt.Errorf("wasm consensus host codec is nil")
}
if delegate == nil {
return nil, fmt.Errorf("wasm delegate consensus host is nil")
}
return &WasmConsensusHost{
cdc: cdc,
delegate: delegate,
}, nil
}
func NewWasmConsensusHost(cdc codec.BinaryCodec, delegate clienttypes.ConsensusHost) (*WasmConsensusHost, error) {
if cdc == nil {
return nil, fmt.Errorf("cannot create WasmConsensusHost: codec is nil")
}
if delegate == nil {
return nil, fmt.Errorf("cannot create WasmConsensusHost: delegate consensus host is nil")
}
return &WasmConsensusHost{
cdc: cdc,
delegate: delegate,
}, nil
}

Comment on lines 59 to 85
// ValidateSelfClient implements the 02-client types.ConsensusHost interface.
func (w *WasmConsensusHost) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientState) error {
if w.cdc == nil {
return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "wasm consensus host codec is nil")
}

if w.delegate == nil {
return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "wasm delegate consensus host is nil")
}

wasmClientState, ok := clientState.(*ClientState)
if !ok {
return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "client must be a wasm client, expected: %T, got: %T", ClientState{}, wasmClientState)
}

if wasmClientState.Data == nil {
return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "wasm client state data is nil")
}

// unmarshal the wasmClientState bytes into the ClientState interface and call self validation
var unwrappedClientState exported.ClientState
if err := w.cdc.UnmarshalInterface(wasmClientState.Data, &unwrappedClientState); err != nil {
return err
}

return w.delegate.ValidateSelfClient(ctx, unwrappedClientState)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Move the nil check for w to the beginning of the ValidateSelfClient method to prevent potential nil pointer dereference errors.

+	if w == nil {
+		return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "wasm consensus host is nil")
+	}

Add this check at the start of the method.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
// ValidateSelfClient implements the 02-client types.ConsensusHost interface.
func (w *WasmConsensusHost) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientState) error {
if w.cdc == nil {
return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "wasm consensus host codec is nil")
}
if w.delegate == nil {
return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "wasm delegate consensus host is nil")
}
wasmClientState, ok := clientState.(*ClientState)
if !ok {
return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "client must be a wasm client, expected: %T, got: %T", ClientState{}, wasmClientState)
}
if wasmClientState.Data == nil {
return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "wasm client state data is nil")
}
// unmarshal the wasmClientState bytes into the ClientState interface and call self validation
var unwrappedClientState exported.ClientState
if err := w.cdc.UnmarshalInterface(wasmClientState.Data, &unwrappedClientState); err != nil {
return err
}
return w.delegate.ValidateSelfClient(ctx, unwrappedClientState)
}
// ValidateSelfClient implements the 02-client types.ConsensusHost interface.
func (w *WasmConsensusHost) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientState) error {
if w == nil {
return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "wasm consensus host is nil")
}
if w.cdc == nil {
return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "wasm consensus host codec is nil")
}
if w.delegate == nil {
return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "wasm delegate consensus host is nil")
}
wasmClientState, ok := clientState.(*ClientState)
if !ok {
return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "client must be a wasm client, expected: %T, got: %T", ClientState{}, wasmClientState)
}
if wasmClientState.Data == nil {
return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "wasm client state data is nil")
}
// unmarshal the wasmClientState bytes into the ClientState interface and call self validation
var unwrappedClientState exported.ClientState
if err := w.cdc.UnmarshalInterface(wasmClientState.Data, &unwrappedClientState); err != nil {
return err
}
return w.delegate.ValidateSelfClient(ctx, unwrappedClientState)
}

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review Status

Configuration used: .coderabbit.yml

Commits Files that changed from the base of the PR and between afb3de2 and 9b9ea03.
Files selected for processing (1)
  • modules/light-clients/08-wasm/testing/simapp/app.go (1 hunks)
Additional Context Used
Path-based Instructions (1)
modules/light-clients/08-wasm/testing/simapp/app.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

Additional comments not posted (2)
modules/light-clients/08-wasm/testing/simapp/app.go (2)

421-421: The addition of a blank line after initializing IBCKeeper is a minor stylistic change and is acceptable.


421-421: Ensure that the updated deprecation comment regarding the registration of proposal types is clear and informative, guiding future developers on handling this deprecated functionality.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review Status

Configuration used: .coderabbit.yml

Commits Files that changed from the base of the PR and between 9b9ea03 and 7ac83fd.
Files selected for processing (3)
  • modules/light-clients/07-tendermint/consensus_host_test.go (1 hunks)
  • modules/light-clients/08-wasm/types/consensus_host.go (1 hunks)
  • modules/light-clients/08-wasm/types/consensus_host_test.go (1 hunks)
Files skipped from review as they are similar to previous changes (3)
  • modules/light-clients/07-tendermint/consensus_host_test.go
  • modules/light-clients/08-wasm/types/consensus_host.go
  • modules/light-clients/08-wasm/types/consensus_host_test.go

Copy link

sonarqubecloud bot commented Apr 3, 2024

Quality Gate Passed Quality Gate passed for 'ibc-go'

Issues
1 New issue
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
No data about Duplication

See analysis details on SonarCloud

@damiannolan damiannolan enabled auto-merge (squash) April 3, 2024 12:56
@damiannolan
Copy link
Member Author

Let's add something in migration doc in a follow up. cc @chatton

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review Status

Configuration used: .coderabbit.yml

Commits Files that changed from the base of the PR and between 7ac83fd and 26cd5d1.
Files selected for processing (1)
  • CHANGELOG.md (1 hunks)
Additional Context Used
Path-based Instructions (1)
CHANGELOG.md (1)

Pattern **/*.md: "Assess the documentation for misspellings, grammatical errors, missing documentation and correctness"

Additional comments not posted (1)
CHANGELOG.md (1)

56-56: The documentation of the addition of the ConsensusHost interface is clear and concise.

@damiannolan damiannolan merged commit 50d2a08 into main Apr 3, 2024
84 of 86 checks passed
@damiannolan damiannolan deleted the damian/cian/ibc-consensus-host branch April 3, 2024 13:00
mergify bot pushed a commit that referenced this pull request Apr 8, 2024
…us state validation (#6055)

Co-authored-by: chatton <github.qpeyb@simplelogin.fr>
(cherry picked from commit 50d2a08)

# Conflicts:
#	CHANGELOG.md
#	modules/core/02-client/keeper/keeper.go
#	modules/core/02-client/keeper/keeper_test.go
#	modules/core/02-client/types/errors.go
#	modules/light-clients/08-wasm/testing/simapp/app.go
damiannolan added a commit that referenced this pull request Apr 10, 2024
…us state validation (backport #6055) (#6111)

* feat: adding `ConsensusHost` interface for custom self client/consensus state validation (#6055)

Co-authored-by: chatton <github.qpeyb@simplelogin.fr>
(cherry picked from commit 50d2a08)

# Conflicts:
#	CHANGELOG.md
#	modules/core/02-client/keeper/keeper.go
#	modules/core/02-client/keeper/keeper_test.go
#	modules/core/02-client/types/errors.go
#	modules/light-clients/08-wasm/testing/simapp/app.go

* chore: resolve conflicts and adapt api breaking changes

* refactor: rm api breaking changes for consensus host feature

* chore: readd staking keeper to reduce diffs

* chore: adapt last api breaking changes

---------

Co-authored-by: Damian Nolan <damiannolan@gmail.com>
mergify bot pushed a commit that referenced this pull request Jun 10, 2024
…us state validation (#6055)

Co-authored-by: chatton <github.qpeyb@simplelogin.fr>
(cherry picked from commit 50d2a08)

# Conflicts:
#	CHANGELOG.md
#	modules/core/02-client/keeper/keeper.go
#	modules/core/02-client/keeper/keeper_test.go
#	modules/core/02-client/types/errors.go
crodriguezvega pushed a commit that referenced this pull request Jun 16, 2024
…us state validation (backport #6055) (#6547)

* feat: adding `ConsensusHost` interface for custom self client/consensus state validation (#6055)

Co-authored-by: chatton <github.qpeyb@simplelogin.fr>
(cherry picked from commit 50d2a08)

# Conflicts:
#	CHANGELOG.md
#	modules/core/02-client/keeper/keeper.go
#	modules/core/02-client/keeper/keeper_test.go
#	modules/core/02-client/types/errors.go

* restore changes from release/v8.3.x

* chore: update changelog

---------

Co-authored-by: Damian Nolan <damiannolan@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport-to-v8.3.x priority PRs that need prompt reviews
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Remove Hardcoding of Tendermint Client Validation in Connection Handshake
5 participants