docs: learn/advance (#22367)

This commit is contained in:
Julián Toledano
2024-10-25 15:04:42 +00:00
committed by GitHub
parent 49e1bc2073
commit 9f79dd39f5
7 changed files with 54 additions and 52 deletions
+7 -7
View File
@@ -16,7 +16,7 @@ While encoding in the Cosmos SDK used to be mainly handled by `go-amino` codec,
## Encoding
The Cosmos SDK supports two wire encoding protocols. Binary encoding is fulfilled by [Protocol
The Cosmos SDK supports two wire encoding protocols. Binary encoding is fulfilled by [Protocol
Buffers](https://protobuf.dev/), specifically the
[gogoprotobuf](https://github.com/cosmos/gogoproto/) implementation, which is a subset of
[Proto3](https://protobuf.dev/programming-guides/proto3/) with an extension for
@@ -37,11 +37,11 @@ but may choose any encoding schema they like. The
[collections](../../build/packages/02-collections.md) package automatically handles encoding and
decoding of state for you.
In the `codec` package, there exists two core interfaces, `BinaryCodec` and `JSONCodec`,
In the `codec` package, there exist two core interfaces, `BinaryCodec` and `JSONCodec`,
where the former encapsulates the current Amino interface except it operates on
types implementing the latter instead of generic `interface{}` types.
The `ProtoCodec`, where both binary and JSON serialization is handled via Protobuf. This means
The `ProtoCodec`, where both binary and JSON serialization are handled via Protobuf. This means
that modules may use Protobuf encoding, but the types must implement `ProtoMarshaler`. If
modules wish to avoid implementing this interface for their types, this is autogenerated via
[buf](https://buf.build/)
@@ -75,7 +75,7 @@ the consensus engine accepts only transactions in the form of raw bytes.
* The `TxDecoder` object performs the decoding.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/types/tx_msg.go#L91-L95
https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/types/tx_msg.go#L117-L121
```
A standard implementation of both these objects can be found in the [`auth/tx` module](https://docs.cosmos.network/main/build/modules/auth#transactions):
@@ -104,7 +104,7 @@ message Profile {
In this `Profile` example, we hardcoded `account` as a `BaseAccount`. However, there are several other types of [user accounts related to vesting](https://docs.cosmos.network/main/build/modules/auth/vesting), such as `BaseVestingAccount` or `ContinuousVestingAccount`. All of these accounts are different, but they all implement the `AccountI` interface. How would you create a `Profile` that allows all these types of accounts with an `account` field that accepts an `AccountI` interface?
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/account.go#L15-L32
https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/types/account.go#L15-L32
```
In [ADR-019](../../architecture/adr-019-protobuf-state-encoding.md), it has been decided to use [`Any`](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto)s to encode interfaces in protobuf. An `Any` contains an arbitrary serialized message as bytes, along with a URL that acts as a globally unique identifier for and resolves to that message's type. This strategy allows us to pack arbitrary Go types inside protobuf messages. Our new `Profile` then looks like:
@@ -143,7 +143,7 @@ bz, err := cdc.Marshal(profile)
jsonBz, err := cdc.MarshalJSON(profile)
```
To summarize, to encode an interface, you must 1/ pack the interface into an `Any` and 2/ marshal the `Any`. For convenience, the Cosmos SDK provides a `MarshalInterface` method to bundle these two steps. Have a look at [a real-life example in the x/auth module](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/keeper/keeper.go#L240-L243).
To summarize, to encode an interface, you must 1/ pack the interface into an `Any` and 2/ marshal the `Any`. For convenience, the Cosmos SDK provides a `MarshalInterface` method to bundle these two steps. Have a look at [a real-life example in the x/auth module](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/x/auth/keeper/keeper.go#L262-L264).
The reverse operation of retrieving the concrete Go type from inside an `Any`, called "unpacking", is done with the `GetCachedValue()` on `Any`.
@@ -192,7 +192,7 @@ The above `Profile` example is a fictive example used for educational purposes.
A real-life example of encoding the pubkey as `Any` inside the Validator struct in x/staking is shown in the following example:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/staking/types/validator.go#L41-L64
https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/x/staking/types/validator.go#L43-L63
```
#### `Any`'s TypeURL