Skip to content

Commit

Permalink
docs: final review of light client developer guide (cosmos#3081)
Browse files Browse the repository at this point in the history
Co-authored-by: crodriguezvega <[email protected]>
  • Loading branch information
tmsdkeys and crodriguezvega authored Feb 9, 2023
1 parent e6247d3 commit fdadae5
Show file tree
Hide file tree
Showing 16 changed files with 248 additions and 209 deletions.
29 changes: 12 additions & 17 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -352,49 +352,44 @@ module.exports = {
path: "/ibc/light-clients/overview.html",
},
{
title: "ClientState",
title: "Client State interface",
directory: false,
path: "/ibc/light-clients/client-state.html",
},
{
title: "ConsensusState",
title: "Consensus State interface",
directory: false,
path: "/ibc/light-clients/consensus-state.html",
},
{
title: "Setup",
directory: false,
path: "/ibc/light-clients/setup.html",
},
{
title: "Updates Handling",
title: "Handling Updates and Misbehaviour",
directory: false,
path: "/ibc/light-clients/update.html",
path: "/ibc/light-clients/updates-and-misbehaviour.html",
},
{
title: "Misbehaviour Handling",
title: "Handling Upgrades",
directory: false,
path: "/ibc/light-clients/misbehaviour.html",
path: "/ibc/light-clients/upgrades.html",
},
{
title: "Existence/Non-Existence Proofs",
directory: false,
path: "/ibc/light-clients/proofs.html",
},
{
title: "Upgrades Handling",
title: "Handling Proposals",
directory: false,
path: "/ibc/light-clients/upgrade.html",
path: "/ibc/light-clients/proposals.html",
},
{
title: "Proposal Handling",
title: "Handling Genesis",
directory: false,
path: "/ibc/light-clients/proposal.html",
path: "/ibc/light-clients/genesis.html",
},
{
title: "Genesis Handling",
title: "Setup",
directory: false,
path: "/ibc/light-clients/genesis.html",
path: "/ibc/light-clients/setup.html",
},
]
},
Expand Down
18 changes: 9 additions & 9 deletions docs/architecture/adr-001-coin-source-tracing.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ trace the token back to the originating chain, as specified on ICS20.

The new proposed format will be the following:

```golang
```go
ibcDenom = "ibc/" + hash(trace path + "/" + base denom)
```

Expand All @@ -133,7 +133,7 @@ message DenomTrace {

The `IBCDenom` function constructs the `Coin` denomination used when creating the ICS20 fungible token packet data:

```golang
```go
// Hash returns the hex bytes of the SHA256 hash of the DenomTrace fields using the following formula:
//
// hash = sha256(tracePath + "/" + baseDenom)
Expand All @@ -157,7 +157,7 @@ In order to retrieve the trace information from an IBC denomination, a lookup ta
added to the `ibc-transfer` module. These values need to also be persisted between upgrades, meaning
that a new `[]DenomTrace` `GenesisState` field state needs to be added to the module:

```golang
```go
// GetDenomTrace retrieves the full identifiers trace and base denomination from the store.
func (k Keeper) GetDenomTrace(ctx Context, denomTraceHash []byte) (DenomTrace, bool) {
store := ctx.KVStore(k.storeKey)
Expand Down Expand Up @@ -188,14 +188,14 @@ func (k Keeper) SetDenomTrace(ctx Context, denomTrace DenomTrace) {
The `MsgTransfer` will validate that the `Coin` denomination from the `Token` field contains a valid
hash, if the trace info is provided, or that the base denominations matches:

```golang
```go
func (msg MsgTransfer) ValidateBasic() error {
// ...
return ValidateIBCDenom(msg.Token.Denom)
}
```

