Skip to content

Commit e442264

Browse files
mergify[bot]kocubinskijulienrbrt
authored
docs(core): create docs for environment and core API (backport #22156) (#22159)
Co-authored-by: Matt Kocubinski <[email protected]> Co-authored-by: Julien Robert <[email protected]>
1 parent befdf58 commit e442264

2 files changed

Lines changed: 157 additions & 19 deletions

File tree

docs/learn/advanced/05-encoding.md

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,38 +16,35 @@ While encoding in the Cosmos SDK used to be mainly handled by `go-amino` codec,
1616

1717
## Encoding
1818

19-
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
20-
interface support. See the [Proto3 spec](https://developers.google.com/protocol-buffers/docs/proto3)
21-
for more information on Proto3, which Amino is largely compatible with (but not with Proto2).
19+
The Cosmos SDK supports two wire encoding protocols. Binary encoding is fulfilled by [Protocol
20+
Buffers](https://developers.google.com/protocol-buffers), specifically the
21+
[gogoprotobuf](https://github.com/cosmos/gogoproto/) implementation, which is a subset of
22+
[Proto3](https://developers.google.com/protocol-buffers/docs/proto3) with an extension for
23+
interface support. Text encoding is fulfilled by [Amino](https://github.com/tendermint/go-amino).
2224

23-
Due to Amino having significant performance drawbacks, being reflection-based, and
24-
not having any meaningful cross-language/client support, Protocol Buffers, specifically
25-
[gogoprotobuf](https://github.com/cosmos/gogoproto/), is being used in place of Amino.
26-
Note, this process of using Protocol Buffers over Amino is still an ongoing process.
25+
Due to Amino having significant performance drawbacks, being reflection-based, and not having
26+
any meaningful cross-language/client support, Amino is only used to generate JSON (Amino
27+
JSON) in order to support the Amino JSON sign mode, and for JSON RPC endpoints.
2728

2829
Binary wire encoding of types in the Cosmos SDK can be broken down into two main
2930
categories, client encoding and store encoding. Client encoding mainly revolves
3031
around transaction processing and signing, whereas store encoding revolves around
3132
types used in state-machine transitions and what is ultimately stored in the Merkle
3233
tree.
3334

34-
For store encoding, protobuf definitions can exist for any type and will typically
35-
have an Amino-based "intermediary" type. Specifically, the protobuf-based type
36-
definition is used for serialization and persistence, whereas the Amino-based type
37-
is used for business logic in the state-machine where they may convert back-n-forth.
38-
Note, the Amino-based types may slowly be phased-out in the future, so developers
39-
should take note to use the protobuf message definitions where possible.
35+
For storage encoding, module developers are encouraged to use Protobuf encoding for their types
36+
but may choose any encoding schema they like. The
37+
[collections](../../build/packages/02-collections.md) package automatically handles encoding and
38+
decoding of state for you.
4039

4140
In the `codec` package, there exists two core interfaces, `BinaryCodec` and `JSONCodec`,
4241
where the former encapsulates the current Amino interface except it operates on
4342
types implementing the latter instead of generic `interface{}` types.
4443

45-
The `ProtoCodec`, where both binary and JSON serialization is handled
46-
via Protobuf. This means that modules may use Protobuf encoding, but the types must
47-
implement `ProtoMarshaler`. If modules wish to avoid implementing this interface
48-
for their types, this is autogenerated via [buf](https://buf.build/)
49-
50-
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.
44+
The `ProtoCodec`, where both binary and JSON serialization is handled via Protobuf. This means
45+
that modules may use Protobuf encoding, but the types must implement `ProtoMarshaler`. If
46+
modules wish to avoid implementing this interface for their types, this is autogenerated via
47+
[buf](https://buf.build/)
5148

5249
### Gogoproto
5350

docs/learn/advanced/17-core.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
---
2+
sidebar_position: 1
3+
---
4+
5+
# Core
6+
7+
Core is package which specifies the interfaces for core components of the Cosmos SDK. Other
8+
packages in the SDK implement these interfaces to provide the core functionality. This design
9+
provides modularity and flexibility to the SDK, allowing developers to swap out implementations
10+
of core components as needed. As such it is often referred to as the Core API.
11+
12+
## Environment
13+
14+
The `Environment` struct is a core component of the Cosmos SDK. It provides access to the core
15+
services of the SDK, such as the KVStore, EventManager, and Logger. The `Environment` struct is
16+
passed to modules and other components of the SDK to provide access to these services.
17+
18+
```go reference
19+
https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/appmodule/v2/environment.go#L16-L29
20+
```
21+
22+
Historically the SDK has used an [sdk.Context](02-context.md) to pass around services and data.
23+
`Environment` is a newer construct that is intended to replace an `sdk.Context` in many cases.
24+
`sdk.Context` will be deprecated in the future on the same timeline as [Baseapp](00-baseapp.md).
25+
26+
## Branch Service
27+
28+
The [BranchService](https://pkg.go.dev/cosmossdk.io/core/branch#Service.Execute) provides an
29+
interface to execute arbitrary code in a branched store. This is useful for executing code
30+
that needs to make changes to the store, but may need to be rolled back if an error occurs.
31+
Below is a contrived example based on the `x/epoch` module's BeginBlocker logic.
32+
33+
```go
34+
func (k Keeper) BeginBlocker(ctx context.Context) error {
35+
err := k.EpochInfo.Walk(
36+
// ...
37+
ctx,
38+
nil,
39+
func(key string, epochInfo types.EpochInfo) (stop bool, err error) {
40+
// ...
41+
if err := k.BranchService.Execute(ctx, func(ctx context.Context) error {
42+
return k.AfterEpochEnd(ctx, epochInfo.Identifier, epochInfo.CurrentEpoch)
43+
}); err != nil {
44+
return true, err
45+
}
46+
})
47+
}
48+
```
49+
50+
Note that calls to `BranchService.Execute` are atomic and cannot share state with each other
51+
except when the transaction is successful. If successful, the changes made to the store will be
52+
committed. If an error occurs, the changes will be rolled back.
53+
54+
## Event Service
55+
56+
The Event Service returns a handle to an [EventManager](https://pkg.go.dev/cosmossdk.io/[email protected]/event#Manager)
57+
which can be used to emit events. For information on how to emit events and their meaning
58+
in the SDK see the [Events](08-events.md) document.
59+
60+
Note that core's `EventManager` API is a subset of the EventManager API described above; the
61+
latter will be deprecated and removed in the future. Roughly speaking legacy `EmitTypeEvent`
62+
maps to `Emit` and legacy `EmitEvent` maps to `EmitKV`.
63+
64+
```go reference
65+
https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/event/service.go#L18-L29
66+
```
67+
68+
## Gas Service
69+
70+
The gas service encapsulates both gas configuration and a gas meter. Gas consumption is largely
71+
handled at the framework level for transaction processing and state access but modules can
72+
choose to use the gas service directly if needed.
73+
74+
```go reference
75+
https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/gas/service.go#L26-L54
76+
```
77+
78+
## Header Service
79+
80+
The header service provides access to the current block header. This is useful for modules that
81+
need to access the block header fields like `Time` and `Height` during transaction processing.
82+
83+
```go reference
84+
https://github.com/cosmos/cosmos-sdk/blob/a3729c1ad6ba2fb46f879ec7ea67c3afc02e9859/core/header/service.go#L11-L23
85+
```
86+
87+
### Custom Header Service
88+
89+
Core's service oriented architecture (SOA) allows for chain developers to define a custom
90+
implementation of the `HeaderService` interface. This would involve creating a new struct that
91+
satisfies `HeaderService` but composes additional logic on top. An example of where this would
92+
happen (when using depinject is shown below). Note this example is taken from `runtime/v2` but
93+
could easily be adapted to `runtime/v1` (the default runtime 0.52). This same pattern can be
94+
replicated for any core service.
95+
96+
```go reference
97+
https://github.com/cosmos/cosmos-sdk/blob/489aaae40234f1015a7bbcfa9384a89dc8de8153/runtime/v2/module.go#L262-L288
98+
```
99+
100+
These bindings are applied to the `depinject` container in simapp/v2 as shown below.
101+
102+
```go reference
103+
https://github.com/cosmos/cosmos-sdk/blob/489aaae40234f1015a7bbcfa9384a89dc8de8153/simapp/v2/app_di.go#L72-L74
104+
```
105+
106+
## Query and Message Router Service
107+
108+
Both the query and message router services are implementation of the same interface, `router.Service`.
109+
110+
```go reference
111+
https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/router/service.go#L11-L16
112+
```
113+
114+
Both are exposed to modules so that arbitrary messages and queries can be routed to the
115+
appropriate handler. This powerful abstraction allows module developers to fully decouple
116+
modules from each other by using only the proto message for dispatching. This is particularly
117+
useful for modules like `x/accounts` which require a dynamic dispatch mechanism in order to
118+
function.
119+
120+
## TransactionService
121+
122+
```go reference
123+
https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/transaction/service.go#L21-L25
124+
```
125+
126+
The transaction service provides access to the execution mode a state machine transaction is
127+
running in, which may be one of `Check`, `Recheck`, `Simulate` or `Finalize`. The SDK primarily
128+
uses these flags in ante handlers to skip certain checks while in `Check` or `Simulate` modes,
129+
but module developers may find uses for them as well.
130+
131+
## KVStore Service
132+
133+
```go reference
134+
https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/store/service.go#L5-L11
135+
```
136+
137+
The KVStore service abstracts access to, and creation of, key-value stores. Most use cases will
138+
be backed by a merkle-tree store, but developers can provide their own implementations if
139+
needed. In the case of the `KVStoreService` implementation provided in `Environment`, module
140+
developers should understand that calling `OpenKVStore` will return a store already scoped to
141+
the module's prefix. The wiring for this scoping is specified in `runtime`.

0 commit comments

Comments
 (0)