From 03f3b96085f1502fa06baf389abd6522b7c0a6d0 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 16 Jun 2018 22:56:53 -0700 Subject: [PATCH] docs/sdk: various updates --- docs/sdk/README.md | 2 +- docs/sdk/core/accounts.md | 3 +-- docs/sdk/core/amino.md | 36 ++++++++++++++++++++++++++++++ docs/sdk/core/handlers.md | 44 ++++++++++++++++++------------------- docs/sdk/core/messages.md | 10 +++++---- docs/sdk/core/multistore.md | 23 +++++++++---------- 6 files changed, 77 insertions(+), 41 deletions(-) diff --git a/docs/sdk/README.md b/docs/sdk/README.md index d64408e6b9..b6c16bec3a 100644 --- a/docs/sdk/README.md +++ b/docs/sdk/README.md @@ -9,7 +9,7 @@ NOTE: This documentation is a work-in-progress! - [Application Architecture](overview/apps.md) - Layers in the application architecture - [Install](install.md) - Install the library and example applications - [Core](core) - - [BaseApp](core/baseapp.md) - BaseApp is the base layer of the appication + - [BaseApp](core/baseapp.md) - BaseApp is the base layer of the application - [The MultiStore](core/multistore.md) - MultiStore is a rich Merkle database - [Messages](core/messages.md) - Messages contain the content of a transaction - [Handlers](core/handlers.md) - Handlers are the workhorse of the app! diff --git a/docs/sdk/core/accounts.md b/docs/sdk/core/accounts.md index 8c61d8c4cc..194c5e4d50 100644 --- a/docs/sdk/core/accounts.md +++ b/docs/sdk/core/accounts.md @@ -1,5 +1,4 @@ - -## Accounts and x/auth +# Accounts ### auth.Account diff --git a/docs/sdk/core/amino.md b/docs/sdk/core/amino.md index e69de29bb2..f2c0aa4a6d 100644 --- a/docs/sdk/core/amino.md +++ b/docs/sdk/core/amino.md @@ -0,0 +1,36 @@ +# Amino + +The SDK is flexible about serialization - application developers can use any +serialization scheme to encode transactions and state. However, the SDK provides +a native serialization format called +[Amino](https://github.com/tendermint/go-amino). + +The goal of Amino is to improve over the latest version of Protocol Buffers, +`proto3`. To that end, Amino is compatible with the subset of `proto3` that +excludes the `oneof` keyword. + +While `oneof` provides union types, Amino aims to provide interfaces. +The main difference being that with union types, you have to know all the types +up front. But anyone can implement an interface type whenever and however +they like. + +To implement interface types, Amino allows any concrete implementation of an +interface to register a globally unique name that is carried along whenever the +type is serialized. This allows Amino to seamlessly deserialize into interface +types! + +The primary use for Amino in the SDK is for messages that implement the +`Msg` interface. By registering each message with a distinct name, they are each +given a distinct Amino prefix, allowing them to be easily distinguished in +transactions. + +Amino can also be used for persistent storage of interfaces. + +To use Amino, simply create a codec, and then register types: + +``` +cdc := wire.NewCodec() + +cdc.RegisterConcrete(MsgSend{}, "cosmos-sdk/Send", nil) +cdc.RegisterConcrete(MsgIssue{}, "cosmos-sdk/Issue", nil) +``` diff --git a/docs/sdk/core/handlers.md b/docs/sdk/core/handlers.md index e78723856f..5dbc22ef3c 100644 --- a/docs/sdk/core/handlers.md +++ b/docs/sdk/core/handlers.md @@ -1,3 +1,4 @@ +# Message Handling ## Context @@ -7,7 +8,7 @@ become ubiquitous in networking middleware and routing applications as a means to easily propogate request context through handler functions. The main information stored in the `Context` includes the application -MultiStore (see below), the last block header, and the transaction bytes. +MultiStore, the last block header, and the transaction bytes. Effectively, the context contains all data that may be necessary for processing a transaction. @@ -25,30 +26,27 @@ A handler takes a context and a message and returns a result. All information necessary for processing a message should be available in the context. -While the context holds the entire application state (all referenced from the -root MultiStore), a particular handler only needs a particular kind of access -to a particular store (or two or more). Access to stores is managed using -capabilities keys and mappers. When a handler is initialized, it is passed a -key or mapper that gives it access to the relevant stores. +While the context holds the entire application state (ie. the +MultiStore), handlers are restricted in what they can do based on the +capabilities they were given when the application was set up. + +For instance, suppose we have a `newFooHandler`: ```go -// File: cosmos-sdk/examples/basecoin/app/init_stores.go -app.BaseApp.MountStore(app.capKeyMainStore, sdk.StoreTypeIAVL) -app.accountMapper = auth.NewAccountMapper( - app.capKeyMainStore, // target store - &types.AppAccount{}, // prototype -) - -// File: cosmos-sdk/examples/basecoin/app/init_handlers.go -app.router.AddRoute("bank", bank.NewHandler(app.accountMapper)) - -// File: cosmos-sdk/x/bank/handler.go -// NOTE: Technically, NewHandler only needs a CoinMapper -func NewHandler(am sdk.AccountMapper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { - cm := CoinMapper{am} - ... - } +func newFooHandler(key sdk.StoreKey) sdk.Handler { + return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + store := ctx.KVStore(key) + // ... + } } ``` +This handler can only access one store based on whichever key its given. +So when we register the handler for the `foo` message type, we make sure +to give it the `fooKey`: + +``` +app.Router().AddRoute("foo", newFooHandler(fooKey)) +``` + +Now it can only access the `foo` store, but not the `bar` or `cat` stores! diff --git a/docs/sdk/core/messages.md b/docs/sdk/core/messages.md index 673307b5b8..15190a8867 100644 --- a/docs/sdk/core/messages.md +++ b/docs/sdk/core/messages.md @@ -1,7 +1,7 @@ +# Messages -### Messages - -Users can create messages containing arbitrary information by +Messages are the primary inputs to application state machines. +Developers can create messages containing arbitrary information by implementing the `Msg` interface: ```go @@ -31,7 +31,7 @@ correspond to the messages handler, so there can be many messages with the same type. Messages must also specify how they are to be authenticated. The `GetSigners()` -method return a list of addresses that must sign the message, while the +method return a list of SDK addresses that must sign the message, while the `GetSignBytes()` method returns the bytes that must be signed for a signature to be valid. @@ -45,11 +45,13 @@ begins. For instance, the `Basecoin` message types are defined in `x/bank/tx.go`: ```go +// Send coins from many inputs to many outputs. type MsgSend struct { Inputs []Input `json:"inputs"` Outputs []Output `json:"outputs"` } +// Issue new coins to many outputs. type MsgIssue struct { Banker sdk.Address `json:"banker"` Outputs []Output `json:"outputs"` diff --git a/docs/sdk/core/multistore.md b/docs/sdk/core/multistore.md index a96eca90fb..1ac80af8e7 100644 --- a/docs/sdk/core/multistore.md +++ b/docs/sdk/core/multistore.md @@ -1,6 +1,4 @@ -## Storage - -## MultiStore +# MultiStore The Cosmos-SDK provides a special Merkle database called a `MultiStore` to be used for all application storage. The MultiStore consists of multiple Stores that must be mounted to the @@ -34,23 +32,26 @@ barKey := sdk.NewKVStoreKey("bar") catKey := sdk.NewKVStoreKey("cat") ``` -Stores can either specify there own database, or share a primary one. -In this example, `foo` and `bar` will share a primary database, while `cat` will +Stores are mounted directly on the BaseApp. +They can either specify their own database, or share the primary one already +passed to the BaseApp. + +In this example, `foo` and `bar` will share the primary database, while `cat` will specify its own: ``` -mainDB, catDB := dbm.NewMemDB(), dbm.NewMemDB() -ms := NewCommitMultiStore(mainDB) -ms.MountStoreWithDB(fooKey, sdk.StoreTypeIAVL, nil) -ms.MountStoreWithDB(barKey, sdk.StoreTypeIAVL, nil) -ms.MountStoreWithDB(catKey, sdk.StoreTypeIAVL, catDB) +catDB := dbm.NewMemDB() +app.MountStore(fooKey, sdk.StoreTypeIAVL) +app.MountStore(barKey, sdk.StoreTypeIAVL) +app.MountStoreWithDB(catKey, sdk.StoreTypeIAVL, catDB) ``` ## Accessing Stores In the Cosmos-SDK, the only way to access a store is with a capability-key. Only modules given explicit access to the capability-key will -be able to access the corresponding store. +be able to access the corresponding store. Access to the MultiStore is mediated +through the `Context`. ## Notes