docs: rewrite building module section (2/n) -- env + core services (#22790)
Co-authored-by: Akhil Kumar P <36399231+akhilkumarpilli@users.noreply.github.com>
This commit is contained in:
co-authored by
Akhil Kumar P
parent
6cf9d57be9
commit
8ef35c39ba
@@ -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
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
|
||||
@@ -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 {
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
:::
|
||||
|
||||
@@ -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.
|
||||
@@ -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).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user