Co-authored-by: Matt Kocubinski <mkocubinski@gmail.com> Co-authored-by: Julien Robert <julien@rbrt.fr>
This commit is contained in:
parent
befdf581a2
commit
e4422645fe
@ -16,14 +16,15 @@ While encoding in the Cosmos SDK used to be mainly handled by `go-amino` codec,
|
||||
|
||||
## Encoding
|
||||
|
||||
The Cosmos SDK utilizes two binary wire encoding protocols, [Amino](https://github.com/tendermint/go-amino/) which is an object encoding specification and [Protocol Buffers](https://developers.google.com/protocol-buffers), a subset of Proto3 with an extension for
|
||||
interface support. See the [Proto3 spec](https://developers.google.com/protocol-buffers/docs/proto3)
|
||||
for more information on Proto3, which Amino is largely compatible with (but not with Proto2).
|
||||
The Cosmos SDK supports two wire encoding protocols. Binary encoding is fulfilled by [Protocol
|
||||
Buffers](https://developers.google.com/protocol-buffers), specifically the
|
||||
[gogoprotobuf](https://github.com/cosmos/gogoproto/) implementation, which is a subset of
|
||||
[Proto3](https://developers.google.com/protocol-buffers/docs/proto3) with an extension for
|
||||
interface support. Text encoding is fulfilled by [Amino](https://github.com/tendermint/go-amino).
|
||||
|
||||
Due to Amino having significant performance drawbacks, being reflection-based, and
|
||||
not having any meaningful cross-language/client support, Protocol Buffers, specifically
|
||||
[gogoprotobuf](https://github.com/cosmos/gogoproto/), is being used in place of Amino.
|
||||
Note, this process of using Protocol Buffers over Amino is still an ongoing process.
|
||||
Due to Amino having significant performance drawbacks, being reflection-based, and not having
|
||||
any meaningful cross-language/client support, Amino is only used to generate JSON (Amino
|
||||
JSON) in order to support the Amino JSON sign mode, and for JSON RPC endpoints.
|
||||
|
||||
Binary wire encoding of types in the Cosmos SDK can be broken down into two main
|
||||
categories, client encoding and store encoding. Client encoding mainly revolves
|
||||
@ -31,23 +32,19 @@ around transaction processing and signing, whereas store encoding revolves aroun
|
||||
types used in state-machine transitions and what is ultimately stored in the Merkle
|
||||
tree.
|
||||
|
||||
For store encoding, protobuf definitions can exist for any type and will typically
|
||||
have an Amino-based "intermediary" type. Specifically, the protobuf-based type
|
||||
definition is used for serialization and persistence, whereas the Amino-based type
|
||||
is used for business logic in the state-machine where they may convert back-n-forth.
|
||||
Note, the Amino-based types may slowly be phased-out in the future, so developers
|
||||
should take note to use the protobuf message definitions where possible.
|
||||
For storage encoding, module developers are encouraged to use Protobuf encoding for their types
|
||||
but may choose any encoding schema they like. The
|
||||
[collections](../../build/packages/02-collections.md) package automatically handles encoding and
|
||||
decoding of state for you.
|
||||
|
||||
In the `codec` package, there exists two core interfaces, `BinaryCodec` and `JSONCodec`,
|
||||
where the former encapsulates the current Amino interface except it operates on
|
||||
types implementing the latter instead of generic `interface{}` types.
|
||||
|
||||
The `ProtoCodec`, where both binary and JSON serialization is handled
|
||||
via Protobuf. This means that modules may use Protobuf encoding, but the types must
|
||||
implement `ProtoMarshaler`. If modules wish to avoid implementing this interface
|
||||
for their types, this is autogenerated via [buf](https://buf.build/)
|
||||
|
||||
Modules are recommended to use [collections](../../build/packages/02-collections.md) for handling encoding and decoding of state. Usage of collections handles marshal and unmarshal for you. By default protobuf is used but other encodings can be used if preferred.
|
||||
The `ProtoCodec`, where both binary and JSON serialization is handled via Protobuf. This means
|
||||
that modules may use Protobuf encoding, but the types must implement `ProtoMarshaler`. If
|
||||
modules wish to avoid implementing this interface for their types, this is autogenerated via
|
||||
[buf](https://buf.build/)
|
||||
|
||||
### Gogoproto
|
||||
|
||||
|
||||
141
docs/learn/advanced/17-core.md
Normal file
141
docs/learn/advanced/17-core.md
Normal file
@ -0,0 +1,141 @@
|
||||
---
|
||||
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
|
||||
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.
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/appmodule/v2/environment.go#L16-L29
|
||||
```
|
||||
|
||||
Historically the SDK has used an [sdk.Context](02-context.md) 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).
|
||||
|
||||
## 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.
|
||||
|
||||
```go
|
||||
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](https://pkg.go.dev/cosmossdk.io/core@v1.0.0-alpha.4/event#Manager)
|
||||
which can be used to emit events. For information on how to emit events and their meaning
|
||||
in the SDK see the [Events](08-events.md) 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`.
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/event/service.go#L18-L29
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/gas/service.go#L26-L54
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/a3729c1ad6ba2fb46f879ec7ea67c3afc02e9859/core/header/service.go#L11-L23
|
||||
```
|
||||
|
||||
### 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.
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/489aaae40234f1015a7bbcfa9384a89dc8de8153/runtime/v2/module.go#L262-L288
|
||||
```
|
||||
|
||||
These bindings are applied to the `depinject` container in simapp/v2 as shown below.
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/489aaae40234f1015a7bbcfa9384a89dc8de8153/simapp/v2/app_di.go#L72-L74
|
||||
```
|
||||
|
||||
## Query and Message Router Service
|
||||
|
||||
Both the query and message router services are implementation of the same interface, `router.Service`.
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/router/service.go#L11-L16
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/transaction/service.go#L21-L25
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
```go reference
|
||||
https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/store/service.go#L5-L11
|
||||
```
|
||||
|
||||
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`.
|
||||
Loading…
Reference in New Issue
Block a user