```golang
```go
// ValidateIBCDenom validates that the given denomination is either:
//
// - A valid base denomination (eg: 'uatom')
Expand Down Expand Up @@ -226,7 +226,7 @@ The denomination trace info only needs to be updated when token is received:
- Receiver is **source** chain: The receiver created the token and must have the trace lookup already stored (if necessary _ie_ native token case wouldn't need a lookup).
- Receiver is **not source** chain: Store the received info. For example, during step 1, when chain `B` receives `transfer/channelToA/denom`.

```golang
```go
// SendTransfer
// ...

Expand All @@ -245,7 +245,7 @@ if types.SenderChainIsSource(sourcePort, sourceChannel, fullDenomPath) {
//...
```
```golang
```go
// DenomPathFromHash returns the full denomination path prefix from an ibc denom with a hash
// component.
func (k Keeper) DenomPathFromHash(ctx sdk.Context, denom string) (string, error) {
Expand All @@ -266,7 +266,7 @@ func (k Keeper) DenomPathFromHash(ctx sdk.Context, denom string) (string, error)
```
```golang
```go
// OnRecvPacket
// ...

Expand Down Expand Up @@ -322,7 +322,7 @@ return k.bankKeeper.SendCoinsFromModuleToAccount(
)
```
```golang
```go
func NewDenomTraceFromRawDenom(denom string) DenomTrace{
denomSplit := strings.Split(denom, "/")
trace := ""
Expand Down
4 changes: 2 additions & 2 deletions docs/dev/go-style-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Perhaps more key for code readability than good commenting is having the right s
- Use [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports).
- Separate imports into blocks: one for the standard lib, one for external libs and one for application libs. For example:

```golang
```go
import (
// standard library imports
"fmt"
Expand Down Expand Up @@ -105,7 +105,7 @@ Perhaps more key for code readability than good commenting is having the right s
- Panic is appropriate when an internal invariant of a system is broken, while all other cases (in particular, incorrect or invalid usage) should return errors.
- Error messages should be formatted as following:

```golang
```go
sdkerrors.Wrapf(
<most specific error type possible>,
"<optional text description ended by colon and space>expected %s, got %s",
Expand Down
15 changes: 8 additions & 7 deletions docs/ibc/integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Integrating the IBC module to your SDK-based application is straighforward. The

- Add required modules to the `module.BasicManager`
- Define additional `Keeper` fields for the new modules on the `App` type
- Add the module's `StoreKeys` and initialize their `Keepers`
- Add the module's `StoreKey`s and initialize their `Keeper`s
- Set up corresponding routers and routes for the `ibc` module
- Add the modules to the module `Manager`
- Add modules to `Begin/EndBlockers` and `InitGenesis`
Expand All @@ -28,10 +28,10 @@ The first step is to add the following modules to the `BasicManager`: `x/capabil
and `x/ibc-transfer`. After that, we need to grant `Minter` and `Burner` permissions to
the `ibc-transfer` `ModuleAccount` to mint and burn relayed tokens.

### Integrating Light Clients
### Integrating light clients

> Note that from v7 onwards, all light clients have to be explicitly registered in a chain's app.go and follow the steps listed below.
This is in contrast to earlier versions of ibc-go when 07-tendermint and 06-solomachine were added out of the box.
This is in contrast to earlier versions of ibc-go when `07-tendermint` and `06-solomachine` were added out of the box.

All light clients must be registered with `module.BasicManager` in a chain's app.go file.

Expand All @@ -40,9 +40,9 @@ The following code example shows how to register the existing `ibctm.AppModuleBa
```diff

import (
...
+ ibctm "github.com/cosmos/ibc-go/v6/modules/light-clients/07-tendermint"
...
...
+ ibctm "github.com/cosmos/ibc-go/v6/modules/light-clients/07-tendermint"
...
)

// app.go
Expand All @@ -55,14 +55,15 @@ var (
transfer.AppModuleBasic{}, // i.e ibc-transfer module

// register light clients on IBC
+ ibctm.AppModuleBasic{},
+ ibctm.AppModuleBasic{},
)

// module account permissions
maccPerms = map[string][]string{
// other module accounts permissions
// ...
ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner},
}
)
```

Expand Down
32 changes: 16 additions & 16 deletions docs/ibc/light-clients/client-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ order: 2

# Implementing the `ClientState` interface

Learn how to implement the [`ClientState`](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/core/exported/client.go#L40) interface.
Learn how to implement the [`ClientState`](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/core/exported/client.go#L40) interface. This list of methods described here does not include all methods of the interface. Some methods are explained in detail in the relevant sections of the guide.

## `ClientType` method

Expand All @@ -18,27 +18,27 @@ The format is created as follows: `ClientType-{N}` where `{N}` is the unique glo
## `Validate` method

`Validate` should validate every client state field and should return an error if any value is invalid. The light client
implementer is in charge of determining which checks are required. See the [tendermint light client implementation](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/light-clients/07-tendermint/types/client_state.go#L101) as a reference.
implementer is in charge of determining which checks are required. See the [Tendermint light client implementation](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/light-clients/07-tendermint/types/client_state.go#L101) as a reference.

## `Status` method

`Status` must return the status of the client.

- An `Active` status indicates that clients are allowed to process packets.
- A `Frozen` status indicates that a client is not allowed to be used.
- An `Expired` status indicates that a client is not allowed to be used.
- A `Frozen` status indicates that misbehaviour was detected in the counterparty chain and the client is not allowed to be used.
- An `Expired` status indicates that a client is not allowed to be used because it was not updated for longer than the trusting period.
- An `Unknown` status indicates that there was an error in determining the status of a client.

All possible Status types can be found [here](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/core/exported/client.go#L26-L36).
All possible `Status` types can be found [here](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/core/exported/client.go#L26-L36).

This field is returned by the gRPC [QueryClientStatusResponse](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/core/02-client/types/query.pb.go#L665) endpoint.
This field is returned in the response of the gRPC [`ibc.core.client.v1.Query/ClientStatus`](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/core/02-client/types/query.pb.go#L665) endpoint.

## `ZeroCustomFields` method

`ZeroCustomFields` should return a copy of the light client with all client customizable fields with their zero value. It should not mutate the fields of the light client.
This method is used when [scheduling upgrades](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/core/02-client/keeper/proposal.go#L89). Upgrades are used to upgrade chain specific fields.
In the tendermint case, this may be the chainID or the unbonding period.
For more information about client upgrades see [the developer guide](../upgrades/developer-guide.md).
In the tendermint case, this may be the chain ID or the unbonding period.
For more information about client upgrades see the [Handling upgrades](./upgrades.md) section.

## `GetTimestampAtHeight` method

Expand All @@ -54,22 +54,22 @@ Clients may also store any necessary client-specific metadata.

## `VerifyMembership` method

`VerifyMembership` must verify the existence of a value at a given CommitmentPath at the specified height. For more information about membership proofs
see [the proof docs](./proofs.md).
`VerifyMembership` must verify the existence of a value at a given commitment path at the specified height. For more information about membership proofs
see the [Existence and non-existence proofs section](./proofs.md).

## `VerifyNonMembership` method

`VerifyNonMembership` must verify the absence of a value at a given CommitmentPath at a specified height. For more information about non membership proofs
see [the proof docs](./proofs.md).
`VerifyNonMembership` must verify the absence of a value at a given commitment path at a specified height. For more information about non-membership proofs
see the [Existence and non-existence proofs section](./proofs.md).

## `VerifyClientMessage` method

VerifyClientMessage must verify a ClientMessage. A ClientMessage could be a Header, Misbehaviour, or batch update.
It must handle each type of ClientMessage appropriately. Calls to CheckForMisbehaviour, UpdateState, and UpdateStateOnMisbehaviour
will assume that the content of the ClientMessage has been verified and can be trusted. An error should be returned
`VerifyClientMessage` must verify a `ClientMessage`. A `ClientMessage` could be a `Header`, `Misbehaviour`, or batch update.
It must handle each type of `ClientMessage` appropriately. Calls to `CheckForMisbehaviour`, `UpdateState`, and `UpdateStateOnMisbehaviour`
will assume that the content of the `ClientMessage` has been verified and can be trusted. An error should be returned
if the ClientMessage fails to verify.

## `CheckForMisbehaviour` method

Checks for evidence of a misbehaviour in Header or Misbehaviour type. It assumes the ClientMessage
Checks for evidence of a misbehaviour in `Header` or `Misbehaviour` type. It assumes the `ClientMessage`
has already been verified.
4 changes: 3 additions & 1 deletion docs/ibc/light-clients/consensus-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ order: 3

# Implementing the `ConsensusState` interface

A `ConsensusState` is the snapshot of the counterparty chain that an IBC client uses to verify proofs (e.g. a block). The further development of multiple types of IBC light clients and the difficulties presented by this generalization problem (see [ADR-006](https://github.com/cosmos/ibc-go/blob/main/docs/architecture/adr-006-02-client-refactor.md) for more information about this historical context) led to the design decision of each client keeping track of and set its own `ClientState` and `ConsensusState`, as well as the simplification of client `ConsensusState` updates through the generalized `ClientMessage` interface.
A `ConsensusState` is the snapshot of the counterparty chain, that an IBC client uses to verify proofs (e.g. a block).

The further development of multiple types of IBC light clients and the difficulties presented by this generalization problem (see [ADR-006](https://github.com/cosmos/ibc-go/blob/main/docs/architecture/adr-006-02-client-refactor.md) for more information about this historical context) led to the design decision of each client keeping track of and set its own `ClientState` and `ConsensusState`, as well as the simplification of client `ConsensusState` updates through the generalized `ClientMessage` interface.

The below [`ConsensusState`](https://github.com/cosmos/ibc-go/blob/main/modules/core/exported/client.go#L134) interface is a generalized interface for the types of information a `ConsensusState` could contain. For a reference `ConsensusState` implementation, please see the [Tendermint light client `ConsensusState`](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/07-tendermint/consensus_state.go).

Expand Down
13 changes: 7 additions & 6 deletions docs/ibc/light-clients/genesis.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
<!--
order: 10
order: 8
-->

# Genesis Metadata
# Genesis metadata

Learn how to implement the `ExportMetadata` interface {synopsis}

## Pre-requisite Readings
## Pre-requisite readings

- [Cosmos SDK module genesis](https://docs.cosmos.network/v0.47/building-modules/genesis) {prereq}

`ClientState` instances are provided their own isolated and namespaced client store upon initialisation. `ClientState` implementations may choose to store any amount of arbitrary metadata in order to verify counterparty consensus state and perform light client updates correctly.

The `ExportMetadata` method of the `ClientState` interface provides light client modules with the ability to persist metadata in genesis exports.
The `ExportMetadata` method of the [`ClientState` interface](https://github.com/cosmos/ibc-go/blob/e650be91614ced7be687c30eb42714787a3bbc59/modules/core/exported/client.go) provides light client modules with the ability to persist metadata in genesis exports.

```go
ExportMetadata(clientStore sdk.KVStore) []GenesisMetadata
Expand All @@ -29,7 +29,8 @@ type GenesisMetadata interface {
}
```

This allows `ClientState` instances to retrieve and export any number of key-value pairs which are maintained within the store in their raw `[]byte` form.
This allows `ClientState` instances to retrieve and export any number of key-value pairs which are maintained within the store in their raw `[]byte` form.

When a chain is started with a `genesis.json` file which contains `ClientState` metadata (for example, when performing manual upgrades using an exported `genesis.json`) the `02-client` submodule of core IBC will handle setting the key-value pairs within their respective client stores. [See `02-client` `InitGenesis`](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/core/02-client/genesis.go#L18-L22).

Please refer to the [`07-tendermint` implementation](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/light-clients/07-tendermint/genesis.go#L12) as an example.
Please refer to the [Tendermint light client implementation](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/light-clients/07-tendermint/genesis.go#L12) for an example.
Loading

0 comments on commit fdadae5

Please sign in to comment.