From 9f47a9214751aa2fbb66d97c55308c1182004dcf Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 16 Mar 2021 14:34:13 +0100 Subject: [PATCH 01/28] Update v042 link --- docs/architecture/adr-041-in-place-store-migrations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/adr-041-in-place-store-migrations.md b/docs/architecture/adr-041-in-place-store-migrations.md index 072a121f5d6..4ba55466b8e 100644 --- a/docs/architecture/adr-041-in-place-store-migrations.md +++ b/docs/architecture/adr-041-in-place-store-migrations.md @@ -75,7 +75,7 @@ func (m Migrator) Migrate1to2(ctx sdk.Context) error { } ``` -Each module's migration functions are specific to the module's store evolutions, and are not described in this ADR. An example of x/bank store key migrations following the introduction of ADR-028 length-prefixed addresses can be seen [here](https://github.com/cosmos/cosmos-sdk/blob/ef8dabcf0f2ecaf26db1c6c6d5922e9399458bb3/x/bank/legacy/v042/store.go#L15). +Each module's migration functions are specific to the module's store evolutions, and are not described in this ADR. An example of x/bank store key migrations following the introduction of ADR-028 length-prefixed addresses can be seen [here](https://github.com/cosmos/cosmos-sdk/blob/36f68eb9e041e20a5bb47e216ac5eb8b91f95471/x/bank/legacy/v043/store.go#L41-L62). ### Tracking Module Versions in `x/upgrade` From 5bfab35cd20c1925a610038fee102f859babd917 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 16 Mar 2021 15:13:22 +0100 Subject: [PATCH 02/28] Add docs for events --- docs/core/events.md | 74 +++++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/docs/core/events.md b/docs/core/events.md index d199d94ced5..a0793862a6d 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -9,20 +9,28 @@ order: 9 ## Pre-requisite Readings - [Anatomy of an SDK application](../basics/app-anatomy.md) {prereq} +- [Tendermint Documentation on Events](https://docs.tendermint.com/master/spec/abci/abci.html#events) {prereq} ## Events Events are implemented in the Cosmos SDK as an alias of the ABCI `Event` type and -take the form of: `{eventType}.{eventAttribute}={value}`. +take the form of: `{eventType}.{attributeKey}={attributeValue}`. -+++ https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/types.pb.go#L2187-L2193 ++++ https://github.com/tendermint/tendermint/blob/v0.34.8/proto/tendermint/abci/types.proto#L304-L313 -Events contain: +An Event contains: -- A `type`, which is meant to categorize an event at a high-level (e.g. by module (e.g. `module=bank`) or action (e.g. `action=/cosmos.bank.v1beta1.Msg/Send`)). -- A list of `attributes`, which are key-value pairs that give more information about - the categorized `event`. - +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/events.go#L51-L56 +- A `type`, which is meant to categorize an event at a high-level, e.g. the SDK uses the `"message"` type to filter events by `Msg`s. +- A list of `attributes`, which are key-value pairs that give more information about the categorized Event. For example, for the `"message"` type, we can filter events by key-value pairs using `message.action={some_action}`, `message.module={some_module}` or `message.sender={some_sender}`. + +::: tip +If you want the attribute values to be parsed as strings, make sure to add `'` (single quotes) around each attribute value. +::: + +Events, the `type` and `attributes` are defined on a **per-module basis** in the module's +`/types/events.go` file, and triggered from the module's [`Msg` service](../building-modules/msg-services.md) +via the [`EventManager`](#eventmanager). In addition, each module documents its events under +`spec/xx_events.md`. Events are returned to the underlying consensus engine in the response of the following ABCI messages: @@ -31,10 +39,17 @@ Events are returned to the underlying consensus engine in the response of the fo - [`CheckTx`](./baseapp.md#checktx) - [`DeliverTx`](./baseapp.md#delivertx) -Events, the `type` and `attributes`, are defined on a **per-module basis** in the module's -`/types/events.go` file, and triggered from the module's [`Msg` service](../building-modules/msg-services.md) -via the [`EventManager`](#eventmanager). In addition, each module documents its events under -`spec/xx_events.md`. +### Examples + +Below are some examples of Events you can query using the SDK. + +| Event | Description | +| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `tx.height=23` | Query all transactions at height 23 | +| `message.action='/cosmos.bank.v1beta1.Msg/Send'` | Query all transactions containing a x/bank `Send` [Service `Msg`](../building-modules/msg-services.md). Note the `'`s around the value. | +| `message.action='send'` | Query all transactions containing a x/bank `Send` [legacy `Msg`](../building-modules/msg-services.md#legacy-amino-msgs). Note the `'`s around the value. | +| `message.module='bank'` | Query all transactions containing messages from the x/bank module. Note the `'`s around the value. | +| `create_validator.validator='cosmosval1...'` | x/staking-specific event, see [x/staking SPEC](../../../cosmos-sdk/x/staking/spec/07_events.md). | ## EventManager @@ -42,13 +57,13 @@ In Cosmos SDK applications, events are managed by an abstraction called the `Eve Internally, the `EventManager` tracks a list of `Events` for the entire execution flow of a transaction or `BeginBlock`/`EndBlock`. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/events.go#L16-L20 ++++ https://github.com/cosmos/cosmos-sdk/blob/21814558eaa47b018018711e5fe16e0b16811fce/types/events.go#L17-L25 The `EventManager` comes with a set of useful methods to manage events. Among them, the one that is used the most by module and application developers is the `EmitEvent` method, which tracks an `event` in the `EventManager`. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/events.go#L29-L31 ++++ https://github.com/cosmos/cosmos-sdk/blob/21814558eaa47b018018711e5fe16e0b16811fce/types/events.go#L33-L37 Module developers should handle event emission via the `EventManager#EmitEvent` in each message `Handler` and in each `BeginBlock`/`EndBlock` handler. The `EventManager` is accessed via @@ -61,6 +76,7 @@ ctx.EventManager().EmitEvent( ``` Module's `handler` function should also set a new `EventManager` to the `context` to isolate emitted events per `message`: + ```go func NewHandler(keeper Keeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { @@ -73,17 +89,17 @@ view on how to typically implement `Events` and use the `EventManager` in module ## Subscribing to Events -It is possible to subscribe to `Events` via Tendermint's [Websocket](https://tendermint.com/docs/app-dev/subscribing-to-events-via-websocket.html#subscribing-to-events-via-websocket). +It is possible to subscribe to `Events` via Tendermint's [Websocket](https://docs.tendermint.com/master/tendermint-core/subscription.html#subscribing-to-events-via-websocket). This is done by calling the `subscribe` RPC method via Websocket: ```json { - "jsonrpc": "2.0", - "method": "subscribe", - "id": "0", - "params": { - "query": "tm.event='eventCategory' AND eventType.eventAttribute='attributeValue'" - } + "jsonrpc": "2.0", + "method": "subscribe", + "id": "0", + "params": { + "query": "tm.event='eventCategory' AND eventType.eventAttribute='attributeValue'" + } } ``` @@ -100,17 +116,23 @@ The `type` and `attribute` value of the `query` allow you to filter the specific ```json { - "jsonrpc": "2.0", - "method": "subscribe", - "id": "0", - "params": { - "query": "tm.event='Tx' AND transfer.sender='senderAddress'" - } + "jsonrpc": "2.0", + "method": "subscribe", + "id": "0", + "params": { + "query": "tm.event='Tx' AND transfer.sender='senderAddress'" + } } ``` where `senderAddress` is an address following the [`AccAddress`](../basics/accounts.md#addresses) format. +## Typed Events (coming soon) + +As described above, events are defined on a per-module basis, and it is the responsability of the module developer to define event types and event attributes. Except in the `spec/XX_events.md` file, these types and attributes are unfortunately not easily discoverable, so the SDK proposes to use Protobuf-defined [Typed Events](../architecture/adr-032-typed-events.md) for emitting and querying for events. + +The Typed Events proposal has not yet been fully implemented, and its documentation will follow with a future release of the SDK. + ## Next {hide} Learn about SDK [telemetry](./telemetry.md) {hide} From fc0889362b1201d6b263aa3bbe6ffe2c524e7eb9 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 16 Mar 2021 16:14:19 +0100 Subject: [PATCH 03/28] Document usage of any --- docs/core/encoding.md | 145 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 117 insertions(+), 28 deletions(-) diff --git a/docs/core/encoding.md b/docs/core/encoding.md index a4cbddc2acd..6a4bac96384 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -69,9 +69,124 @@ typically used for when the data needs to be streamed or grouped together ### Gogoproto -Modules are encouraged to utilize Protobuf encoding for their respective types. +Modules are encouraged to utilize Protobuf encoding for their respective types. In the SDK, we use a specific implementation of the Protobuf spec, called [Gogoproto](https://github.com/gogo/protobuf), which offers speed and DX improvements compared to the official [Google implementation](https://github.com/protocolbuffers/protobuf). -#### FAQ +### Guidelines for protobuf message definitions + +In addition to [following official guidelines](https://developers.google.com/protocol-buffers/docs/proto3#simple), we recommend to use these annotations in .proto files when dealing with interfaces: + +- fields which accept interfaces should be annotated with `cosmos_proto.accepts_interface` + using the same full-qualified name passed as `protoName` to `InterfaceRegistry.RegisterInterface` +- interface implementations should be annotated with `cosmos_proto.implements_interface` + using the same full-qualified name passed as `protoName` to `InterfaceRegistry.RegisterInterface` + +### Transaction Encoding + +Another important use of Protobuf is the encoding and decoding of +[transactions](./transactions.md). Transactions are defined by the application or +the SDK, but passed to the underlying consensus engine in order to be relayed to +other peers. Since the underlying consensus engine is agnostic to the application, +it only accepts transactions in the form of raw bytes. The encoding is done by an +object called `TxEncoder` and the decoding by an object called `TxDecoder`. + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc4/types/tx_msg.go#L83-L87 + +A standard implementation of both these objects can be found in the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth): + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc4/x/auth/tx/decoder.go + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc4/x/auth/tx/encoder.go + +Please also refer to [ADR-020](../architecture/adr-020-protobuf-transaction-encoding.md) on the details of how a transaction is encoded. + +### Interface Encoding and Usage of `Any`s + +The Protobuf DSL is strongly typed, which can make inserting variable-typed fields difficult. Imagine we want to create a `Profile` protobuf message, which serves as a wrapper over [an account](../basics/accounts.md): + +```proto +message Profile { + // account is the account associated to a profile. + cosmos.auth.v1beta1.BaseAccount account = 1; + // bio is a short description of the account. + string bio = 4; +} +``` + +In the above `Profile`, we hardcoded `account` as a `BaseAccount`. However, there are several other types of [user accounts related to vesting](../../x/auth/spec/05_vesting.md), such as `BaseVestingAccount` or `ContinuousVestingAccount`. All of these accounts are different, but they all implement the `AccountI` interface. How would one create a `Profile` which allows all these types of accounts, with an `account` field accepting an `AccountI` interface? + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/auth/types/account.go#L307-L330 + +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. It allows us to pack arbitrary Go types inside protobuf messages. Our new `Profile` then looks like: + +```protobuf +message Profile { + // account is the account associated to a profile. + google.protobuf.Any account = 1 [ + (cosmos_proto.accepts_interface) = "AccountI"; // Asserts that this field only accepts Go types implementing `AccountI`. It is purely informational for now. + ]; + // bio is a short description of the account. + string bio = 4; +} +``` + +To add an account inside a profile, we need to "pack" it inside an `Any` first, using `codectypes.NewAnyWithValue`: + +```go +var myAccount AccountI +myAccount = ... // Can be a BaseAccount, a ContinuousVestingAccount or any struct implementing `AccountI` + +// Pack the account into an Any +accAny, err := codectypes.NewAnyWithValue(myAccount) +if err != nil { + return nil, err +} + +// Create a new Profile with the any. +profile := Profile { + Account: accAny, + Bio: "some bio", +} + +// We can then marshal the profile as usual. +bz, err := cdc.MarshalBinaryBare(profile) +jsonBz, err := cdc.MarshalJSON(profile) +``` + +To summarize, if you want to encode an interface, you need to 1/ pack it into an `Any` and 2/ marshal the `Any`. For convenience, the SDK provides a `MarshalInterface` method to bundle the 2 steps into one. Have a look at [a real-life example in the x/auth module](https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/auth/keeper/keeper.go#L218-L221). + +The reverse operation of retrieving the concrete Go type from inside an `Any`, called "unpacking", is done with the `GetCachedValue()` on `Any`. + +```go +profileBz := ... // The proto-encoded bytes of a Profile, e.g. retrieved through gRPC. +var myProfile Profile +// Unmarshal the bytes into the myProfile struct. +err := cdc.UnmarshalBinaryBare(profilebz, &myProfile) + +// Let's see the types of the Account field. +fmt.Printf("%T\n", myProfile.Account) // Prints "Any" +fmt.Printf("%T\n", myProfile.Account.GetCachedValue()) // Prints "BaseAccount", "ContinuousVestingAccount" or whatever was initially packed in the Any. + +// Get the address of the accountt. +accAddr := myProfile.Account.GetCachedValue().(AccountI).GetAddress() +``` + +For more information about interface encoding, and especially on how the `Any`'s `type_url` gets resolved using the `InterfaceRegistry`, please refer to [ADR-019](../architecture/adr-019-protobuf-state-encoding.md). + +#### `Any` Encoding in the SDK + +The above `Profile` example is a fictive example used for educational purposes. In the SDK, we use `Any` encoding in several places (non-exhaustive list): + +- the `cryptotypes.PubKey` interface for encoding different types of public keys, +- the `sdk.Msg` interface for encoding different `Msg`s in a transaction, +- the `AccountI` interface for encodinig different types of accounts (similar to the above example) in the x/auth query responses, +- the `Evidencei` interface for encoding different types of evidences in the x/evidence module, +- the `AuthorizationI` interface for encoding different types of x/authz authorizations. + +A real-life example of encoding the pubkey as `Any` inside the Validator struct in x/staking is given below: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/staking/types/validator.go#L40-L61 + +## FAQ 1. How to create modules using protobuf encoding? @@ -123,32 +238,6 @@ type UnpackInterfacesMessage interface { } ``` -#### Guidelines for protobuf message definitions - -In addition to [following official guidelines](https://developers.google.com/protocol-buffers/docs/proto3#simple), we recommend to use these annotations in .proto files when dealing with interfaces: - -- fields which accept interfaces should be annotated with `cosmos_proto.accepts_interface` - using the same full-qualified name passed as `protoName` to `InterfaceRegistry.RegisterInterface` -- interface implementations should be annotated with `cosmos_proto.implements_interface` - using the same full-qualified name passed as `protoName` to `InterfaceRegistry.RegisterInterface` - -#### Transaction Encoding - -Another important use of Protobuf is the encoding and decoding of -[transactions](./transactions.md). Transactions are defined by the application or -the SDK, but passed to the underlying consensus engine in order to be relayed to -other peers. Since the underlying consensus engine is agnostic to the application, -it only accepts transactions in the form of raw bytes. The encoding is done by an -object called `TxEncoder` and the decoding by an object called `TxDecoder`. - -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc4/types/tx_msg.go#L83-L87 - -A standard implementation of both these objects can be found in the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth): - -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc4/x/auth/tx/decoder.go - -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc4/x/auth/tx/encoder.go - ## Next {hide} Learn about [gRPC, REST and other endpoints](./grpc_rest.md) {hide} From da42fec3561536e27364305add849992add720c2 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 16 Mar 2021 16:27:58 +0100 Subject: [PATCH 04/28] Random cleanups --- docs/basics/accounts.md | 2 +- docs/basics/app-anatomy.md | 2 +- docs/building-modules/invariants.md | 2 +- docs/building-modules/simulator.md | 2 +- docs/core/baseapp.md | 4 ++-- docs/core/encoding.md | 2 +- docs/core/events.md | 2 +- docs/core/store.md | 6 +++--- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/basics/accounts.md b/docs/basics/accounts.md index 756545af4aa..9b7648b8c7d 100644 --- a/docs/basics/accounts.md +++ b/docs/basics/accounts.md @@ -98,7 +98,7 @@ Also see the [`Addresses`](#addresses) section for more information. `PubKey`s used in the Cosmos SDK are Protobuf messages and have the following methods: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/crypto/types/types.go#L8-L17 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/crypto/types/types.go#L8-L17 - For `secp256k1` keys, the actual implementation can be found [here](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/crypto/keys/secp256k1/secp256k1.go). - For `ed25519` keys, it can be found [here](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/crypto/keys/ed25519/ed25519.go). diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 8980ebda54a..1069099bd2d 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -114,7 +114,7 @@ The `EncodingConfig` structure is the last important part of the `app.go` file. Here are descriptions of what each of the four fields means: - `InterfaceRegistry`: The `InterfaceRegistry` is used by the Protobuf codec to handle interfaces, which are encoded and decoded (we also say "unpacked") using [`google.protobuf.Any`](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). `Any` could be thought as a struct which contains a `type_url` (name of a concrete type implementing the interface) and a `value` (its encoded bytes). `InterfaceRegistry` provides a mechanism for registering interfaces and implementations that can be safely unpacked from `Any`. Each of the application's modules implements the `RegisterInterfaces` method, which can be used to register the module's own interfaces and implementations. - - You can read more about Any in [ADR-19](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-019-protobuf-state-encoding.md#usage-of-any-to-encode-interfaces). + - You can read more about Any in [ADR-19](../architecture/adr-019-protobuf-state-encoding.md#usage-of-any-to-encode-interfaces). - To go more into details, the SDK uses an implementation of the Protobuf specification called [`gogoprotobuf`](https://github.com/gogo/protobuf). By default, the [gogo protobuf implementation of `Any`](https://godoc.org/github.com/gogo/protobuf/types) uses [global type registration](https://github.com/gogo/protobuf/blob/master/proto/properties.go#L540) to decode values packed in `Any` into concrete Go types. This introduces a vulnerability where any malicious module in the dependency tree could registry a type with the global protobuf registry and cause it to be loaded and unmarshaled by a transaction that referenced it in the `type_url` field. For more information, please refer to [ADR-019](../architecture/adr-019-protobuf-state-encoding.md). - `Marshaler`: the default codec used throughout the SDK. It is composed of a `BinaryMarshaler` used to encode and decode state, and a `JSONMarshaler` used to output data to the users (for example in the [CLI](#cli)). By default, the SDK uses Protobuf as `Marshaler`. - `TxConfig`: `TxConfig` defines an interface a client can utilize to generate an application-defined concrete transaction type. Currently, the SDK handles two transaction types: `SIGN_MODE_DIRECT` (which uses Protobuf binary as over-the-wire encoding) and `SIGN_MODE_LEGACY_AMINO_JSON` (which depends on Amino). Read more about transactions [here](../core/transactions.md). diff --git a/docs/building-modules/invariants.md b/docs/building-modules/invariants.md index d21100cb24b..32fd30591b0 100644 --- a/docs/building-modules/invariants.md +++ b/docs/building-modules/invariants.md @@ -74,7 +74,7 @@ At its core, the `InvariantRegistry` is defined in the SDK as an interface: Typically, this interface is implemented in the `keeper` of a specific module. The most used implementation of an `InvariantRegistry` can be found in the `crisis` module: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/keeper/keeper.go#L50-L54 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/crisis/keeper/keeper.go#L50-L54 The `InvariantRegistry` is therefore typically instantiated by instantiating the `keeper` of the `crisis` module in the [application's constructor function](../basics/app-anatomy.md#constructor-function). diff --git a/docs/building-modules/simulator.md b/docs/building-modules/simulator.md index 1d46f3c70e4..9c53a6dc43b 100644 --- a/docs/building-modules/simulator.md +++ b/docs/building-modules/simulator.md @@ -63,7 +63,7 @@ Operations on the simulation are simulated using the full [transaction cycle](.. Shown below is how weights are set: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/simulation/operations.go#L18-L68 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/staking/simulation/operations.go#L18-L68 As you can see the weights are predefined in this case but there are options on how to override this behavior with different weights. One is allowing `*rand.Rand` to define a random weight for the operation, or you can inject your own predefined weights. diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index c17ce939de4..3458973cc12 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -126,7 +126,7 @@ is the canonical state of the application and the volatile states, `checkState` are used to handle state transitions in-between the main state made during [`Commit`](#commit). Internally, there is only a single `CommitMultiStore` which we refer to as the main or root state. -From this root state, we derive two volatile state through a mechanism called _store branching_ (performed by `CacheWrap` function). +From this root state, we derive two volatile state through a mechanism called _store branching_ (performed by `CacheWrap` function). The types can be illustrated as follows: ![Types](./baseapp_state_types.png) @@ -333,7 +333,7 @@ The `AnteHandler` is theoretically optional, but still a very important componen - Perform preliminary _stateful_ validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. - Play a role in the incentivisation of stakeholders via the collection of transaction fees. -`BaseApp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante/ante.go). +`BaseApp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/auth/ante/ante.go). Click [here](../basics/gas-fees.md#antehandler) for more on the `anteHandler`. diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 6a4bac96384..4ec44147a82 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -91,7 +91,7 @@ object called `TxEncoder` and the decoding by an object called `TxDecoder`. +++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc4/types/tx_msg.go#L83-L87 -A standard implementation of both these objects can be found in the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth): +A standard implementation of both these objects can be found in the [`auth` module](../../x/auth/spec/README.md): +++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc4/x/auth/tx/decoder.go diff --git a/docs/core/events.md b/docs/core/events.md index a0793862a6d..64790b39834 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -112,7 +112,7 @@ The main `eventCategory` you can subscribe to are: These events are triggered from the `state` package after a block is committed. You can get the full list of `event` categories [here](https://godoc.org/github.com/tendermint/tendermint/types#pkg-constants). -The `type` and `attribute` value of the `query` allow you to filter the specific `event` you are looking for. For example, a `transfer` transaction triggers an `event` of type `Transfer` and has `Recipient` and `Sender` as `attributes` (as defined in the [`events` file of the `bank` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/events.go)). Subscribing to this `event` would be done like so: +The `type` and `attribute` value of the `query` allow you to filter the specific `event` you are looking for. For example, a `transfer` transaction triggers an `event` of type `Transfer` and has `Recipient` and `Sender` as `attributes` (as defined in the [`events` file of the `bank` module](https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/bank/types/events.go)). Subscribing to this `event` would be done like so: ```json { diff --git a/docs/core/store.md b/docs/core/store.md index 5de83b8269c..a469b77ebfd 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -56,11 +56,11 @@ The Cosmos SDK comes with a large set of stores to persist the state of applicat ### Store Interface -At its very core, a Cosmos SDK `store` is an object that holds a `CacheWrapper` and has a `GetStoreType()` method: +At its very core, a Cosmos SDK `store` is an object that holds a `CacheWrapper` and has a `GetStoreType()` method: +++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/types/store.go#L15-L18 -The `GetStoreType` is a simple method that returns the type of store, whereas a `CacheWrapper` is a simple interface that implements store read caching and write branching through `Write` method: +The `GetStoreType` is a simple method that returns the type of store, whereas a `CacheWrapper` is a simple interface that implements store read caching and write branching through `Write` method: +++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/types/store.go#L240-L264 @@ -104,7 +104,7 @@ The `rootMulti.Store` is a base-layer multistore built around a `db` on top of w ### CacheMultiStore -Whenever the `rootMulti.Store` needs to be branched, a [`cachemulti.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go) is used. +Whenever the `rootMulti.Store` needs to be branched, a [`cachemulti.Store`](https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/store/cachemulti/store.go) is used. +++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/cachemulti/store.go#L17-L28 From a19b48cba2efe466ca2f604a691c099a36156cbe Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 16 Mar 2021 17:16:33 +0100 Subject: [PATCH 05/28] Add UnpackInterfaces --- docs/core/encoding.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 4ec44147a82..84c55b308ef 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -170,7 +170,22 @@ fmt.Printf("%T\n", myProfile.Account.GetCachedValue()) // Prints "BaseAccount", accAddr := myProfile.Account.GetCachedValue().(AccountI).GetAddress() ``` -For more information about interface encoding, and especially on how the `Any`'s `type_url` gets resolved using the `InterfaceRegistry`, please refer to [ADR-019](../architecture/adr-019-protobuf-state-encoding.md). +It is important to note that for `GetCachedValue()` to work, `Profile` (and any other structs embedding `Profile`) must implement the `UnpackInterfaces` method: + +```go +func (p *Profile) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { + if p.Account != nil { + var account AccountI + return unpacker.UnpackAny(p.Account, &account) + } + + return nil +} +``` + +The `UnpackInterfaces` gets called recursively on all structs implementing this method, to allow all `Any`s to have their `GetCachedValue()` correctly populated. + +For more information about interface encoding, and especially on `UnpackInterfaces` and how the `Any`'s `type_url` gets resolved using the `InterfaceRegistry`, please refer to [ADR-019](../architecture/adr-019-protobuf-state-encoding.md). #### `Any` Encoding in the SDK From 9e062614a9c3fb6bf586fbdb87ebf44c20f47e71 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Tue, 16 Mar 2021 18:00:13 +0100 Subject: [PATCH 06/28] Use tag instead of commit --- docs/core/events.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/core/events.md b/docs/core/events.md index 64790b39834..dbdd9604053 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -57,13 +57,13 @@ In Cosmos SDK applications, events are managed by an abstraction called the `Eve Internally, the `EventManager` tracks a list of `Events` for the entire execution flow of a transaction or `BeginBlock`/`EndBlock`. -+++ https://github.com/cosmos/cosmos-sdk/blob/21814558eaa47b018018711e5fe16e0b16811fce/types/events.go#L17-L25 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/types/events.go#L17-L25 The `EventManager` comes with a set of useful methods to manage events. Among them, the one that is used the most by module and application developers is the `EmitEvent` method, which tracks an `event` in the `EventManager`. -+++ https://github.com/cosmos/cosmos-sdk/blob/21814558eaa47b018018711e5fe16e0b16811fce/types/events.go#L33-L37 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/types/events.go#L33-L37 Module developers should handle event emission via the `EventManager#EmitEvent` in each message `Handler` and in each `BeginBlock`/`EndBlock` handler. The `EventManager` is accessed via From 97d87397e4efc5b99245a2af46c01e043ddf8f68 Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:12:40 +0100 Subject: [PATCH 07/28] Update docs/architecture/adr-041-in-place-store-migrations.md Co-authored-by: Barrie Byron --- docs/architecture/adr-041-in-place-store-migrations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/adr-041-in-place-store-migrations.md b/docs/architecture/adr-041-in-place-store-migrations.md index 4ba55466b8e..4687ef31f88 100644 --- a/docs/architecture/adr-041-in-place-store-migrations.md +++ b/docs/architecture/adr-041-in-place-store-migrations.md @@ -75,7 +75,7 @@ func (m Migrator) Migrate1to2(ctx sdk.Context) error { } ``` -Each module's migration functions are specific to the module's store evolutions, and are not described in this ADR. An example of x/bank store key migrations following the introduction of ADR-028 length-prefixed addresses can be seen [here](https://github.com/cosmos/cosmos-sdk/blob/36f68eb9e041e20a5bb47e216ac5eb8b91f95471/x/bank/legacy/v043/store.go#L41-L62). +Each module's migration functions are specific to the module's store evolutions, and are not described in this ADR. An example of x/bank store key migrations after the introduction of ADR-028 length-prefixed addresses can be seen in this [store.go code](https://github.com/cosmos/cosmos-sdk/blob/36f68eb9e041e20a5bb47e216ac5eb8b91f95471/x/bank/legacy/v043/store.go#L41-L62). ### Tracking Module Versions in `x/upgrade` From f8b4e1cb01c2d457a7a2d27b50e5a964bf506ab7 Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:13:05 +0100 Subject: [PATCH 08/28] Update docs/basics/app-anatomy.md Co-authored-by: Barrie Byron --- docs/basics/app-anatomy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 1069099bd2d..70b725865ab 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -113,7 +113,7 @@ The `EncodingConfig` structure is the last important part of the `app.go` file. Here are descriptions of what each of the four fields means: -- `InterfaceRegistry`: The `InterfaceRegistry` is used by the Protobuf codec to handle interfaces, which are encoded and decoded (we also say "unpacked") using [`google.protobuf.Any`](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). `Any` could be thought as a struct which contains a `type_url` (name of a concrete type implementing the interface) and a `value` (its encoded bytes). `InterfaceRegistry` provides a mechanism for registering interfaces and implementations that can be safely unpacked from `Any`. Each of the application's modules implements the `RegisterInterfaces` method, which can be used to register the module's own interfaces and implementations. +- `InterfaceRegistry`: The `InterfaceRegistry` is used by the Protobuf codec to handle interfaces that are encoded and decoded (we also say "unpacked") using [`google.protobuf.Any`](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). `Any` could be thought as a struct that contains a `type_url` (name of a concrete type implementing the interface) and a `value` (its encoded bytes). `InterfaceRegistry` provides a mechanism for registering interfaces and implementations that can be safely unpacked from `Any`. Each of the application's modules implements the `RegisterInterfaces` method that can be used to register the module's own interfaces and implementations. - You can read more about Any in [ADR-19](../architecture/adr-019-protobuf-state-encoding.md#usage-of-any-to-encode-interfaces). - To go more into details, the SDK uses an implementation of the Protobuf specification called [`gogoprotobuf`](https://github.com/gogo/protobuf). By default, the [gogo protobuf implementation of `Any`](https://godoc.org/github.com/gogo/protobuf/types) uses [global type registration](https://github.com/gogo/protobuf/blob/master/proto/properties.go#L540) to decode values packed in `Any` into concrete Go types. This introduces a vulnerability where any malicious module in the dependency tree could registry a type with the global protobuf registry and cause it to be loaded and unmarshaled by a transaction that referenced it in the `type_url` field. For more information, please refer to [ADR-019](../architecture/adr-019-protobuf-state-encoding.md). - `Marshaler`: the default codec used throughout the SDK. It is composed of a `BinaryMarshaler` used to encode and decode state, and a `JSONMarshaler` used to output data to the users (for example in the [CLI](#cli)). By default, the SDK uses Protobuf as `Marshaler`. From e0d1a4531ff7b91b19af03fb425dae9917b18465 Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:13:23 +0100 Subject: [PATCH 09/28] Update docs/building-modules/simulator.md Co-authored-by: Barrie Byron --- docs/building-modules/simulator.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-modules/simulator.md b/docs/building-modules/simulator.md index 9c53a6dc43b..7a9e72ca00d 100644 --- a/docs/building-modules/simulator.md +++ b/docs/building-modules/simulator.md @@ -65,7 +65,7 @@ Shown below is how weights are set: +++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/staking/simulation/operations.go#L18-L68 -As you can see the weights are predefined in this case but there are options on how to override this behavior with different weights. One is allowing `*rand.Rand` to define a random weight for the operation, or you can inject your own predefined weights. +As you can see, the weights are predefined in this case. Options exist to override this behavior with different weights. One option is to use `*rand.Rand` to define a random weight for the operation, or you can inject your own predefined weights. Here is how one can override the above package `simappparams`. From 9c929047ae80145e89a99ddc00ae4b6f9d9015e2 Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:13:41 +0100 Subject: [PATCH 10/28] Update docs/core/baseapp.md Co-authored-by: Barrie Byron --- docs/core/baseapp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 3458973cc12..a7bda8717f0 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -333,7 +333,7 @@ The `AnteHandler` is theoretically optional, but still a very important componen - Perform preliminary _stateful_ validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. - Play a role in the incentivisation of stakeholders via the collection of transaction fees. -`BaseApp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/auth/ante/ante.go). +`BaseApp` holds an `anteHandler` as parameter that is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` is the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/auth/ante/ante.go). Click [here](../basics/gas-fees.md#antehandler) for more on the `anteHandler`. From 35ffaa463af3c0102964aa9f0a91e34a09f56f05 Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:13:54 +0100 Subject: [PATCH 11/28] Update docs/core/baseapp.md Co-authored-by: Barrie Byron --- docs/core/baseapp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index a7bda8717f0..67dbd557e03 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -126,7 +126,7 @@ is the canonical state of the application and the volatile states, `checkState` are used to handle state transitions in-between the main state made during [`Commit`](#commit). Internally, there is only a single `CommitMultiStore` which we refer to as the main or root state. -From this root state, we derive two volatile state through a mechanism called _store branching_ (performed by `CacheWrap` function). +From this root state, we derive two volatile states by using a mechanism called _store branching_ (performed by `CacheWrap` function). The types can be illustrated as follows: ![Types](./baseapp_state_types.png) From 7ddd3707cf7f287dd9beb606587a4f8440384aaa Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:14:25 +0100 Subject: [PATCH 12/28] Update docs/core/encoding.md Co-authored-by: Barrie Byron --- docs/core/encoding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 84c55b308ef..383d4c2e75b 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -69,7 +69,7 @@ typically used for when the data needs to be streamed or grouped together ### Gogoproto -Modules are encouraged to utilize Protobuf encoding for their respective types. In the SDK, we use a specific implementation of the Protobuf spec, called [Gogoproto](https://github.com/gogo/protobuf), which offers speed and DX improvements compared to the official [Google implementation](https://github.com/protocolbuffers/protobuf). +Modules are encouraged to utilize Protobuf encoding for their respective types. In the SDK, we use the [Gogoproto](https://github.com/gogo/protobuf) specific implementation of the Protobuf spec that offers speed and DX improvements compared to the official [Google protobuf implementation](https://github.com/protocolbuffers/protobuf). ### Guidelines for protobuf message definitions From 68dd03bc4aaf57ae052365cdf82e55219958375a Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:14:45 +0100 Subject: [PATCH 13/28] Update docs/core/events.md Co-authored-by: Barrie Byron --- docs/core/events.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/core/events.md b/docs/core/events.md index dbdd9604053..ace9736785f 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -24,12 +24,12 @@ An Event contains: - A list of `attributes`, which are key-value pairs that give more information about the categorized Event. For example, for the `"message"` type, we can filter events by key-value pairs using `message.action={some_action}`, `message.module={some_module}` or `message.sender={some_sender}`. ::: tip -If you want the attribute values to be parsed as strings, make sure to add `'` (single quotes) around each attribute value. +To parse the attribute values as strings, make sure to add `'` (single quotes) around each attribute value. ::: Events, the `type` and `attributes` are defined on a **per-module basis** in the module's `/types/events.go` file, and triggered from the module's [`Msg` service](../building-modules/msg-services.md) -via the [`EventManager`](#eventmanager). In addition, each module documents its events under +by using the [`EventManager`](#eventmanager). In addition, each module documents its events under `spec/xx_events.md`. Events are returned to the underlying consensus engine in the response of the following ABCI messages: From 4cb4a3acb16533c6eddf38c4e5b0f97e5304aedb Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:14:53 +0100 Subject: [PATCH 14/28] Update docs/core/events.md Co-authored-by: Barrie Byron --- docs/core/events.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/core/events.md b/docs/core/events.md index ace9736785f..00e06ee28af 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -59,8 +59,8 @@ transaction or `BeginBlock`/`EndBlock`. +++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/types/events.go#L17-L25 -The `EventManager` comes with a set of useful methods to manage events. Among them, the one that is -used the most by module and application developers is the `EmitEvent` method, which tracks +The `EventManager` comes with a set of useful methods to manage events. The method +that is used most by module and application developers is `EmitEvent` that tracks an `event` in the `EventManager`. +++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/types/events.go#L33-L37 From 583a5416fa56b37c6e5a112036edc58148f26a5a Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:15:07 +0100 Subject: [PATCH 15/28] Update docs/core/events.md Co-authored-by: Barrie Byron --- docs/core/events.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/core/events.md b/docs/core/events.md index 00e06ee28af..a23fb9a83ef 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -89,8 +89,7 @@ view on how to typically implement `Events` and use the `EventManager` in module ## Subscribing to Events -It is possible to subscribe to `Events` via Tendermint's [Websocket](https://docs.tendermint.com/master/tendermint-core/subscription.html#subscribing-to-events-via-websocket). -This is done by calling the `subscribe` RPC method via Websocket: +You can use Tendermint's [Websocket](https://docs.tendermint.com/master/tendermint-core/subscription.html#subscribing-to-events-via-websocket) to subscribe to `Events` by calling the `subscribe` RPC method: ```json { From 46a738d0ded68accf60ebef453e5536755b0cbce Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:15:39 +0100 Subject: [PATCH 16/28] Update docs/core/events.md Co-authored-by: Barrie Byron --- docs/core/events.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/core/events.md b/docs/core/events.md index a23fb9a83ef..02e6e534939 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -128,9 +128,9 @@ where `senderAddress` is an address following the [`AccAddress`](../basics/accou ## Typed Events (coming soon) -As described above, events are defined on a per-module basis, and it is the responsability of the module developer to define event types and event attributes. Except in the `spec/XX_events.md` file, these types and attributes are unfortunately not easily discoverable, so the SDK proposes to use Protobuf-defined [Typed Events](../architecture/adr-032-typed-events.md) for emitting and querying for events. +As previously described, Events are defined on a per-module basis. It is the responsibility of the module developer to define event types and event attributes. Except in the `spec/XX_events.md` file, these event types and attributes are unfortunately not easily discoverable, so the SDK proposes to use Protobuf-defined [Typed Events](../architecture/adr-032-typed-events.md) for emitting and querying Events. -The Typed Events proposal has not yet been fully implemented, and its documentation will follow with a future release of the SDK. +The Typed Events proposal has not yet been fully implemented. Documentation is not yet available. ## Next {hide} From 3e2f4b5d53b7ab75194149244079e8585b4de077 Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:15:54 +0100 Subject: [PATCH 17/28] Update docs/core/events.md Co-authored-by: Barrie Byron --- docs/core/events.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/events.md b/docs/core/events.md index 02e6e534939..95d126a98f5 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -41,7 +41,7 @@ Events are returned to the underlying consensus engine in the response of the fo ### Examples -Below are some examples of Events you can query using the SDK. +The following examples show how to query Events using the SDK. | Event | Description | | ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | From b0fd14ab37ddd69f8285411b3f4d3fee16ae4ccb Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:16:09 +0100 Subject: [PATCH 18/28] Update docs/core/encoding.md Co-authored-by: Barrie Byron --- docs/core/encoding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 383d4c2e75b..f913fdd4d9f 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -73,7 +73,7 @@ Modules are encouraged to utilize Protobuf encoding for their respective types. ### Guidelines for protobuf message definitions -In addition to [following official guidelines](https://developers.google.com/protocol-buffers/docs/proto3#simple), we recommend to use these annotations in .proto files when dealing with interfaces: +In addition to [following official Protocol Buffer guidelines](https://developers.google.com/protocol-buffers/docs/proto3#simple), we recommend using these annotations in .proto files when dealing with interfaces: - fields which accept interfaces should be annotated with `cosmos_proto.accepts_interface` using the same full-qualified name passed as `protoName` to `InterfaceRegistry.RegisterInterface` From de52a4f81be380e97ffd641074a86b72c79e4e61 Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:16:28 +0100 Subject: [PATCH 19/28] Update docs/core/encoding.md Co-authored-by: Barrie Byron --- docs/core/encoding.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/core/encoding.md b/docs/core/encoding.md index f913fdd4d9f..21394df271a 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -75,10 +75,10 @@ Modules are encouraged to utilize Protobuf encoding for their respective types. In addition to [following official Protocol Buffer guidelines](https://developers.google.com/protocol-buffers/docs/proto3#simple), we recommend using these annotations in .proto files when dealing with interfaces: -- fields which accept interfaces should be annotated with `cosmos_proto.accepts_interface` - using the same full-qualified name passed as `protoName` to `InterfaceRegistry.RegisterInterface` -- interface implementations should be annotated with `cosmos_proto.implements_interface` - using the same full-qualified name passed as `protoName` to `InterfaceRegistry.RegisterInterface` +- use `cosmos_proto.accepts_interface` to annote fields that accept interfaces +- pass the same fully qualified name as `protoName` to `InterfaceRegistry.RegisterInterface` +- annotate interface implementations with `cosmos_proto.implements_interface` +- pass the same fully qualified name as `protoName` to `InterfaceRegistry.RegisterInterface` ### Transaction Encoding From b74cfa4ae91667376a7dcba3b0b455162813e01c Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:16:47 +0100 Subject: [PATCH 20/28] Update docs/core/encoding.md Co-authored-by: Barrie Byron --- docs/core/encoding.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 21394df271a..7baae283d64 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -84,10 +84,12 @@ In addition to [following official Protocol Buffer guidelines](https://developer Another important use of Protobuf is the encoding and decoding of [transactions](./transactions.md). Transactions are defined by the application or -the SDK, but passed to the underlying consensus engine in order to be relayed to +the SDK but are then passed to the underlying consensus engine to be relayed to other peers. Since the underlying consensus engine is agnostic to the application, -it only accepts transactions in the form of raw bytes. The encoding is done by an -object called `TxEncoder` and the decoding by an object called `TxDecoder`. +the consensus engine accepts only transactions in the form of raw bytes. + +- The `TxEncoder` object performs the encoding. +- The `TxDecoder` object performs the decoding. +++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc4/types/tx_msg.go#L83-L87 From 26f09a55dd87c842de33d0d400965e64c5844785 Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:17:04 +0100 Subject: [PATCH 21/28] Update docs/core/encoding.md Co-authored-by: Barrie Byron --- docs/core/encoding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 7baae283d64..84cb27f2300 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -99,7 +99,7 @@ A standard implementation of both these objects can be found in the [`auth` modu +++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc4/x/auth/tx/encoder.go -Please also refer to [ADR-020](../architecture/adr-020-protobuf-transaction-encoding.md) on the details of how a transaction is encoded. +See [ADR-020](../architecture/adr-020-protobuf-transaction-encoding.md) for details of how a transaction is encoded. ### Interface Encoding and Usage of `Any`s From 6e94d8a055abf2dfacc4081113f8f7dcd7a2a75f Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:19:58 +0100 Subject: [PATCH 22/28] Update docs/core/encoding.md Co-authored-by: Barrie Byron --- docs/core/encoding.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 84cb27f2300..036736061c6 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -101,9 +101,9 @@ A standard implementation of both these objects can be found in the [`auth` modu See [ADR-020](../architecture/adr-020-protobuf-transaction-encoding.md) for details of how a transaction is encoded. -### Interface Encoding and Usage of `Any`s +### Interface Encoding and Usage of `Any` -The Protobuf DSL is strongly typed, which can make inserting variable-typed fields difficult. Imagine we want to create a `Profile` protobuf message, which serves as a wrapper over [an account](../basics/accounts.md): +The Protobuf DSL is strongly typed, which can make inserting variable-typed fields difficult. Imagine we want to create a `Profile` protobuf message that serves as a wrapper over [an account](../basics/accounts.md): ```proto message Profile { From fc789d66139b7af384f06cabb6bf9f1243bc6318 Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:20:53 +0100 Subject: [PATCH 23/28] Update docs/core/encoding.md Co-authored-by: Barrie Byron --- docs/core/encoding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 036736061c6..8d436c2a428 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -114,7 +114,7 @@ message Profile { } ``` -In the above `Profile`, we hardcoded `account` as a `BaseAccount`. However, there are several other types of [user accounts related to vesting](../../x/auth/spec/05_vesting.md), such as `BaseVestingAccount` or `ContinuousVestingAccount`. All of these accounts are different, but they all implement the `AccountI` interface. How would one create a `Profile` which allows all these types of accounts, with an `account` field accepting an `AccountI` interface? +In this `Profile` example, we hardcoded `account` as a `BaseAccount`. However, there are several other types of [user accounts related to vesting](../../x/auth/spec/05_vesting.md), 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? +++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/auth/types/account.go#L307-L330 From 1afbd0c718874fcd0cea7d4b0444e945494fb900 Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:21:12 +0100 Subject: [PATCH 24/28] Update docs/core/encoding.md Co-authored-by: Barrie Byron --- docs/core/encoding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 8d436c2a428..5abe589ac47 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -118,7 +118,7 @@ In this `Profile` example, we hardcoded `account` as a `BaseAccount`. However, t +++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/auth/types/account.go#L307-L330 -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. It allows us to pack arbitrary Go types inside protobuf messages. Our new `Profile` then looks like: +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: ```protobuf message Profile { From a3867c00a6482119cdf5ab0c623932646b365eff Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:21:32 +0100 Subject: [PATCH 25/28] Update docs/core/encoding.md Co-authored-by: Barrie Byron --- docs/core/encoding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 5abe589ac47..f3462107723 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -154,7 +154,7 @@ bz, err := cdc.MarshalBinaryBare(profile) jsonBz, err := cdc.MarshalJSON(profile) ``` -To summarize, if you want to encode an interface, you need to 1/ pack it into an `Any` and 2/ marshal the `Any`. For convenience, the SDK provides a `MarshalInterface` method to bundle the 2 steps into one. Have a look at [a real-life example in the x/auth module](https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/auth/keeper/keeper.go#L218-L221). +To summarize, to encode an interface, you must 1/ pack the interface into an `Any` and 2/ marshal the `Any`. For convenience, the 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.42.1/x/auth/keeper/keeper.go#L218-L221). The reverse operation of retrieving the concrete Go type from inside an `Any`, called "unpacking", is done with the `GetCachedValue()` on `Any`. From d84d2620a578cc3df94b8e39af0b2dff597c5fde Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:21:55 +0100 Subject: [PATCH 26/28] Update docs/core/encoding.md Co-authored-by: Barrie Byron --- docs/core/encoding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/encoding.md b/docs/core/encoding.md index f3462107723..fc390f79dd5 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -199,7 +199,7 @@ The above `Profile` example is a fictive example used for educational purposes. - the `Evidencei` interface for encoding different types of evidences in the x/evidence module, - the `AuthorizationI` interface for encoding different types of x/authz authorizations. -A real-life example of encoding the pubkey as `Any` inside the Validator struct in x/staking is given below: +A real-life example of encoding the pubkey as `Any` inside the Validator struct in x/staking is shown in the following example: +++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/staking/types/validator.go#L40-L61 From b791fd0909f40728e88324aa3350134481196c82 Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:22:07 +0100 Subject: [PATCH 27/28] Update docs/core/events.md Co-authored-by: Barrie Byron --- docs/core/events.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/core/events.md b/docs/core/events.md index 95d126a98f5..ee963fe251a 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -20,8 +20,8 @@ take the form of: `{eventType}.{attributeKey}={attributeValue}`. An Event contains: -- A `type`, which is meant to categorize an event at a high-level, e.g. the SDK uses the `"message"` type to filter events by `Msg`s. -- A list of `attributes`, which are key-value pairs that give more information about the categorized Event. For example, for the `"message"` type, we can filter events by key-value pairs using `message.action={some_action}`, `message.module={some_module}` or `message.sender={some_sender}`. +- A `type` to categorize the Event at a high-level; for example, the SDK uses the `"message"` type to filter events by `Msg`s. +- A list of `attributes` are key-value pairs that give more information about the categorized Event. For example, for the `"message"` type, we can filter events by key-value pairs using `message.action={some_action}`, `message.module={some_module}` or `message.sender={some_sender}`. ::: tip To parse the attribute values as strings, make sure to add `'` (single quotes) around each attribute value. From 9f755220b278feaebec344110f71a683cdd5dea4 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:26:36 +0100 Subject: [PATCH 28/28] Use consistent casing --- docs/core/events.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/core/events.md b/docs/core/events.md index ee963fe251a..999d2876169 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -20,8 +20,8 @@ take the form of: `{eventType}.{attributeKey}={attributeValue}`. An Event contains: -- A `type` to categorize the Event at a high-level; for example, the SDK uses the `"message"` type to filter events by `Msg`s. -- A list of `attributes` are key-value pairs that give more information about the categorized Event. For example, for the `"message"` type, we can filter events by key-value pairs using `message.action={some_action}`, `message.module={some_module}` or `message.sender={some_sender}`. +- A `type` to categorize the Event at a high-level; for example, the SDK uses the `"message"` type to filter Events by `Msg`s. +- A list of `attributes` are key-value pairs that give more information about the categorized Event. For example, for the `"message"` type, we can filter Events by key-value pairs using `message.action={some_action}`, `message.module={some_module}` or `message.sender={some_sender}`. ::: tip To parse the attribute values as strings, make sure to add `'` (single quotes) around each attribute value. @@ -29,7 +29,7 @@ To parse the attribute values as strings, make sure to add `'` (single quotes) a Events, the `type` and `attributes` are defined on a **per-module basis** in the module's `/types/events.go` file, and triggered from the module's [`Msg` service](../building-modules/msg-services.md) -by using the [`EventManager`](#eventmanager). In addition, each module documents its events under +by using the [`EventManager`](#eventmanager). In addition, each module documents its Events under `spec/xx_events.md`. Events are returned to the underlying consensus engine in the response of the following ABCI messages: @@ -49,25 +49,25 @@ The following examples show how to query Events using the SDK. | `message.action='/cosmos.bank.v1beta1.Msg/Send'` | Query all transactions containing a x/bank `Send` [Service `Msg`](../building-modules/msg-services.md). Note the `'`s around the value. | | `message.action='send'` | Query all transactions containing a x/bank `Send` [legacy `Msg`](../building-modules/msg-services.md#legacy-amino-msgs). Note the `'`s around the value. | | `message.module='bank'` | Query all transactions containing messages from the x/bank module. Note the `'`s around the value. | -| `create_validator.validator='cosmosval1...'` | x/staking-specific event, see [x/staking SPEC](../../../cosmos-sdk/x/staking/spec/07_events.md). | +| `create_validator.validator='cosmosval1...'` | x/staking-specific Event, see [x/staking SPEC](../../../cosmos-sdk/x/staking/spec/07_events.md). | ## EventManager -In Cosmos SDK applications, events are managed by an abstraction called the `EventManager`. -Internally, the `EventManager` tracks a list of `Events` for the entire execution flow of a +In Cosmos SDK applications, Events are managed by an abstraction called the `EventManager`. +Internally, the `EventManager` tracks a list of Events for the entire execution flow of a transaction or `BeginBlock`/`EndBlock`. +++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/types/events.go#L17-L25 -The `EventManager` comes with a set of useful methods to manage events. The method +The `EventManager` comes with a set of useful methods to manage Events. The method that is used most by module and application developers is `EmitEvent` that tracks -an `event` in the `EventManager`. +an Event in the `EventManager`. +++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/types/events.go#L33-L37 -Module developers should handle event emission via the `EventManager#EmitEvent` in each message +Module developers should handle Event emission via the `EventManager#EmitEvent` in each message `Handler` and in each `BeginBlock`/`EndBlock` handler. The `EventManager` is accessed via -the [`Context`](./context.md), where event emission generally follows this pattern: +the [`Context`](./context.md), where Event emission generally follows this pattern: ```go ctx.EventManager().EmitEvent( @@ -75,7 +75,7 @@ ctx.EventManager().EmitEvent( ) ``` -Module's `handler` function should also set a new `EventManager` to the `context` to isolate emitted events per `message`: +Module's `handler` function should also set a new `EventManager` to the `context` to isolate emitted Events per `message`: ```go func NewHandler(keeper Keeper) sdk.Handler { @@ -85,11 +85,11 @@ func NewHandler(keeper Keeper) sdk.Handler { ``` See the [`Msg` services](../building-modules/msg-services.md) concept doc for a more detailed -view on how to typically implement `Events` and use the `EventManager` in modules. +view on how to typically implement Events and use the `EventManager` in modules. ## Subscribing to Events -You can use Tendermint's [Websocket](https://docs.tendermint.com/master/tendermint-core/subscription.html#subscribing-to-events-via-websocket) to subscribe to `Events` by calling the `subscribe` RPC method: +You can use Tendermint's [Websocket](https://docs.tendermint.com/master/tendermint-core/subscription.html#subscribing-to-events-via-websocket) to subscribe to Events by calling the `subscribe` RPC method: ```json { @@ -104,14 +104,14 @@ You can use Tendermint's [Websocket](https://docs.tendermint.com/master/tendermi The main `eventCategory` you can subscribe to are: -- `NewBlock`: Contains `events` triggered during `BeginBlock` and `EndBlock`. -- `Tx`: Contains `events` triggered during `DeliverTx` (i.e. transaction processing). +- `NewBlock`: Contains Events triggered during `BeginBlock` and `EndBlock`. +- `Tx`: Contains Events triggered during `DeliverTx` (i.e. transaction processing). - `ValidatorSetUpdates`: Contains validator set updates for the block. -These events are triggered from the `state` package after a block is committed. You can get the -full list of `event` categories [here](https://godoc.org/github.com/tendermint/tendermint/types#pkg-constants). +These Events are triggered from the `state` package after a block is committed. You can get the +full list of Event categories [on the Tendermint Godoc page](https://godoc.org/github.com/tendermint/tendermint/types#pkg-constants). -The `type` and `attribute` value of the `query` allow you to filter the specific `event` you are looking for. For example, a `transfer` transaction triggers an `event` of type `Transfer` and has `Recipient` and `Sender` as `attributes` (as defined in the [`events` file of the `bank` module](https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/bank/types/events.go)). Subscribing to this `event` would be done like so: +The `type` and `attribute` value of the `query` allow you to filter the specific Event you are looking for. For example, a `transfer` transaction triggers an Event of type `Transfer` and has `Recipient` and `Sender` as `attributes` (as defined in the [`events.go` file of the `bank` module](https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/bank/types/events.go)). Subscribing to this Event would be done like so: ```json { @@ -128,9 +128,9 @@ where `senderAddress` is an address following the [`AccAddress`](../basics/accou ## Typed Events (coming soon) -As previously described, Events are defined on a per-module basis. It is the responsibility of the module developer to define event types and event attributes. Except in the `spec/XX_events.md` file, these event types and attributes are unfortunately not easily discoverable, so the SDK proposes to use Protobuf-defined [Typed Events](../architecture/adr-032-typed-events.md) for emitting and querying Events. +As previously described, Events are defined on a per-module basis. It is the responsibility of the module developer to define Event types and Event attributes. Except in the `spec/XX_events.md` file, these Event types and attributes are unfortunately not easily discoverable, so the SDK proposes to use Protobuf-defined [Typed Events](../architecture/adr-032-typed-events.md) for emitting and querying Events. -The Typed Events proposal has not yet been fully implemented. Documentation is not yet available. +The Typed Events proposal has not yet been fully implemented. Documentation is not yet available. ## Next {hide}