From dfb56acb924efbeab1019b8cb851629a151c1d1f Mon Sep 17 00:00:00 2001 From: Matt Kocubinski Date: Fri, 4 Oct 2024 15:13:07 -0500 Subject: [PATCH 1/6] docs(core): create core docs --- core/header/service.go | 15 ++++ docs/learn/advanced/05-encoding.md | 35 ++++----- docs/learn/advanced/17-core.md | 119 +++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 19 deletions(-) create mode 100644 docs/learn/advanced/17-core.md diff --git a/core/header/service.go b/core/header/service.go index 8d36087a059c..5ea7fce55b99 100644 --- a/core/header/service.go +++ b/core/header/service.go @@ -13,6 +13,21 @@ type Service interface { HeaderInfo(context.Context) Info } +type HeaderInfo interface { + Bytes() ([]byte, error) + FromBytes([]byte) error +} + +type GenericService[T HeaderInfo] interface { + HeaderInfo(context.Context) T +} + +// let consumers cast when necessary + +type CastingService interface { + HeaderInfo(context.Context) HeaderInfo +} + // Info defines a struct that contains information about the header type Info struct { Height int64 // Height returns the height of the block diff --git a/docs/learn/advanced/05-encoding.md b/docs/learn/advanced/05-encoding.md index 4a3af677d61d..07fca0e6bb01 100644 --- a/docs/learn/advanced/05-encoding.md +++ b/docs/learn/advanced/05-encoding.md @@ -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 diff --git a/docs/learn/advanced/17-core.md b/docs/learn/advanced/17-core.md new file mode 100644 index 000000000000..b41dd1f63133 --- /dev/null +++ b/docs/learn/advanced/17-core.md @@ -0,0 +1,119 @@ +--- +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 the [Context](02-context.md) to pass around services and data. `Environment` is a newer construct that is intended to replace the `Context` in many cases. `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 execution 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 reference +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 [Event Manager](https://pkg.go.dev/cosmossdk.io/core@v1.0.0-alpha.4/event#Manager) which can be used to emit events. For 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. \ No newline at end of file From 28b7e03ad849bbc5d3d4af0c74f69892e9d1742d Mon Sep 17 00:00:00 2001 From: Matt Kocubinski Date: Mon, 7 Oct 2024 10:56:17 -0500 Subject: [PATCH 2/6] clean up --- docs/learn/advanced/17-core.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/learn/advanced/17-core.md b/docs/learn/advanced/17-core.md index b41dd1f63133..1610ab85acab 100644 --- a/docs/learn/advanced/17-core.md +++ b/docs/learn/advanced/17-core.md @@ -116,4 +116,4 @@ uses these flags in ante handlers to skip certain checks while in `Check` or `Si 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. \ No newline at end of file +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`. From 97061cf801d624071cd8db9464ddd5f2505fdef9 Mon Sep 17 00:00:00 2001 From: Matt Kocubinski Date: Mon, 7 Oct 2024 10:57:40 -0500 Subject: [PATCH 3/6] revert --- core/header/service.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/core/header/service.go b/core/header/service.go index 5ea7fce55b99..8d36087a059c 100644 --- a/core/header/service.go +++ b/core/header/service.go @@ -13,21 +13,6 @@ type Service interface { HeaderInfo(context.Context) Info } -type HeaderInfo interface { - Bytes() ([]byte, error) - FromBytes([]byte) error -} - -type GenericService[T HeaderInfo] interface { - HeaderInfo(context.Context) T -} - -// let consumers cast when necessary - -type CastingService interface { - HeaderInfo(context.Context) HeaderInfo -} - // Info defines a struct that contains information about the header type Info struct { Height int64 // Height returns the height of the block From 631cc280182227e0b4800c0396d4c94d6a007463 Mon Sep 17 00:00:00 2001 From: Matt Kocubinski Date: Mon, 7 Oct 2024 10:59:50 -0500 Subject: [PATCH 4/6] formatting --- docs/learn/advanced/17-core.md | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/docs/learn/advanced/17-core.md b/docs/learn/advanced/17-core.md index 1610ab85acab..99c79e3dcad6 100644 --- a/docs/learn/advanced/17-core.md +++ b/docs/learn/advanced/17-core.md @@ -46,9 +46,13 @@ committed. If an error occurs, the changes will be rolled back. ## Event Service -The Event Service returns a handle to an [Event Manager](https://pkg.go.dev/cosmossdk.io/core@v1.0.0-alpha.4/event#Manager) which can be used to emit events. For for information on how to emit events and their meaning in the SDK see the [Events](08-events.md) document. +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 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`. +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 @@ -56,7 +60,9 @@ https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/event/service ## 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. +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 @@ -64,7 +70,8 @@ https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/gas/service.g ## 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. +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 @@ -76,7 +83,8 @@ Core's service oriented architecture (SOA) allows for chain developers to define 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. +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 @@ -98,7 +106,9 @@ https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/router/servic 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. +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 @@ -108,7 +118,8 @@ https://github.com/cosmos/cosmos-sdk/blob/core/v1.0.0-alpha.4/core/transaction/s 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. +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 @@ -116,4 +127,8 @@ uses these flags in ante handlers to skip certain checks while in `Check` or `Si 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`. +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`. From c72f711b9b1b4381a7b7963eb7ac9472e9df6c71 Mon Sep 17 00:00:00 2001 From: Matt Kocubinski Date: Mon, 7 Oct 2024 11:02:27 -0500 Subject: [PATCH 5/6] proofiing --- docs/learn/advanced/17-core.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/learn/advanced/17-core.md b/docs/learn/advanced/17-core.md index 99c79e3dcad6..a2026e3d444d 100644 --- a/docs/learn/advanced/17-core.md +++ b/docs/learn/advanced/17-core.md @@ -14,12 +14,14 @@ The `Environment` struct is a core component of the Cosmos SDK. It provides acc 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 the [Context](02-context.md) to pass around services and data. `Environment` is a newer construct that is intended to replace the `Context` in many cases. `Context` will be deprecated in the future on the same timeline as [Baseapp](00-baseapp.md). +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 execution arbitrary code in a branched store. This is useful for executing code +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. From 89291c9c47e4a7ada807c97f501883b2ead3981f Mon Sep 17 00:00:00 2001 From: Matt Kocubinski Date: Mon, 7 Oct 2024 11:05:07 -0500 Subject: [PATCH 6/6] proof --- docs/learn/advanced/17-core.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/learn/advanced/17-core.md b/docs/learn/advanced/17-core.md index a2026e3d444d..85f5b110cec5 100644 --- a/docs/learn/advanced/17-core.md +++ b/docs/learn/advanced/17-core.md @@ -4,11 +4,16 @@ 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. +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. +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 @@ -49,7 +54,7 @@ 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 for information on how to emit events and their meaning +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