diff --git a/docs/build/building-apps/00-runtime.md b/docs/build/building-apps/00-runtime.md index a962019e2993..5f9ab6f9287f 100644 --- a/docs/build/building-apps/00-runtime.md +++ b/docs/build/building-apps/00-runtime.md @@ -5,5 +5,23 @@ sidebar_position: 1 # What is `runtime`? The `runtime` package is the Cosmos SDK package that combines the building blocks of your blockchain together. It wires together the modules, the applications, the codecs, and the stores. +It is a layer of abstraction between `baseapp` and the application modules that simplifies the process of building a Cosmos SDK application. +## Modules wiring + +Runtime is responsible for wiring the modules together. It uses `depinject` to inject the dependencies of the modules. + +## App wiring + +Runtime is the base boilerplate of a Cosmos SDK application. A user only needs to import `runtime` in their `app.go` and instantiate a `runtime.App`. + +## Services + +Modules have access to a multitude of services that are provided by the runtime. +These services include the `store`, the `event manager`, the `context`, and the `logger`. +As runtime is doing the wiring of modules, it can ensure that the services are scoped to their respective modules. + +```go reference +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/runtime/module.go#L250-L279 +``` diff --git a/docs/build/building-modules/00-intro.md b/docs/build/building-modules/00-intro.md index 6618a44caa61..bd8e78a42380 100644 --- a/docs/build/building-modules/00-intro.md +++ b/docs/build/building-modules/00-intro.md @@ -58,6 +58,13 @@ While there are no definitive guidelines for writing modules, here are some impo * **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concerns enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](https://docs.cosmos.network/main/learn/advanced/ocap#ocaps-in-practice) of the Cosmos SDK. * **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some modules to be malicious. That is why module developers need to carefully think not only about how their module interacts with other modules, but also about how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./06-keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. +## Core APIs for Modules + +The SDK provides a set of APIs that a module can implement, and a set of services that a module can use. +Those APIs are defined in the `cosmossdk.io/core/appmodule` package, and are used to defined the module capabilities, which is used by `runtime` during the wiring of the application. + +Learn more about the core APIs for modules [here](../../learn/advanced/02-core.md). + ## Main Components of Cosmos SDK Modules Modules are by convention defined in the `./x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components: diff --git a/docs/build/building-modules/01-module-manager.md b/docs/build/building-modules/01-module-manager.md index 1e3bf38aa95e..9e6694ec3327 100644 --- a/docs/build/building-modules/01-module-manager.md +++ b/docs/build/building-modules/01-module-manager.md @@ -217,11 +217,9 @@ The module manager is used throughout the application whenever an action on a co * `InitGenesis(ctx context.Context, genesisData map[string]json.RawMessage)`: Calls the [`InitGenesis`](./08-genesis.md#initgenesis) function of each module when the application is first started, in the order defined in `OrderInitGenesis`. Returns an `abci.InitChainResponse` to the underlying consensus engine, which can contain validator updates. * `ExportGenesis(ctx context.Context)`: Calls the [`ExportGenesis`](./08-genesis.md#exportgenesis) function of each module, in the order defined in `OrderExportGenesis`. The export constructs a genesis file from a previously existing state, and is mainly used when a hard-fork upgrade of the chain is required. * `ExportGenesisForModules(ctx context.Context, modulesToExport []string)`: Behaves the same as `ExportGenesis`, except takes a list of modules to export. -* `BeginBlock(ctx context.Context) error`: At the beginning of each block, this function is called from [`BaseApp`](../../learn/advanced/00-baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./06-preblock-beginblock-endblock.md) function of each modules implementing the `appmodule.HasBeginBlocker` interface, in the order defined in `OrderBeginBlockers`. It creates a child [context](../../learn/advanced/02-context.md) with an event manager to aggregate [events](../../learn/advanced/08-events.md) emitted from each modules. -* `EndBlock(ctx context.Context) error`: At the end of each block, this function is called from [`BaseApp`](../../learn/advanced/00-baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./06-preblock-beginblock-endblock.md) function of each modules implementing the `appmodule.HasEndBlocker` interface, in the order defined in `OrderEndBlockers`. It creates a child [context](../../learn/advanced/02-context.md) with an event manager to aggregate [events](../../learn/advanced/08-events.md) emitted from all modules. The function returns an `abci` which contains the aforementioned events, as well as validator set updates (if any). -* `EndBlock(context.Context) ([]abci.ValidatorUpdate, error)`: At the end of each block, this function is called from [`BaseApp`](../../learn/advanced/00-baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./06-preblock-beginblock-endblock.md) function of each modules implementing the `module.HasABCIEndBlock` interface, in the order defined in `OrderEndBlockers`. It creates a child [context](../../learn/advanced/02-context.md) with an event manager to aggregate [events](../../learn/advanced/08-events.md) emitted from all modules. The function returns an `abci` which contains the aforementioned events, as well as validator set updates (if any). -* `Precommit(ctx context.Context)`: During [`Commit`](../../learn/advanced/00-baseapp.md#commit), this function is called from `BaseApp` immediately before the [`deliverState`](../../learn/advanced/00-baseapp.md#state-updates) is written to the underlying [`rootMultiStore`](../../learn/advanced/04-store.md#commitmultistore) and, in turn calls the `Precommit` function of each modules implementing the `HasPrecommit` interface, in the order defined in `OrderPrecommiters`. It creates a child [context](../../learn/advanced/02-context.md) where the underlying `CacheMultiStore` is that of the newly committed block's [`finalizeblockstate`](../../learn/advanced/00-baseapp.md#state-updates). -* `PrepareCheckState(ctx context.Context)`: During [`Commit`](../../learn/advanced/00-baseapp.md#commit), this function is called from `BaseApp` immediately after the [`deliverState`](../../learn/advanced/00-baseapp.md#state-updates) is written to the underlying [`rootMultiStore`](../../learn/advanced/04-store.md#commitmultistore) and, in turn calls the `PrepareCheckState` function of each module implementing the `HasPrepareCheckState` interface, in the order defined in `OrderPrepareCheckStaters`. It creates a child [context](../../learn/advanced/02-context.md) where the underlying `CacheMultiStore` is that of the next block's [`checkState`](../../learn/advanced/00-baseapp.md#state-updates). Writes to this state will be present in the [`checkState`](../../learn/advanced/00-baseapp.md#state-updates) of the next block, and therefore this method can be used to prepare the `checkState` for the next block. +* `BeginBlock(ctx context.Context) error`: At the beginning of each block, this function is called from [`BaseApp`](../../learn/advanced/00-baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./06-preblock-beginblock-endblock.md) function of each modules implementing the `appmodule.HasBeginBlocker` interface, in the order defined in `OrderBeginBlockers`. +* `EndBlock(ctx context.Context) error`: At the end of each block, this function is called from [`BaseApp`](../../learn/advanced/00-baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./06-preblock-beginblock-endblock.md) function of each modules implementing the `appmodule.HasEndBlocker` interface, in the order defined in `OrderEndBlockers`. +* `EndBlock(context.Context) ([]abci.ValidatorUpdate, error)`: At the end of each block, this function is called from [`BaseApp`](../../learn/advanced/00-baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./06-preblock-beginblock-endblock.md) function of each modules implementing the `appmodule.HasABCIEndBlock` interface, in the order defined in `OrderEndBlockers`. Extended implementation for modules that need to update the validator set (typically used by the staking module). * (Optional) `RegisterLegacyAminoCodec(cdc *codec.LegacyAmino)`: Registers the [`codec.LegacyAmino`s](../../learn/advanced/05-encoding.md#amino) of each of the application module. This function is usually called early on in the [application's construction](../../learn/beginner/00-app-anatomy.md#constructor). * `RegisterInterfaces(registry codectypes.InterfaceRegistry)`: Registers interface types and implementations of each of the application's `AppModule`. * (Optional) `RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux)`: Registers gRPC routes for modules. diff --git a/docs/build/building-modules/05-protobuf-annotations.md b/docs/build/building-modules/05-protobuf-annotations.md index 9843a63398fc..29dfe19d5f9c 100644 --- a/docs/build/building-modules/05-protobuf-annotations.md +++ b/docs/build/building-modules/05-protobuf-annotations.md @@ -2,9 +2,9 @@ sidebar_position: 1 --- -# ProtocolBuffer Annotations +# Protocol buffer Annotations -This document explains the various protobuf scalars that have been added to make working with protobuf easier for Cosmos SDK application developers +This document explains the various protobuf scalars that have been added to make working with protobuf easier for Cosmos SDK application developers. ## Signer @@ -85,7 +85,7 @@ option (cosmos_proto.method_added_in) = "simapp v24.0.0"; The amino codec was removed in `v0.50+`, this means there is not a need register `legacyAminoCodec`. To replace the amino codec, Amino protobuf annotations are used to provide information to the amino codec on how to encode and decode protobuf messages. :::note -Amino annotations are only used for backwards compatibility with amino. New modules are not required use amino annotations. +Amino annotations are only used for backwards compatibility with amino. ::: The below annotations are used to provide information to the amino codec on how to encode and decode protobuf messages in a backwards compatible manner. diff --git a/docs/build/building-modules/06-keeper.md b/docs/build/building-modules/06-keeper.md index 59180170cfd7..deb6727842a0 100644 --- a/docs/build/building-modules/06-keeper.md +++ b/docs/build/building-modules/06-keeper.md @@ -5,7 +5,7 @@ sidebar_position: 1 # Keepers :::note Synopsis -`Keeper`s refer to a Cosmos SDK abstraction whose role is to manage access to the subset of the state defined by various modules. `Keeper`s are module-specific, i.e. the subset of state defined by a module can only be accessed by a `keeper` defined in said module. If a module needs to access the subset of state defined by another module, a reference to the second module's internal `keeper` needs to be passed to the first one. This is done in `app.go` during the instantiation of module keepers. +`Keeper`s refer to a Cosmos SDK abstraction whose role is to manage access to the subset of the state defined by various modules. `Keeper`s are module-specific, i.e. the subset of state defined by a module can only be accessed by a `keeper` defined in said module. If a module needs to access the subset of state defined by another module, a reference to the second module's internal `keeper` needs to be passed to the first one. This is done by specifying the module inputs in the `depinject` config; `runtime` will ensure that the correct `keeper` is passed to the module. ::: :::note Pre-requisite Readings @@ -28,9 +28,9 @@ The core idea behind the object-capabilities approach is to only reveal what is ```go type Keeper struct { - // External keepers, if any + appmodule.Environment - // Store key(s) + // External keepers, if any // codec @@ -46,8 +46,8 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/staking/keeper/keeper Let us go through the different parameters: +* Environment is a struct that holds the necessary references to services available to the modules. This includes the [store services](../../advanced/04-store.md#store-services), the [event manager](../../learn/advanced/06-events.md) and more. * An expected `keeper` is a `keeper` external to a module that is required by the internal `keeper` of said module. External `keeper`s are listed in the internal `keeper`'s type definition as interfaces. These interfaces are themselves defined in an `expected_keepers.go` file in the root of the module's folder. In this context, interfaces are used to reduce the number of dependencies, as well as to facilitate the maintenance of the module itself. -* `KVStoreService`s grant access to the store(s) of the [multistore](../../learn/advanced/04-store.md) managed by the module. They should always remain unexposed to external modules. * `cdc` is the [codec](../../learn/advanced/05-encoding.md) used to marshal and unmarshal structs to/from `[]byte`. The `cdc` can be any of `codec.BinaryCodec`, `codec.JSONCodec` or `codec.Codec` based on your requirements. It can be either a proto or amino codec as long as they implement these interfaces. * The authority listed is a module account or user account that has the right to change module level parameters. Previously this was handled by the param module, which has been deprecated. @@ -55,6 +55,21 @@ Of course, it is possible to define different types of internal `keeper`s for th ## Environment +Environment is a struct, part of the module Core APIs (`cosmossdk.io/core/appmodule`). +A keeper should embed the `environment` struct to get access to the necessary references to services available to the modules. [Runtime](../../build/building-apps/00-runtime.md) ensures that the `Environment` struct is scoped to the module. + +```go reference +https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.6/core/appmodule/v2/environment.go#L14-L29 +``` + +All services are then easily available to the module wherever the `keeper` is used: + +```go reference +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/x/gov/keeper/proposal.go#L110-L112 +``` + +Learn more about those services in the [core api](../../learn/advanced/02-core.md) documentation. + ## Implementing Methods `Keeper`s primarily expose methods for business logic, as validity checks should have already been performed by the [`Msg` server](./03-msg-services.md) when `keeper`s' methods are called. @@ -67,5 +82,4 @@ State management is recommended to be done via [Collections](../packages/collect In the Cosmos SDK, it is crucial to be methodical and selective when managing state within a module, as improper state management can lead to inefficiency, security risks, and scalability issues. Not all data belongs in the on-chain state; it's important to store only essential blockchain data that needs to be verified by consensus. Storing unnecessary information, especially client-side data, can bloat the state and slow down performance. Instead, developers should focus on using an off-chain database to handle supplementary data, extending the API as needed. This approach minimizes on-chain complexity, optimizes resource usage, and keeps the blockchain state lean and efficient, ensuring scalability and smooth operations. - The Cosmos SDK leverages Protocol Buffers (protobuf) for efficient state management, providing a well-structured, binary encoding format that ensures compatibility and performance across different modules. The SDK’s recommended approach for managing state is through the [collections package](../pacakges/02-collections.md), which simplifies state handling by offering predefined data structures like maps and indexed sets, reducing the complexity of managing raw state data. While users can opt for custom encoding schemes if they need more flexibility or have specialized requirements, they should be aware that such custom implementations may not integrate seamlessly with indexers that decode state data on the fly. This could lead to challenges in data retrieval, querying, and interoperability, making protobuf a safer and more future-proof choice for most use cases. diff --git a/docs/learn/advanced/00-baseapp.md b/docs/learn/advanced/00-baseapp.md index e30bb4a9a0e4..8fea13d4fd39 100644 --- a/docs/learn/advanced/00-baseapp.md +++ b/docs/learn/advanced/00-baseapp.md @@ -92,7 +92,7 @@ Finally, a few more important parameters: * `voteInfos`: This parameter carries the list of validators whose precommit is missing, either because they did not vote or because the proposer did not include their vote. This information is - carried by the [Context](./02-context.md) and can be used by the application for various things like + carried by the [Context](./17-context.md) and can be used by the application for various things like punishing absent validators. * `minGasPrices`: This parameter defines the minimum gas prices accepted by the node. This is a **local** parameter, meaning each full-node can set a different `minGasPrices`. It is used in the @@ -474,7 +474,7 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/baseapp/abci.go#L894 * Initialize the [block gas meter](../beginner/04-gas-fees.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. * Run the application's [`beginBlocker()`](../beginner/00-app-anatomy.md#beginblocker-and-endblocker), which mainly runs the [`BeginBlocker()`](../../build/building-modules/06-preblock-beginblock-endblock.md#beginblocker-and-endblocker) method of each of the modules. -* Set the [`VoteInfos`](https://docs.cometbft.com/v1.0/spec/abci/abci++_methods#voteinfo) of the application, i.e. the list of validators whose _precommit_ for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./02-context.md) so that it can be used during transaction execution and EndBlock. +* Set the [`VoteInfos`](https://docs.cometbft.com/v1.0/spec/abci/abci++_methods#voteinfo) of the application, i.e. the list of validators whose _precommit_ for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./17-context.md) so that it can be used during transaction execution and EndBlock. #### Transaction Execution diff --git a/docs/learn/advanced/01-transactions.md b/docs/learn/advanced/01-transactions.md index 5eba0acc1759..35d319f19b00 100644 --- a/docs/learn/advanced/01-transactions.md +++ b/docs/learn/advanced/01-transactions.md @@ -16,7 +16,7 @@ sidebar_position: 1 ## Transactions -Transactions are comprised of metadata held in [contexts](./02-context.md) and [`sdk.Msg`s](../../build/building-modules/02-messages-and-queries.md) that trigger state changes within a module through the module's Protobuf [`Msg` service](../../build/building-modules/03-msg-services.md). +Transactions are comprised of metadata held in [contexts](./17-context.md) and [`sdk.Msg`s](../../build/building-modules/02-messages-and-queries.md) that trigger state changes within a module through the module's Protobuf [`Msg` service](../../build/building-modules/03-msg-services.md). When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's `sdk.Msg` must be signed using the private key associated with the appropriate account(s), before the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../beginner/01-tx-lifecycle.md). diff --git a/docs/learn/advanced/17-core.md b/docs/learn/advanced/02-core.md similarity index 85% rename from docs/learn/advanced/17-core.md rename to docs/learn/advanced/02-core.md index b6a453fbb130..b1b93235e403 100644 --- a/docs/learn/advanced/17-core.md +++ b/docs/learn/advanced/02-core.md @@ -4,8 +4,7 @@ sidebar_position: 1 # Core -Core is package which specifies the interfaces for core components of the Cosmos SDK. Other -packages in the SDK implement these interfaces to provide the core functionality. This design +Core (`cosmossdk.io/core`) is package which specifies the interfaces for core components of the Cosmos SDK. Other packages in the SDK implement these interfaces to provide the core functionality. This design provides modularity and flexibility to the SDK, allowing developers to swap out implementations of core components as needed. As such it is often referred to as the Core API. @@ -16,19 +15,28 @@ services of the SDK, such as the KVStore, EventManager, and Logger. The `Enviro passed to modules and other components of the SDK to provide access to these services. ```go reference -https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/appmodule/v2/environment.go#L16-L29 +https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.6/core/appmodule/v2/environment.go#L16-L29 ``` -Historically the SDK has used an [sdk.Context](02-context.md) to pass around services and data. +Historically the SDK has used an [sdk.Context](https://docs.cosmos.network/v0.50/learn/advanced/context) to pass around services and data. `Environment` is a newer construct that is intended to replace an `sdk.Context` in many cases. `sdk.Context` will be deprecated in the future on the same timeline as [Baseapp](00-baseapp.md). +## Logger + +The [Logger](https://pkg.go.dev/cosmossdk.io/log) provides a structured logging interface to the SDK. It is used throughout the SDK to log messages at various levels of severity. The Logger service is a thin wrapper around the [zerolog](https://github.com/rs/zerolog) logging library. +When used via environment, the logger is scoped to the module that is using it. + +```go reference +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/runtime/module.go#L274 +``` + ## Branch Service The [BranchService](https://pkg.go.dev/cosmossdk.io/core/branch#Service.Execute) provides an interface to execute arbitrary code in a branched store. This is useful for executing code that needs to make changes to the store, but may need to be rolled back if an error occurs. -Below is a contrived example based on the `x/epoch` module's BeginBlocker logic. +Below is a contrived example based on the `x/epochs` module's BeginBlocker logic. ```go func (k Keeper) BeginBlocker(ctx context.Context) error { diff --git a/docs/learn/advanced/04-store.md b/docs/learn/advanced/04-store.md index 9c5b7dd9913b..d1b20d20ef66 100644 --- a/docs/learn/advanced/04-store.md +++ b/docs/learn/advanced/04-store.md @@ -45,7 +45,9 @@ The `GetStoreType` is a simple method that returns the type of store, whereas a https://github.com/cosmos/cosmos-sdk/blob/store/v1.1.1/store/types/store.go#L287-L303 ``` -Branching and cache is used ubiquitously in the Cosmos SDK and required to be implemented on every store type. A storage branch creates an isolated, ephemeral branch of a store that can be passed around and updated without affecting the main underlying store. This is used to trigger temporary state-transitions that may be reverted later should an error occur. Read more about it in [context](./02-context.md#store-branching) +Branching and cache is used ubiquitously in the Cosmos SDK and required to be implemented on every store type. A storage branch creates an isolated, ephemeral branch of a store that can be passed around and updated without affecting the main underlying store. This is used to trigger temporary state-transitions that may be reverted later should an error occur. + +Branching is available as a service for modules. Read more about it in the [core](./02-core.md#branch-service) documentation. ### Commit Store @@ -147,29 +149,7 @@ The documentation on the IAVL Tree is located [here](https://github.com/cosmos/i https://github.com/cosmos/cosmos-sdk/blob/store/v1.1.1/store/dbadapter/store.go#L13-L16 ``` -`dbadapter.Store` embeds `corestore.KVStoreWithBatch`, meaning most of the `KVStore` interface functions are implemented. The other functions (mostly miscellaneous) are manually implemented. This store is primarily used within [Transient Stores](#transient-store) - -### `Transient` Store - -`Transient.Store` is a base-layer `KVStore` which is automatically discarded at the end of the block. - -```go reference -https://github.com/cosmos/cosmos-sdk/blob/store/v1.1.1/store/transient/store.go#L16-L19 -``` - -`Transient.Store` is a `dbadapter.Store` with a `coretesting.NewMemDB()`. All `KVStore` methods are reused. When `Store.Commit()` is called, a new `dbadapter.Store` is assigned, discarding previous reference and making it garbage collected. - -This type of store is useful to persist information that is only relevant per-block. One example would be to store parameter changes (i.e. a bool set to `true` if a parameter changed in a block). - -```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/x/params/types/subspace.go#L23-L33 -``` - -Transient stores are typically accessed via the [`context`](./02-context.md) via the `TransientStore()` method: - -```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/types/context.go#L344-L347 -``` +`dbadapter.Store` embeds `corestore.KVStoreWithBatch`, meaning most of the `KVStore` interface functions are implemented. The other functions (mostly miscellaneous) are manually implemented. ## KVStore Wrappers @@ -215,12 +195,7 @@ By default, all `KVStores` are wrapped in `GasKv.Stores` when retrieved. This is https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/types/context.go#L339-L342 ``` -In this case, the gas configuration set in the `context` is used. The gas configuration can be set using the `WithKVGasConfig` method of the `context`. -Otherwise it uses the following default: - -```go reference -https://github.com/cosmos/cosmos-sdk/blob/store/v1.1.1/store/types/gas.go#L231-L242 -``` +`KVStores` can be accessed in their corresponding modules by using the [`kvStoreService` and `memStoreService`](./02-core.md#kvstore-service). ### `TraceKv` Store diff --git a/docs/learn/advanced/08-events.md b/docs/learn/advanced/08-events.md index cea128dac93e..64d2baa1c979 100644 --- a/docs/learn/advanced/08-events.md +++ b/docs/learn/advanced/08-events.md @@ -77,10 +77,11 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/types/events.go#L62-L86 ``` Module developers should handle Event emission via the `EventManager#EmitTypedEvent` or `EventManager#EmitEvent` in each -message `Handler` and in each `BeginBlock`/`EndBlock` handler. The `EventManager` is accessed via -the [`Context`](./02-context.md), where Event should be already registered, and emitted like this: +message `Handler` and in each `BeginBlock`/`EndBlock` handler. +The `EventManager` is accessible via the event service, present in the `Environment` struct. +This event service is a [core service](./02-core.md) available to all modules. -Note: it is preferred to use `EmitTypedEvent` over `EmitEvent` as the latter has been deprecated. +Events can be emitted like this using the `EventService`: **Typed events:** @@ -90,18 +91,28 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/x/group/keeper/msg_serv **Legacy events:** -```go -ctx.EventManager().EmitEvent( - sdk.NewEvent(eventType, sdk.NewAttribute(attributeKey, attributeValue)), -) +```go reference +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/x/gov/keeper/vote.go#L91-L95 ``` -Where the `EventManager` is accessed via the [`Context`](./02-context.md). - See the [`Msg` services](../../build/building-modules/03-msg-services.md) concept doc for a more detailed view on how to typically implement Events and use the `EventManager` in modules. -## Subscribing to Events +## Default Events + +There are a few events that are automatically emitted for all messages, directly from `baseapp`. + +* `message.action`: The name of the message type. +* `message.sender`: The address of the message signer. +* `message.module`: The name of the module that emitted the message. + +:::tip +The module name is assumed by `baseapp` to be the second element of the message route: `"cosmos.bank.v1beta1.MsgSend" -> "bank"`. +In case a module does not follow the standard message path, (e.g. IBC), it is advised to keep emitting the module name event. +`Baseapp` only emits that event if the module have not already done so. +::: + +## Subscribing to CometBFT Events You can use CometBFT's [Websocket](https://docs.cometbft.com/v1.0/explanation/core/subscription) to subscribe to Events by calling the `subscribe` RPC method: @@ -143,17 +154,3 @@ Subscribing to this Event would be done like so: where `ownerAddress` is an address following the [`AccAddress`](../beginner/03-accounts.md#addresses) format. The same way can be used to subscribe to [legacy events](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/bank/types/events.go). - -## Default Events - -There are a few events that are automatically emitted for all messages, directly from `baseapp`. - -* `message.action`: The name of the message type. -* `message.sender`: The address of the message signer. -* `message.module`: The name of the module that emitted the message. - -:::tip -The module name is assumed by `baseapp` to be the second element of the message route: `"cosmos.bank.v1beta1.MsgSend" -> "bank"`. -In case a module does not follow the standard message path, (e.g. IBC), it is advised to keep emitting the module name event. -`Baseapp` only emits that event if the module have not already done so. -::: diff --git a/docs/learn/advanced/02-context.md b/docs/learn/advanced/17-context.md similarity index 95% rename from docs/learn/advanced/02-context.md rename to docs/learn/advanced/17-context.md index eb0405df3fab..77b1a6285140 100644 --- a/docs/learn/advanced/02-context.md +++ b/docs/learn/advanced/17-context.md @@ -5,7 +5,7 @@ sidebar_position: 1 # Context :::note Synopsis -The `context` is a data structure intended to be passed from function to function that carries information about the current state of the application. It provides access to a branched storage (a safe branch of the entire state) as well as useful objects and information like `gasMeter`, `block height`, `consensus parameters` and more. +The `context` is a data structure that carries information about the current state of the application. It provides access to a branched storage (a safe branch of the entire state) as well as useful objects and information like `gasMeter`, `block height`, `consensus parameters` and more. ::: :::note Pre-requisite Readings @@ -15,6 +15,10 @@ The `context` is a data structure intended to be passed from function to functio ::: +:::warning +The `sdk.Context` should not be used directly. `Runtime` is implementing the [core services](./02-core.md), which are using directly the `sdk.Context`. +::: + ## Context Definition The Cosmos SDK `Context` is a custom data structure that contains Go's stdlib [`context`](https://pkg.go.dev/context) as its base, and has many additional types within its definition that are specific to the Cosmos SDK. The `Context` is integral to transaction processing in that it allows modules to easily access their respective [store](./04-store.md#base-layer-kvstores) in the [`multistore`](./04-store.md#multistore) and retrieve transactional context such as the block header and gas meter. diff --git a/docs/learn/beginner/04-gas-fees.md b/docs/learn/beginner/04-gas-fees.md index ea9af2e492b7..de9a308f91c6 100644 --- a/docs/learn/beginner/04-gas-fees.md +++ b/docs/learn/beginner/04-gas-fees.md @@ -26,7 +26,7 @@ In the Cosmos SDK, `gas` is a special unit that is used to track the consumption In the Cosmos SDK, `gas` is a simple alias for `uint64`, and is managed by an object called a _gas meter_. Gas meters implement the `GasMeter` interface ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/store/types/gas.go#L40-L51 +https://github.com/cosmos/cosmos-sdk/blob/b795646/store/types/gas.go#L40-L51 ``` where: @@ -40,17 +40,21 @@ where: * `IsPastLimit()` returns `true` if the amount of gas consumed by the gas meter instance is strictly above the limit, `false` otherwise. * `IsOutOfGas()` returns `true` if the amount of gas consumed by the gas meter instance is above or equal to the limit, `false` otherwise. -The gas meter is generally held in [`ctx`](../advanced/02-context.md), and consuming gas is done with the following pattern: +The gas meter is held under the `GasMeterService` in [`Environment`](../advanced/02-core.md), and consuming gas is done with the following pattern: + +:::note +The gas.Service does not give access to all the methods of the gas meter. +::: ```go -ctx.GasMeter().ConsumeGas(amount, "description") +environment.GasMeter(ctx).Consume(amount, "description") ``` By default, the Cosmos SDK makes use of two different gas meters, the [main gas meter](#main-gas-meter) and the [block gas meter](#block-gas-meter). ### Main Gas Meter -`ctx.GasMeter()` is the main gas meter of the application. The main gas meter is initialized in `FinalizeBlock` via `setFinalizeBlockState`, and then tracks gas consumption during execution sequences that lead to state-transitions, i.e. those originally triggered by [`FinalizeBlock`](../advanced/00-baseapp.md#finalizeblock). At the beginning of each transaction execution, the main gas meter **must be set to 0** in the [`AnteHandler`](#antehandler), so that it can track gas consumption per-transaction. +The main gas meter is initialized in `FinalizeBlock` via `setFinalizeBlockState`, and then tracks gas consumption during execution sequences that lead to state-transitions, i.e. those originally triggered by [`FinalizeBlock`](../advanced/00-baseapp.md#finalizeblock). At the beginning of each transaction execution, the main gas meter **must be set to 0** in the [`AnteHandler`](#antehandler), so that it can track gas consumption per-transaction. Gas consumption can be done manually, generally by the module developer in the [`BeginBlocker`, `EndBlocker`](../../build/building-modules/06-preblock-beginblock-endblock.md) or [`Msg` service](../../build/building-modules/03-msg-services.md), but most of the time it is done automatically whenever there is a read or write to the store. This automatic gas consumption logic is implemented in a special store called [`GasKv`](../advanced/04-store.md#gaskv-store).