Core
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.
Environment
The Environment
struct is a core component of the Cosmos SDK. It provides access to the core
services of the SDK, such as the KVStore, EventManager, and Logger. The Environment
struct is
passed to modules and other components of the SDK to provide access to these services.
loading...
Historically the SDK has used an sdk.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.
Logger
The Logger 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 logging library. When used via environment, the logger is scoped to the module that is using it.
loading...
Branch Service
The BranchService 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/epochs
module's BeginBlocker logic.
func (k Keeper) BeginBlocker(ctx context.Context) error {
err := k.EpochInfo.Walk(
// ...
ctx,
nil,
func(key string, epochInfo types.EpochInfo) (stop bool, err error) {
// ...
if err := k.BranchService.Execute(ctx, func(ctx context.Context) error {
return k.AfterEpochEnd(ctx, epochInfo.Identifier, epochInfo.CurrentEpoch)
}); err != nil {
return true, err
}
})
}
Note that calls to BranchService.Execute
are atomic and cannot share state with each other
except when the transaction is successful. If successful, the changes made to the store will be
committed. If an error occurs, the changes will be rolled back.
Event Service
The Event Service returns a handle to an EventManager which can be used to emit events. For information on how to emit events and their meaning in the SDK see the Events document.
Note that core's EventManager
API is a subset of the EventManager API described above; the
latter will be deprecated and removed in the future. Roughly speaking legacy EmitTypeEvent
maps to Emit
and legacy EmitEvent
maps to EmitKV
.
loading...
Gas Service
The gas service encapsulates both gas configuration and a gas meter. Gas consumption is largely handled at the framework level for transaction processing and state access but modules can choose to use the gas service directly if needed.
loading...
Header Service
The header service provides access to the current block header. This is useful for modules that
need to access the block header fields like Time
and Height
during transaction processing.
loading...
Custom Header Service
Core's service oriented architecture (SOA) allows for chain developers to define a custom
implementation of the HeaderService
interface. This would involve creating a new struct that
satisfies HeaderService
but composes additional logic on top. An example of where this would
happen (when using depinject is shown below). Note this example is taken from runtime/v2
but
could easily be adapted to runtime/v1
(the default runtime 0.52). This same pattern can be
replicated for any core service.
loading...
These bindings are applied to the depinject
container in simapp/v2 as shown below.
loading...
Query and Message Router Service
Both the query and message router services are implementation of the same interface, router.Service
.
loading...
Both are exposed to modules so that arbitrary messages and queries can be routed to the
appropriate handler. This powerful abstraction allows module developers to fully decouple
modules from each other by using only the proto message for dispatching. This is particularly
useful for modules like x/accounts
which require a dynamic dispatch mechanism in order to
function.
TransactionService
loading...
The transaction service provides access to the execution mode a state machine transaction is
running in, which may be one of Check
, Recheck
, Simulate
or Finalize
. The SDK primarily
uses these flags in ante handlers to skip certain checks while in Check
or Simulate
modes,
but module developers may find uses for them as well.
KVStore Service
loading...
The KVStore service abstracts access to, and creation of, key-value stores. Most use cases will
be backed by a merkle-tree store, but developers can provide their own implementations if
needed. In the case of the KVStoreService
implementation provided in Environment
, module
developers should understand that calling OpenKVStore
will return a store already scoped to
the module's prefix. The wiring for this scoping is specified in runtime
.