Skip to content

Commit

Permalink
Update "Core Concepts" docs (cosmos#7948)
Browse files Browse the repository at this point in the history
* Update "Core Concepts" docs

* Update tags

* Update more subsctions

* Revert basics

* ADd link to run-node

* Typo

* Add sign modes

* Finish transaction.md

* Update docs/core/baseapp.md

Co-authored-by: Marie Gauthier <[email protected]>

* Update docs/core/baseapp.md

Co-authored-by: Marie Gauthier <[email protected]>

* Update docs/core/baseapp.md

Co-authored-by: Marie Gauthier <[email protected]>

* Update docs/core/baseapp.md

Co-authored-by: Marie Gauthier <[email protected]>

* Update docs/core/baseapp.md

Co-authored-by: Marie Gauthier <[email protected]>

* Update docs/core/baseapp.md

Co-authored-by: Marie Gauthier <[email protected]>

* Wording

* Update docs/core/baseapp.md

Co-authored-by: Marie Gauthier <[email protected]>

* Revert basics changes

* revert space change

* typo

* Update docs/core/transactions.md

Co-authored-by: Marie Gauthier <[email protected]>

* Update docs/core/node.md

Co-authored-by: Robert Zaremba <[email protected]>

* Update docs/core/store.md

Co-authored-by: Robert Zaremba <[email protected]>

Co-authored-by: Marie Gauthier <[email protected]>
Co-authored-by: Robert Zaremba <[email protected]>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
4 people authored Nov 24, 2020
1 parent 13bc504 commit ccd0d63
Show file tree
Hide file tree
Showing 10 changed files with 285 additions and 244 deletions.
4 changes: 4 additions & 0 deletions docs/building-modules/msg-services.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ All `Msg` processing is done by a [`Msg`](messages-and-queries.md#msg-services)

As further described in [ADR 031](../architecture/adr-031-msg-service.md), this approach has the advantage of clearly specifying return types and generating server and client code.

Based on the definition of the `Msg` service, Protobuf generates a `MsgServer` interface. It is the role of the module developer to implement this interface, by implementing the state transition logic that should happen upon receival of each `Msg`. As an example, here is the generated `MsgServer` interface for `x/bank`, which exposes two `Msg`s:

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/bank/types/tx.pb.go#L285-L291

When possible, the existing module's [`Keeper`](keeper.md) should implement `MsgServer`, otherwise a `msgServer` struct that embeds the `Keeper` can be created, typically in `./keeper/msg_server.go`:

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/x/bank/keeper/msg_server.go#L14-L16
Expand Down
2 changes: 1 addition & 1 deletion docs/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ parent:

This repository contains reference documentation on the core concepts of the Cosmos SDK.

1. [`Baseapp`](./baseapp.md)
1. [`BaseApp`](./baseapp.md)
2. [Transaction](./transactions.md)
3. [Context](./context.md)
4. [Node Client](./node.md)
Expand Down
194 changes: 96 additions & 98 deletions docs/core/baseapp.md

Large diffs are not rendered by default.

40 changes: 12 additions & 28 deletions docs/core/context.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,9 @@ The `context` is a data structure intended to be passed from function to functio

The SDK `Context` is a custom data structure that contains Go's stdlib [`context`](https://golang.org/pkg/context) as its base, and has many additional types within its definition that are specific to the Cosmos SDK. he `Context` is integral to transaction processing in that it allows modules to easily access their respective [store](./store.md#base-layer-kvstores) in the [`multistore`](./store.md#multistore) and retrieve transactional context such as the block header and gas meter.

```go
type Context struct {
ctx context.Context
ms MultiStore
header tmproto.Header
chainID string
txBytes []byte
logger log.Logger
voteInfo []abci.VoteInfo
gasMeter GasMeter
blockGasMeter GasMeter
checkTx bool
minGasPrice DecCoins
consParams *abci.ConsensusParams
eventManager *EventManager
}
```
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/context.go#L16-L39

- **Context:** The base type is a Go [Context](https://golang.org/pkg/context), which is explained further in the [Go Context Package](#go-context-package) section below.
- **Context:** The base type is a Go [Context](https://golang.org/pkg/context), which is explained further in the [Go Context Package](#go-context-package) section below.
- **Multistore:** Every application's `BaseApp` contains a [`CommitMultiStore`](./store.md#multistore) which is provided when a `Context` is created. Calling the `KVStore()` and `TransientStore()` methods allows modules to fetch their respective [`KVStore`](./store.md#base-layer-kvstores) using their unique `StoreKey`.
- **ABCI Header:** The [header](https://tendermint.com/docs/spec/abci/abci.html#header) is an ABCI type. It carries important information about the state of the blockchain, such as block height and proposer of the current block.
- **Chain ID:** The unique identification number of the blockchain a block pertains to.
Expand All @@ -42,10 +26,10 @@ type Context struct {
- **VoteInfo:** A list of the ABCI type [`VoteInfo`](https://tendermint.com/docs/spec/abci/abci.html#voteinfo), which includes the name of a validator and a boolean indicating whether they have signed the block.
- **Gas Meters:** Specifically, a [`gasMeter`](../basics/gas-fees.md#main-gas-meter) for the transaction currently being processed using the context and a [`blockGasMeter`](../basics/gas-fees.md#block-gas-meter) for the entire block it belongs to. Users specify how much in fees they wish to pay for the execution of their transaction; these gas meters keep track of how much [gas](../basics/gas-fees.md) has been used in the transaction or block so far. If the gas meter runs out, execution halts.
- **CheckTx Mode:** A boolean value indicating whether a transaction should be processed in `CheckTx` or `DeliverTx` mode.
- **Min Gas Price:** The minimum [gas](../basics/gas-fees.md) price a node is willing to take in order to include a transaction in its block. This price is a local value configured by each node individually, and should therefore **not be used in any functions used in sequences leading to state-transitions**.
- **Min Gas Price:** The minimum [gas](../basics/gas-fees.md) price a node is willing to take in order to include a transaction in its block. This price is a local value configured by each node individually, and should therefore **not be used in any functions used in sequences leading to state-transitions**.
- **Consensus Params:** The ABCI type [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters), which specify certain limits for the blockchain, such as maximum gas for a block.
- **Event Manager:** The event manager allows any caller with access to a `Context` to emit [`Events`](./events.md). Modules may define module specific
`Events` by defining various `Types` and `Attributes` or use the common definitions found in `types/`. Clients can subscribe or query for these `Events`. These `Events` are collected throughout `DeliverTx`, `BeginBlock`, and `EndBlock` and are returned to Tendermint for indexing. For example:
`Events` by defining various `Types` and `Attributes` or use the common definitions found in `types/`. Clients can subscribe or query for these `Events`. These `Events` are collected throughout `DeliverTx`, `BeginBlock`, and `EndBlock` and are returned to Tendermint for indexing. For example:

```go
ctx.EventManager().EmitEvent(sdk.NewEvent(
Expand All @@ -63,7 +47,7 @@ are also designed to enable concurrency and to be used in goroutines.
Contexts are intended to be **immutable**; they should never be edited. Instead, the convention is
to create a child context from its parent using a `With` function. For example:

``` go
```go
childCtx = parentCtx.WithBlockHeader(header)
```

Expand All @@ -79,12 +63,12 @@ goes wrong. The pattern of usage for a Context is as follows:

1. A process receives a Context `ctx` from its parent process, which provides information needed to
perform the process.
2. The `ctx.ms` is **cache wrapped**, i.e. a cached copy of the [multistore](./store.md#multistore) is made so that the process can make changes to the state as it executes, without changing the original`ctx.ms`. This is useful to protect the underlying multistore in case the changes need to be reverted at some point in the execution.
2. The `ctx.ms` is **cache wrapped**, i.e. a cached copy of the [multistore](./store.md#multistore) is made so that the process can make changes to the state as it executes, without changing the original`ctx.ms`. This is useful to protect the underlying multistore in case the changes need to be reverted at some point in the execution.
3. The process may read and write from `ctx` as it is executing. It may call a subprocess and pass
`ctx` to it as needed.
`ctx` to it as needed.
4. When a subprocess returns, it checks if the result is a success or failure. If a failure, nothing
needs to be done - the cache wrapped `ctx` is simply discarded. If successful, the changes made to
the cache-wrapped `MultiStore` can be committed to the original `ctx.ms` via `Write()`.
needs to be done - the cache wrapped `ctx` is simply discarded. If successful, the changes made to
the cache-wrapped `MultiStore` can be committed to the original `ctx.ms` via `Write()`.

For example, here is a snippet from the [`runTx`](./baseapp.md#runtx-and-runmsgs) function in
[`baseapp`](./baseapp.md):
Expand All @@ -106,12 +90,12 @@ if result.IsOK() {
Here is the process:

1. Prior to calling `runMsgs` on the message(s) in the transaction, it uses `app.cacheTxContext()`
to cache-wrap the context and multistore.
to cache-wrap the context and multistore.
2. The cache-wrapped context, `runMsgCtx`, is used in `runMsgs` to return a result.
3. If the process is running in [`checkTxMode`](./baseapp.md#checktx), there is no need to write the
changes - the result is returned immediately.
changes - the result is returned immediately.
4. If the process is running in [`deliverTxMode`](./baseapp.md#delivertx) and the result indicates
a successful run over all the messages, the cached multistore is written back to the original.
a successful run over all the messages, the cached multistore is written back to the original.

## Next {hide}

Expand Down
55 changes: 30 additions & 25 deletions docs/core/node.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,60 +12,65 @@ The main endpoint of an SDK application is the daemon client, otherwise known as

## `main` function

The full-node client of any SDK application is built by running a `main` function. The client is generally named by appending the `-d` suffix to the application name (e.g. `appd` for an application named `app`), and the `main` function is defined in a `./cmd/appd/main.go` file. Running this function creates an executable `.appd` that comes with a set of commands. For an app named `app`, the main command is [`appd start`](#start-command), which starts the full-node.
The full-node client of any SDK application is built by running a `main` function. The client is generally named by appending the `-d` suffix to the application name (e.g. `appd` for an application named `app`), and the `main` function is defined in a `./appd/cmd/main.go` file. Running this function creates an executable `appd` that comes with a set of commands. For an app named `app`, the main command is [`appd start`](#start-command), which starts the full-node.

In general, developers will implement the `main.go` function with the following structure:

- First, a [`codec`](./encoding.md) is instanciated for the application.
- First, an [`appCodec`](./encoding.md) is instanciated for the application.
- Then, the `config` is retrieved and config parameters are set. This mainly involves setting the bech32 prefixes for [addresses and pubkeys](../basics/accounts.md#addresses-and-pubkeys).
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/config.go#L10-L21
- Using [cobra](https://github.com/spf13/cobra), the root command of the full-node client is created. After that, all the custom commands of the application are added using the `AddCommand()` method of `rootCmd`.
- Add default server commands to `rootCmd` using the `server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators)` method. These commands are separated from the ones added above since they are standard and defined at SDK level. They should be shared by all SDK-based applications. They include the most important command: the [`start` command](#start-command).
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/config.go#L13-L24
- Using [cobra](https://github.com/spf13/cobra), the root command of the full-node client is created. After that, all the custom commands of the application are added using the `AddCommand()` method of `rootCmd`.
- Add default server commands to `rootCmd` using the `server.AddCommands()` method. These commands are separated from the ones added above since they are standard and defined at SDK level. They should be shared by all SDK-based applications. They include the most important command: the [`start` command](#start-command).
- Prepare and execute the `executor`.
+++ https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/libs/cli/setup.go#L75-L78
+++ https://github.com/tendermint/tendermint/blob/v0.34.0-rc6/libs/cli/setup.go#L74-L78

See an example of `main` function from the [`gaia`](https://github.com/cosmos/gaia) application:
See an example of `main` function from the `simapp` application, the SDK's application for demo purposes:

+++ https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/cmd/gaiad/main.go
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/simapp/simd/main.go

## `start` command

The `start` command is defined in the `/server` folder of the Cosmos SDK. It is added to the root command of the full-node client in the [`main` function](#main-function) and called by the end-user to start their node:

```go
// For an example app named "app", the following command starts the full-node

```bash
# For an example app named "app", the following command starts the full-node.
appd start

# Using the SDK's own simapp, the following commands start the simapp node.
simd start
```

As a reminder, the full-node is composed of three conceptual layers: the networking layer, the consensus layer and the application layer. The first two are generally bundled together in an entity called the consensus engine (Tendermint Core by default), while the third is the state-machine defined with the help of the Cosmos SDK. Currently, the Cosmos SDK uses Tendermint as the default consensus engine, meaning the start command is implemented to boot up a Tendermint node.
As a reminder, the full-node is composed of three conceptual layers: the networking layer, the consensus layer and the application layer. The first two are generally bundled together in an entity called the consensus engine (Tendermint Core by default), while the third is the state-machine defined with the help of the Cosmos SDK. Currently, the Cosmos SDK uses Tendermint as the default consensus engine, meaning the start command is implemented to boot up a Tendermint node.

The flow of the `start` command is pretty straightforward. First, it retrieves the `config` from the `context` in order to open the `db` (a [`leveldb`](https://github.com/syndtr/goleveldb) instance by default). This `db` contains the latest known state of the application (empty if the application is started from the first time.
The flow of the `start` command is pretty straightforward. First, it retrieves the `config` from the `context` in order to open the `db` (a [`leveldb`](https://github.com/syndtr/goleveldb) instance by default). This `db` contains the latest known state of the application (empty if the application is started from the first time.

With the `db`, the `start` command creates a new instance of the application using an `appCreator` function:

+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/server/start.go#L144
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/server/start.go#L227

Note that an `appCreator` is a function that fulfills the `AppCreator` signature:
+++https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/server/types/app.go#L48-L50

Note that an `appCreator` is a function that fulfills the `AppCreator` signature. In practice, the [constructor the application](../basics/app-anatomy.md#constructor-function) is passed as the `appCreator`.
In practice, the [constructor of the application](../basics/app-anatomy.md#constructor-function) is passed as the `appCreator`.

+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/server/constructors.go#L17-L25
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/simapp/simd/cmd/root.go#L170-L215

Then, the instance of `app` is used to instanciate a new Tendermint node:

+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/server/start.go#L153-L163
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/server/start.go#L235-L244

The Tendermint node can be created with `app` because the latter satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/application.go#L11-L26) (given that `app` extends [`baseapp`](./baseapp.md)). As part of the `NewNode` method, Tendermint makes sure that the height of the application (i.e. number of blocks since genesis) is equal to the height of the Tendermint node. The difference between these two heights should always be negative or null. If it is strictly negative, `NewNode` will replay blocks until the height of the application reaches the height of the Tendermint node. Finally, if the height of the application is `0`, the Tendermint node will call [`InitChain`](./baseapp.md#initchain) on the application to initialize the state from the genesis file.
The Tendermint node can be created with `app` because the latter satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/v0.34.0/abci/types/application.go#L7-L32) (given that `app` extends [`baseapp`](./baseapp.md)). As part of the `NewNode` method, Tendermint makes sure that the height of the application (i.e. number of blocks since genesis) is equal to the height of the Tendermint node. The difference between these two heights should always be negative or null. If it is strictly negative, `NewNode` will replay blocks until the height of the application reaches the height of the Tendermint node. Finally, if the height of the application is `0`, the Tendermint node will call [`InitChain`](./baseapp.md#initchain) on the application to initialize the state from the genesis file.

Once the Tendermint node is instanciated and in sync with the application, the node can be started:

```go
if err := tmNode.Start(); err != nil {
return nil, err
}
```
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/server/start.go#L250-L252

Upon starting, the node will bootstrap its RPC and P2P server and start dialing peers. During handshake with its peers, if the node realizes they are ahead, it will query all the blocks sequentially in order to catch up. Then, it will wait for new block proposals and block signatures from validators in order to make progress.

## Other commands

Upon starting, the node will bootstrap its RPC and P2P server and start dialing peers. During handshake with its peers, if the node realizes they are ahead, it will query all the blocks sequentially in order to catch up. Then, it will wait for new block proposals and block signatures from validators in order to make progress.
To discover how to concretely run a node and interact with it, please refer to our [Running a Node](../run-node/README.md) guide.

## Next {hide}

Learn about the [store](./store.md) {hide}
Learn about the [store](./store.md) {hide}
Loading

0 comments on commit ccd0d63

Please sign in to comment.