From 465197876d9dacb52782f996978192be2ead8956 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 16 Jun 2018 19:23:06 -0700 Subject: [PATCH 01/13] gut the readme --- README.md | 62 +++++++++---------------------------------------------- 1 file changed, 10 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 3af98fb4f2..247d883b07 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,15 @@ Branch | Tests | Coverage develop | [![CircleCI](https://circleci.com/gh/cosmos/cosmos-sdk/tree/develop.svg?style=shield)](https://circleci.com/gh/cosmos/cosmos-sdk/tree/develop) | [![codecov](https://codecov.io/gh/cosmos/cosmos-sdk/branch/develop/graph/badge.svg)](https://codecov.io/gh/cosmos/cosmos-sdk) master | [![CircleCI](https://circleci.com/gh/cosmos/cosmos-sdk/tree/master.svg?style=shield)](https://circleci.com/gh/cosmos/cosmos-sdk/tree/master) | [![codecov](https://codecov.io/gh/cosmos/cosmos-sdk/branch/master/graph/badge.svg)](https://codecov.io/gh/cosmos/cosmos-sdk) -**WARNING**: the libraries are still undergoing breaking changes as we get better ideas and start building out the Apps. +The Cosmos-SDK is a framework for building blockchain applications in Golang. +It is being used to build `Gaia`, the first implementation of the [Cosmos Hub](https://cosmos.network), + +**WARNING**: The SDK has mostly stabilized, but we are still making some +breaking changes. **Note**: Requires [Go 1.10+](https://golang.org/dl/) -## Testnet +## Gaia Testnet For more information on connecting to the testnet, see [cmd/gaia/testnets](/cmd/gaia/testnets) @@ -26,59 +30,13 @@ For more information on connecting to the testnet, see For the latest status of the testnet, see the [status file](/cmd/gaia/testnets/STATUS.md). +## Install -## Overview +See the [install instructions](/docs/install.md) -The Cosmos-SDK is a platform for building multi-asset Proof-of-Stake (PoS) blockchains, like the [Cosmos Hub](https://cosmos.network). It is both a library for building and securely interacting with blockchain applications. +## Quick Start -The goal of the Cosmos-SDK is to allow developers to easily create custom interoperable blockchain applications within the Cosmos Network without having to recreate common blockchain functionality, thus abstracting away the complexities of building a Tendermint ABCI application. We envision the SDK as the `npm`-like framework to build secure blockchain applications on top of Tendermint. - -In terms of its design, the SDK optimizes flexibility and security. The framework is designed around a modular execution stack which allows applications to mix and match elements as desired. In addition, all modules are sandboxed for greater application security. - -It is based on two major principles: - -- **Composability**: Anyone can create a module for the Cosmos-SDK and integrating the already-built modules is as simple as importing them into your blockchain application. - -- **Capabilities**: The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state machines. Most developers will need to access other 3rd party modules when building their own modules. Given that the Cosmos-SDK is an open framework and that we assume that some those modules may be malicious, we designed the SDK using object-capabilities (_ocaps_) based principles. In practice, this means that instead of having each module keep an access control list for other modules, each module implements `keepers` that can be passed to other modules to grant a pre-defined set of capabilities. For example, if an instance of module A's `keepers` is passed to module B, the latter will be able to call a restricted set of module A's functions. - - The capabilities of each `keeper` are defined by the module's developer, and it's their job to understand and audit the safety of foreign code from 3rd party modules based on the capabilities they are passing into each 3rd party module. For a deeper look at capabilities, you can read this [article](http://habitatchronicles.com/2017/05/what-are-capabilities/). - -_Note: For now the Cosmos-SDK only exists in [Golang](https://golang.org/), which means that developers can only develop SDK modules in Golang. In the future, we expect that the SDK will be implemented in other programming languages. Funding opportunities supported by the Tendermint team may be available eventually._ - -## Application architecture - -#### Modules - -The Cosmos-SDK has all the necessary pre-built modules to add functionality on top of a `BaseApp`, which is the template to build a blockchain dApp in Cosmos. In this context, a `module` is a fundamental unit in the Cosmos-SDK. Each module is an extension of the `BaseApp` functionalities that defines transactions, handles application state and the state transition logic. Each module also contains handlers for messages and transactions, as well as REST and CLI for secure user interactions. - -Some of the most important modules already integrated in the SDK are: - -- `Auth`: Defines a standard account structure (`BaseAccount`) and how transaction signers are authenticated. -- `Bank`: Defines how coins (i.e cryptocurrencies) are transferred. -- `Governance`: Governance related implementation including proposals and voting. -- `Staking`: Proof of Stake related implementation including bonding and delegation transactions, inflation, fees, unbonding, etc. -- `IBC`: Defines the intereoperability of blockchain zones according to the specifications of the [IBC Protocol](https://cosmos.network/whitepaper#inter-blockchain-communication-ibc). - - -#### Directories - -The key directories of the SDK are: - -- `baseapp`: Defines the template for a basic [ABCI ](https://cosmos.network/whitepaper#abci) application so that your Cosmos-SDK application can communicate with the underlying Tendermint node. -- `client`: CLI and REST server tooling. -- `server`: RPC server to communicate with the node. -- `examples`: Contains examples on how to build working standalone applications. -- `store`: Contains code for the multistore (_i.e._ state). Each module can create any number of `KVStores` (key-value stores) from the multistore. -- `types`: Common types required in any SDK-based application. -- `x`(for e**X**tensions): Folder for storing the `BaseApp` module and all the already-built modules described in the previous section. - -## Prerequisites - -- [Golang](https://golang.org/doc/install) - -## Getting Started - -See the [documentation](https://cosmos-sdk.readthedocs.io). +TODO ## Disambiguation From 5573beffa7c7974d6aad36747d6eaae5ed5d1ed9 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 16 Jun 2018 19:24:48 -0700 Subject: [PATCH 02/13] bust up guide.md into docs/sdk --- docs/sdk/accounts.md | 102 ++++++++++++++++++++++++++ docs/sdk/amino.md | 0 docs/sdk/handlers.md | 54 ++++++++++++++ docs/sdk/keepers.md | 0 docs/sdk/messages.md | 74 +++++++++++++++++++ docs/sdk/overview.md | 0 docs/sdk/store.md | 54 ++++++++++++++ docs/sdk/transactions.md | 154 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 438 insertions(+) create mode 100644 docs/sdk/accounts.md create mode 100644 docs/sdk/amino.md create mode 100644 docs/sdk/handlers.md create mode 100644 docs/sdk/keepers.md create mode 100644 docs/sdk/messages.md create mode 100644 docs/sdk/overview.md create mode 100644 docs/sdk/store.md create mode 100644 docs/sdk/transactions.md diff --git a/docs/sdk/accounts.md b/docs/sdk/accounts.md new file mode 100644 index 0000000000..8c61d8c4cc --- /dev/null +++ b/docs/sdk/accounts.md @@ -0,0 +1,102 @@ + +## Accounts and x/auth + +### auth.Account + +```go +// Account is a standard account using a sequence number for replay protection +// and a pubkey for authentication. +type Account interface { + GetAddress() sdk.Address + SetAddress(sdk.Address) error // errors if already set. + + GetPubKey() crypto.PubKey // can return nil. + SetPubKey(crypto.PubKey) error + + GetAccountNumber() int64 + SetAccountNumber(int64) error + + GetSequence() int64 + SetSequence(int64) error + + GetCoins() sdk.Coins + SetCoins(sdk.Coins) error +} +``` + +Accounts are the standard way for an application to keep track of addresses and their associated balances. + +### auth.BaseAccount + +```go +// BaseAccount - base account structure. +// Extend this by embedding this in your AppAccount. +// See the examples/basecoin/types/account.go for an example. +type BaseAccount struct { + Address sdk.Address `json:"address"` + Coins sdk.Coins `json:"coins"` + PubKey crypto.PubKey `json:"public_key"` + AccountNumber int64 `json:"account_number"` + Sequence int64 `json:"sequence"` +} +``` + +The `auth.BaseAccount` struct provides a standard implementation of the Account interface with replay protection. +BaseAccount can be extended by embedding it in your own Account struct. + +### auth.AccountMapper + +```go +// This AccountMapper encodes/decodes accounts using the +// go-amino (binary) encoding/decoding library. +type AccountMapper struct { + + // The (unexposed) key used to access the store from the Context. + key sdk.StoreKey + + // The prototypical Account concrete type. + proto Account + + // The wire codec for binary encoding/decoding of accounts. + cdc *wire.Codec +} +``` + +The AccountMapper is responsible for managing and storing the state of all accounts in the application. + +Example Initialization: + +```go +// File: examples/basecoin/app/app.go +// Define the accountMapper. +app.accountMapper = auth.NewAccountMapper( + cdc, + app.keyAccount, // target store + &types.AppAccount{}, // prototype +) +``` + +The accountMapper allows you to retrieve the current account state by `GetAccount(ctx Context, addr auth.Address)` and change the state by +`SetAccount(ctx Context, acc Account)`. + +Note: To update an account you will first have to get the account, update the appropriate fields with its associated setter method, and then call +`SetAccount(ctx Context, acc updatedAccount)`. + +Updating accounts is made easier by using the `Keeper` struct in the `x/bank` module. + +Example Initialization: + +```go +// File: examples/basecoin/app/app.go +app.coinKeeper = bank.NewKeeper(app.accountMapper) +``` + +Example Usage: + +```go +// Finds account with addr in accountmapper +// Adds coins to account's coin array +// Sets updated account in accountmapper +app.coinKeeper.AddCoins(ctx, addr, coins) +``` + diff --git a/docs/sdk/amino.md b/docs/sdk/amino.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/sdk/handlers.md b/docs/sdk/handlers.md new file mode 100644 index 0000000000..e78723856f --- /dev/null +++ b/docs/sdk/handlers.md @@ -0,0 +1,54 @@ + +## Context + +The SDK uses a `Context` to propogate common information across functions. The +`Context` is modeled after the Golang `context.Context` object, which has +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. +Effectively, the context contains all data that may be necessary for processing +a transaction. + +Many methods on SDK objects receive a context as the first argument. + +## Handler + +Message processing in the SDK is defined through `Handler` functions: + +```go +type Handler func(ctx Context, msg Msg) Result +``` + +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. + +```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} + ... + } +} +``` + diff --git a/docs/sdk/keepers.md b/docs/sdk/keepers.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/sdk/messages.md b/docs/sdk/messages.md new file mode 100644 index 0000000000..673307b5b8 --- /dev/null +++ b/docs/sdk/messages.md @@ -0,0 +1,74 @@ + +### Messages + +Users can create messages containing arbitrary information by +implementing the `Msg` interface: + +```go +type Msg interface { + + // Return the message type. + // Must be alphanumeric or empty. + Type() string + + // Get the canonical byte representation of the Msg. + GetSignBytes() []byte + + // ValidateBasic does a simple validation check that + // doesn't require access to any other information. + ValidateBasic() error + + // Signers returns the addrs of signers that must sign. + // CONTRACT: All signatures must be present to be valid. + // CONTRACT: Returns addrs in some deterministic order. + GetSigners() []Address +} + +``` + +Messages must specify their type via the `Type()` method. The type should +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 +`GetSignBytes()` method returns the bytes that must be signed for a signature +to be valid. + +Addresses in the SDK are arbitrary byte arrays that are hex-encoded when +displayed as a string or rendered in JSON. + +Messages can specify basic self-consistency checks using the `ValidateBasic()` +method to enforce that message contents are well formed before any actual logic +begins. + +For instance, the `Basecoin` message types are defined in `x/bank/tx.go`: + +```go +type MsgSend struct { + Inputs []Input `json:"inputs"` + Outputs []Output `json:"outputs"` +} + +type MsgIssue struct { + Banker sdk.Address `json:"banker"` + Outputs []Output `json:"outputs"` +} +``` + +Each specifies the addresses that must sign the message: + +```go +func (msg MsgSend) GetSigners() []sdk.Address { + addrs := make([]sdk.Address, len(msg.Inputs)) + for i, in := range msg.Inputs { + addrs[i] = in.Address + } + return addrs +} + +func (msg MsgIssue) GetSigners() []sdk.Address { + return []sdk.Address{msg.Banker} +} +``` + diff --git a/docs/sdk/overview.md b/docs/sdk/overview.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/sdk/store.md b/docs/sdk/store.md new file mode 100644 index 0000000000..46616a8ebf --- /dev/null +++ b/docs/sdk/store.md @@ -0,0 +1,54 @@ + +## Storage + +### MultiStore + +MultiStore is like a root filesystem of an operating system, except +all the entries are fully Merkleized. You mount onto a MultiStore +any number of Stores. Currently only KVStores are supported, but in +the future we may support more kinds of stores, such as a HeapStore +or a NDStore for multidimensional storage. + +The MultiStore as well as all mounted stores provide caching (aka +cache-wrapping) for intermediate state (aka software transactional +memory) during the execution of transactions. In the case of the +KVStore, this also works for iterators. For example, after running +the app's AnteHandler, the MultiStore is cache-wrapped (and each +store is also cache-wrapped) so that should processing of the +transaction fail, at least the transaction fees are paid and +sequence incremented. + +The MultiStore as well as all stores support (or will support) +historical state pruning and snapshotting and various kinds of +queries with proofs. + +### KVStore + +Here we'll focus on the IAVLStore, which is a kind of KVStore. + +IAVLStore is a fast balanced dynamic Merkle store that also supports +iteration, and of course cache-wrapping, state pruning, and various +queries with proofs, such as proofs of existence, absence, range, +and so on. + +Here's how you mount them to a MultiStore. + +```go +mainDB, catDB := dbm.NewMemDB(), dbm.NewMemDB() +fooKey := sdk.NewKVStoreKey("foo") +barKey := sdk.NewKVStoreKey("bar") +catKey := sdk.NewKVStoreKey("cat") +ms := NewCommitMultiStore(mainDB) +ms.MountStoreWithDB(fooKey, sdk.StoreTypeIAVL, nil) +ms.MountStoreWithDB(barKey, sdk.StoreTypeIAVL, nil) +ms.MountStoreWithDB(catKey, sdk.StoreTypeIAVL, catDB) +``` + +In the example above, all IAVL nodes (inner and leaf) will be stored +in mainDB with the prefix of "s/k:foo/" and "s/k:bar/" respectively, +thus sharing the mainDB. All IAVL nodes (inner and leaf) for the +cat KVStore are stored separately in catDB with the prefix of +"s/\_/". The "s/k:KEY/" and "s/\_/" prefixes are there to +disambiguate store items from other items of non-storage concern. + + diff --git a/docs/sdk/transactions.md b/docs/sdk/transactions.md new file mode 100644 index 0000000000..aafcb105cb --- /dev/null +++ b/docs/sdk/transactions.md @@ -0,0 +1,154 @@ +### Transactions + +A message is a set of instructions for a state transition. + +For a message to be valid, it must be accompanied by at least one +digital signature. The signatures required are determined solely +by the contents of the message. + +A transaction is a message with additional information for authentication: + +```go +type Tx interface { + + GetMsg() Msg + +} +``` + +The standard way to create a transaction from a message is to use the `StdTx` struct defined in the `x/auth` module. + +```go +type StdTx struct { + Msg sdk.Msg `json:"msg"` + Fee StdFee `json:"fee"` + Signatures []StdSignature `json:"signatures"` +} +``` + +The `StdTx.GetSignatures()` method returns a list of signatures, which must match +the list of addresses returned by `tx.Msg.GetSigners()`. The signatures come in +a standard form: + +```go +type StdSignature struct { + crypto.PubKey // optional + crypto.Signature + AccountNumber int64 + Sequence int64 +} +``` + +It contains the signature itself, as well as the corresponding account's +sequence number. The sequence number is expected to increment every time a +message is signed by a given account. This prevents "replay attacks", where +the same message could be executed over and over again. + +The `StdSignature` can also optionally include the public key for verifying the +signature. An application can store the public key for each address it knows +about, making it optional to include the public key in the transaction. In the +case of Basecoin, the public key only needs to be included in the first +transaction send by a given account - after that, the public key is forever +stored by the application and can be left out of transactions. + +The address responsible for paying the transactions fee is the first address +returned by msg.GetSigners(). The convenience function `FeePayer(tx Tx)` is provided +to return this. + +The standard bytes for signers to sign over is provided by: + +```go +func StdSignByes(chainID string, accnums []int64, sequences []int64, fee StdFee, msg sdk.Msg) []byte +``` + +in `x/auth`. The standard way to construct fees to pay for the processing of transactions is: + +```go +// StdFee includes the amount of coins paid in fees and the maximum +// gas to be used by the transaction. The ratio yields an effective "gasprice", +// which must be above some miminum to be accepted into the mempool. +type StdFee struct { + Amount sdk.Coins `json:"amount"` + Gas int64 `json:"gas"` +} +``` + +### Encoding and Decoding Transactions + +Messages and transactions are designed to be generic enough for developers to +specify their own encoding schemes. This enables the SDK to be used as the +framwork for constructing already specified cryptocurrency state machines, for +instance Ethereum. + +When initializing an application, a developer can specify a `TxDecoder` +function which determines how an arbitrary byte array should be unmarshalled +into a `Tx`: + +```go +type TxDecoder func(txBytes []byte) (Tx, error) +``` + +The default tx decoder is the Tendermint wire format which uses the go-amino library +for encoding and decoding all message types. + +In `Basecoin`, we use the default transaction decoder. The `go-amino` library has the nice +property that it can unmarshal into interface types, but it requires the +relevant types to be registered ahead of type. Registration happens on a +`Codec` object, so as not to taint the global name space. + +For instance, in `Basecoin`, we wish to register the `MsgSend` and `MsgIssue` +types: + +```go +cdc.RegisterInterface((*sdk.Msg)(nil), nil) +cdc.RegisterConcrete(bank.MsgSend{}, "cosmos-sdk/MsgSend", nil) +cdc.RegisterConcrete(bank.MsgIssue{}, "cosmos-sdk/MsgIssue", nil) +``` + +Note how each concrete type is given a name - these name determine the type's +unique "prefix bytes" during encoding. A registered type will always use the +same prefix-bytes, regardless of what interface it is satisfying. For more +details, see the [go-amino documentation](https://github.com/tendermint/go-amino/blob/develop). + +If you wish to use a custom encoding scheme, you must define a TxDecoder function +and set it as the decoder in your extended baseapp using the `SetTxDecoder(decoder sdk.TxDecoder)`. + +Ex: + +```go +app.SetTxDecoder(CustomTxDecodeFn) +``` + + +## AnteHandler + +The AnteHandler is used to do all transaction-level processing (i.e. Fee payment, signature verification) +before passing the message to its respective handler. + +```go +type AnteHandler func(ctx Context, tx Tx) (newCtx Context, result Result, abort bool) +``` + +The antehandler takes a Context and a transaction and returns a new Context, a Result, and the abort boolean. +As with the handler, all information necessary for processing a message should be available in the +context. + +If the transaction fails, then the application should not waste time processing the message. Thus, the antehandler should +return an Error's Result method and set the abort boolean to `true` so that the application knows not to process the message in a handler. + +Most applications can use the provided antehandler implementation in `x/auth` which handles signature verification +as well as collecting fees. + +Note: Signatures must be over `auth.StdSignDoc` introduced above to use the provided antehandler. + +```go +// File: cosmos-sdk/examples/basecoin/app/app.go +app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper)) +``` + +### Handling Fee payment +### Handling Authentication + +The antehandler is responsible for handling all authentication of a transaction before passing the message onto its handler. +This generally involves signature verification. The antehandler should check that all of the addresses that are returned in +`tx.GetMsg().GetSigners()` signed the message and that they signed over `tx.GetMsg().GetSignBytes()`. From d95cb82741018c45c914f3c968a390cddfca07be Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 16 Jun 2018 20:16:04 -0700 Subject: [PATCH 03/13] reorg docs/sdk and move stuff from docs/guide/sdk --- docs/sdk/README.md | 29 ++ docs/sdk/clients/key-management.md | 7 + docs/sdk/clients/lcd-rest-api.yaml | 781 ++++++++++++++++++++++++++++ docs/sdk/{ => core}/accounts.md | 0 docs/sdk/{ => core}/amino.md | 0 docs/sdk/{ => core}/handlers.md | 0 docs/sdk/{ => core}/keepers.md | 0 docs/sdk/{ => core}/messages.md | 0 docs/sdk/{ => core}/store.md | 15 + docs/sdk/{ => core}/transactions.md | 0 docs/sdk/install.md | 59 +++ docs/sdk/overview.md | 0 docs/sdk/overview/apps.md | 70 +++ docs/sdk/overview/capabilities.md | 118 +++++ docs/sdk/overview/overview.md | 34 ++ docs/spec/README.md | 2 +- 16 files changed, 1114 insertions(+), 1 deletion(-) create mode 100644 docs/sdk/README.md create mode 100644 docs/sdk/clients/key-management.md create mode 100644 docs/sdk/clients/lcd-rest-api.yaml rename docs/sdk/{ => core}/accounts.md (100%) rename docs/sdk/{ => core}/amino.md (100%) rename docs/sdk/{ => core}/handlers.md (100%) rename docs/sdk/{ => core}/keepers.md (100%) rename docs/sdk/{ => core}/messages.md (100%) rename docs/sdk/{ => core}/store.md (81%) rename docs/sdk/{ => core}/transactions.md (100%) create mode 100644 docs/sdk/install.md delete mode 100644 docs/sdk/overview.md create mode 100644 docs/sdk/overview/apps.md create mode 100644 docs/sdk/overview/capabilities.md create mode 100644 docs/sdk/overview/overview.md diff --git a/docs/sdk/README.md b/docs/sdk/README.md new file mode 100644 index 0000000000..059970cb24 --- /dev/null +++ b/docs/sdk/README.md @@ -0,0 +1,29 @@ +# Cosmos SDK Documentation + +- [Overview](overview) + - [Overview](overview/overview.md) - An overview of the Cosmos-SDK + - [The Object-Capability Model](overview/capabilities.md) - + - [Application Architecture](overview/apps.md) - Understanding SDK + application architecture +- [Install](install.md) - Install the SDK library and example applications +- [Core](core) + - [The Store](core/store.md) - How to work with the database + - [Messages](core/messages.md) - Messages contain the content of a transaction + - [Handlers](core/handlers.md) - Handlers are the workhorse of the app! + - [Amino](core/amino.md) - Amino is the primary serialization library used in the SDK + - [Accounts](core/accounts.md) - Accounts are the prototypical object kept in the store + - [Transactions](core/transactions.md) - Transactions wrap messages and provide authentication + - [Keepers](core/keepers.md) - Keepers are the interfaces between handlers +- [Modules](modules) + - [Bank](modules/bank.md) + - [Staking](modules/staking.md) + - [Slashing](modules/slashing.md) + - [Provisions](modules/provisions.md) + - [Governance](modules/governance.md) + - [IBC](modules/ibc.md) +- [Clients](clients) + - [Running a Node](clients/node.md) + - [Key Management](clients/keys.md) - Managing user keys + - [CLI](clients/cli.md) - Queries and transactions via command line + - [Light Client Daemon](clients/lcd.md) - Queries and transactions via REST + API diff --git a/docs/sdk/clients/key-management.md b/docs/sdk/clients/key-management.md new file mode 100644 index 0000000000..1474989b93 --- /dev/null +++ b/docs/sdk/clients/key-management.md @@ -0,0 +1,7 @@ +# Key Management + +Here we cover many aspects of handling keys within the Cosmos SDK +framework. + +// TODO add relevant key discussion +(related https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/encoding.md#public-key-cryptography) diff --git a/docs/sdk/clients/lcd-rest-api.yaml b/docs/sdk/clients/lcd-rest-api.yaml new file mode 100644 index 0000000000..a39b7bf089 --- /dev/null +++ b/docs/sdk/clients/lcd-rest-api.yaml @@ -0,0 +1,781 @@ +swagger: '2.0' +info: + version: '1.1.0' + title: Light client daemon to interface with Cosmos baseserver via REST + description: Specification for the LCD provided by `gaiacli advanced rest-server` + + +securityDefinitions: + kms: + type: basic + +paths: + /version: + get: + summary: Version of the light client daemon + description: Get the version of the LCD running locally to compare against expected + responses: + 200: + description: Plaintext version i.e. "v0.5.0" + /node_version: + get: + summary: Version of the connected node + description: Get the version of the SDK running on the connected node to compare against expected + responses: + 200: + description: Plaintext version i.e. "v0.5.0" + /node_info: + get: + description: Only the node info. Block information can be queried via /block/latest + summary: The propertied of the connected node + produces: + - application/json + responses: + 200: + description: Node status + schema: + type: object + properties: + pub_key: + $ref: '#/definitions/PubKey' + moniker: + type: string + example: 159.89.198.221 + network: + type: string + example: gaia-2 + remote_addr: + type: string + listen_addr: + type: string + example: 192.168.56.1:26656 + version: + description: Tendermint version + type: string + example: 0.15.0 + other: + description: more information on versions + type: array + items: + type: string + /syncing: + get: + summary: Syncing state of node + description: Get if the node is currently syning with other nodes + responses: + 200: + description: '"true" or "false"' + + /keys: + get: + summary: List of accounts stored locally + produces: + - application/json + responses: + 200: + description: Array of accounts + schema: + type: array + items: + $ref: '#/definitions/Account' + post: + summary: Create a new account locally + consumes: + - application/json + parameters: + - in: body + name: account + description: The account to create + schema: + type: object + required: + - name + - password + - seed + properties: + name: + type: string + password: + type: string + seed: + type: string + responses: + 200: + description: Returns address of the account created + /keys/seed: + get: + summary: Create a new seed to create a new account with + produces: + - application/json + responses: + 200: + description: 16 word Seed + schema: + type: string + /keys/{name}: + parameters: + - in: path + name: name + description: Account name + required: true + type: string + get: + summary: Get a certain locally stored account + produces: + - application/json + responses: + 200: + description: Locally stored account + schema: + $ref: "#/definitions/Account" + 404: + description: Account is not available + put: + summary: Update the password for this account in the KMS + consumes: + - application/json + parameters: + - in: body + name: account + description: The new and old password + schema: + type: object + required: + - new_password + - old_password + properties: + new_password: + type: string + old_password: + type: string + responses: + 200: + description: Updated password + 401: + description: Password is wrong + 404: + description: Account is not available + delete: + summary: Remove an account + consumes: + - application/json + parameters: + - in: body + name: account + description: The password of the account to remove from the KMS + schema: + type: object + required: + - password + properties: + password: + type: string + responses: + 200: + description: Removed account + 401: + description: Password is wrong + 404: + description: Account is not available +# /accounts/send: + # post: + # summary: Send coins (build -> sign -> send) + # security: + # - sign: [] + # requestBody: + # content: + # application/json: + # schema: + # type: object + # properties: + # fees: + # $ref: "#/definitions/Coins" + # outputs: + # type: array + # items: + # type: object + # properties: + # pub_key: + # $ref: "#/definitions/PubKey" + # amount: + # type: array + # items: + # $ref: "#/definitions/Coins" + # responses: + # 202: + # description: Tx was send and will probably be added to the next block + # 400: + # description: The Tx was malformated + + /accounts/{address}: + parameters: + - in: path + name: address + description: Account address in bech32 format + required: true + type: string + get: + summary: Get the account balances + produces: + - application/json + responses: + 200: + description: Account balances + schema: + $ref: "#/definitions/Balance" + 204: + description: There is no data for the requested account. This is not a 404 as the account might exist, just does not hold data. + /accounts/{address}/send: + parameters: + - in: path + name: address + description: Account address in bech32 format + required: true + type: string + post: + summary: Send coins (build -> sign -> send) + security: + - kms: [] + consumes: + - application/json + parameters: + - in: body + name: account + description: The password of the account to remove from the KMS + schema: + type: object + properties: + name: + type: string + password: + type: string + amount: + type: array + items: + $ref: "#/definitions/Coins" + chain_id: + type: string + squence: + type: number + responses: + 202: + description: Tx was send and will probably be added to the next block + 400: + description: The Tx was malformated + /blocks/latest: + get: + summary: Get the latest block + produces: + - application/json + responses: + 200: + description: The latest block + schema: + $ref: "#/definitions/Block" + /blocks/{height}: + parameters: + - in: path + name: height + description: Block height + required: true + type: number + get: + summary: Get a block at a certain height + produces: + - application/json + responses: + 200: + description: The block at a specific height + schema: + $ref: "#/definitions/Block" + 404: + description: Block at height is not available + /validatorsets/latest: + get: + summary: Get the latest validator set + produces: + - application/json + responses: + 200: + description: The validator set at the latest block height + schema: + type: object + properties: + block_height: + type: number + validators: + type: array + items: + $ref: "#/definitions/Validator" + /validatorsets/{height}: + parameters: + - in: path + name: height + description: Block height + required: true + type: number + get: + summary: Get a validator set a certain height + produces: + - application/json + responses: + 200: + description: The validator set at a specific block height + schema: + type: object + properties: + block_height: + type: number + validators: + type: array + items: + $ref: "#/definitions/Validator" + 404: + description: Block at height not available + # /txs: + # parameters: + # - in: query + # name: tag + # schema: + # type: string + # example: "coin.sender=EE5F3404034C524501629B56E0DDC38FAD651F04" + # required: true + # - in: query + # name: page + # description: Pagination page + # schema: + # type: number + # default: 0 + # - in: query + # name: size + # description: Pagination size + # schema: + # type: number + # default: 50 + # get: + # summary: Query Tx + # responses: + # 200: + # description: All Tx matching the provided tags + # content: + # application/json: + # schema: + # type: array + # items: + # $ref: "#/definitions/Tx" + # 404: + # description: Pagination is out of bounds + # /txs/sign: + # post: + # summary: Sign a Tx + # description: Sign a Tx providing locally stored account and according password + # security: + # - sign: [] + # requestBody: + # content: + # application/json: + # schema: + # $ref: "#/definitions/TxBuild" + # responses: + # 200: + # description: The signed Tx + # content: + # application/json: + # schema: + # $ref: "#/definitions/TxSigned" + # 401: + # description: Account name and/or password where wrong + # /txs/broadcast: + # post: + # summary: Send signed Tx + # requestBody: + # content: + # application/json: + # schema: + # $ref: "#/definitions/TxSigned" + # responses: + # 202: + # description: Tx was send and will probably be added to the next block + # 400: + # description: The Tx was malformated + /txs/{hash}: + parameters: + - in: path + name: hash + description: Tx hash + required: true + type: string + get: + summary: Get a Tx by hash + produces: + - application/json + responses: + 200: + description: Tx with the provided hash + schema: + $ref: "#/definitions/Tx" + 404: + description: Tx not available for provided hash + # /delegates: + # parameters: + # - in: query + # name: delegator + # description: Query for all delegates a delegator has stake with + # schema: + # $ref: "#/definitions/Address" + # get: + # summary: Get a list of canidates/delegates/validators (optionally filtered by delegator) + # responses: + # 200: + # description: List of delegates, filtered by provided delegator address + # content: + # application/json: + # schema: + # type: array + # items: + # $ref: "#/definitions/Delegate" + # /delegates/bond: + # post: + # summary: Bond atoms (build -> sign -> send) + # security: + # - sign: [] + # requestBody: + # content: + # application/json: + # schema: + # type: array + # items: + # type: object + # properties: + # amount: + # $ref: "#/definitions/Coins" + # pub_key: + # $ref: "#/definitions/PubKey" + # responses: + # 202: + # description: Tx was send and will probably be added to the next block + # 400: + # description: The Tx was malformated + # /delegates/unbond: + # post: + # summary: Unbond atoms (build -> sign -> send) + # security: + # - sign: [] + # requestBody: + # content: + # application/json: + # schema: + # type: array + # items: + # type: object + # properties: + # amount: + # $ref: "#/definitions/Coins" + # pub_key: + # $ref: "#/definitions/PubKey" + # responses: + # 202: + # description: Tx was send and will probably be added to the next block + # 400: + # description: The Tx was malformated + # /delegates/{pubkey}: + # parameters: + # - in: path + # name: pubkey + # description: Pubkey of a delegate + # required: true + # schema: + # type: string + # example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958 + # get: + # summary: Get a certain canidate/delegate/validator + # responses: + # 200: + # description: Delegate for specified pub_key + # content: + # application/json: + # schema: + # $ref: "#/definitions/Delegate" + # 404: + # description: No delegate found for provided pub_key + # /delegates/{pubkey}/bond: + # parameters: + # - in: path + # name: pubkey + # description: Pubkey of a delegate + # required: true + # schema: + # type: string + # example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958 + # post: + # summary: Bond atoms (build -> sign -> send) + # security: + # - sign: [] + # requestBody: + # content: + # application/json: + # schema: + # type: object + # properties: + # amount: + # $ref: "#/definitions/Coins" + # responses: + # 202: + # description: Tx was send and will probably be added to the next block + # 400: + # description: The Tx was malformated + # /delegates/{pubkey}/unbond: + # parameters: + # - in: path + # name: pubkey + # description: Pubkey of a delegate + # required: true + # schema: + # type: string + # example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958 + # post: + # summary: Unbond atoms (build -> sign -> send) + # security: + # - sign: [] + # requestBody: + # content: + # application/json: + # schema: + # type: object + # properties: + # amount: + # $ref: "#/definitions/Coins" + # responses: + # 202: + # description: Tx was send and will probably be added to the next block + # 400: + # description: The Tx was malformated + +definitions: + Address: + type: string + description: bech32 encoded addres + example: cosmosaccaddr:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq + ValidatorAddress: + type: string + description: bech32 encoded addres + example: cosmosvaladdr:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq + PubKey: + type: string + description: bech32 encoded public key + example: cosmosaccpub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq + ValidatorPubKey: + type: string + description: bech32 encoded public key + example: cosmosvalpub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq + Coins: + type: object + properties: + denom: + type: string + example: steak + amount: + type: number + example: 50 + Hash: + type: string + example: EE5F3404034C524501629B56E0DDC38FAD651F04 + Tx: + type: object + properties: + type: + type: string + enum: + - stake/delegate + data: + type: object + TxChain: + type: object + properties: + type: + type: string + default: chain/tx + data: + type: object + properties: + chain_id: + type: string + example: gaia-2 + expires_at: + type: number + example: 0 + tx: + type: object + properties: + type: + type: string + default: nonce + data: + type: object + properties: + sequence: + type: number + example: 0 + signers: + type: array + items: + type: object + properties: + chain: + type: string + example: '' + app: + type: string + default: sigs + addr: + $ref: "#/definitions/Address" + tx: + $ref: "#/definitions/Tx" + TxBuild: + type: object + properties: + type: + type: string + default: sigs/one + data: + type: object + properties: + tx: + $ref: "#/definitions/Tx" + signature: + type: object + properties: + Sig: + type: string + default: '' + Pubkey: + type: string + default: '' + TxSigned: + type: object + properties: + type: + type: string + default: sigs/one + data: + type: object + properties: + tx: + $ref: "#/definitions/Tx" + signature: + type: object + properties: + Sig: + type: string + example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958 + Pubkey: + $ref: "#/definitions/PubKey" + Account: + type: object + properties: + name: + type: string + example: Main Account + address: + $ref: "#/definitions/Address" + pub_key: + $ref: "#/definitions/PubKey" + Balance: + type: object + properties: + height: + type: number + example: 123456 + coins: + type: array + items: + $ref: "#/definitions/Coins" + credit: + type: array + items: + type: object + BlockID: + type: object + properties: + hash: + $ref: "#/definitions/Hash" + parts: + type: object + properties: + total: + type: number + example: 0 + hash: + $ref: "#/definitions/Hash" + Block: + type: object + properties: + header: + type: object + properties: + chain_id: + type: string + example: gaia-2 + height: + type: number + example: 1 + time: + type: string + example: '2017-12-30T05:53:09.287+01:00' + num_txs: + type: number + example: 0 + last_block_id: + $ref: "#/definitions/BlockID" + total_txs: + type: number + example: 35 + last_commit_hash: + $ref: "#/definitions/Hash" + data_hash: + $ref: "#/definitions/Hash" + validators_hash: + $ref: "#/definitions/Hash" + consensus_hash: + $ref: "#/definitions/Hash" + app_hash: + $ref: "#/definitions/Hash" + last_results_hash: + $ref: "#/definitions/Hash" + evidence_hash: + $ref: "#/definitions/Hash" + txs: + type: array + items: + $ref: "#/definitions/Tx" + evidence: + type: array + items: + type: object + last_commit: + type: object + properties: + blockID: + $ref: "#/definitions/BlockID" + precommits: + type: array + items: + type: object + Validator: + type: object + properties: + address: + $ref: '#/definitions/ValidatorAddress' + pub_key: + $ref: "#/definitions/ValidatorPubKey" + power: + type: number + example: 1000 + accum: + type: number + example: 1000 +# Added by API Auto Mocking Plugin +host: virtserver.swaggerhub.com +basePath: /faboweb1/Cosmos-LCD-2/1.0.0 +schemes: + - https diff --git a/docs/sdk/accounts.md b/docs/sdk/core/accounts.md similarity index 100% rename from docs/sdk/accounts.md rename to docs/sdk/core/accounts.md diff --git a/docs/sdk/amino.md b/docs/sdk/core/amino.md similarity index 100% rename from docs/sdk/amino.md rename to docs/sdk/core/amino.md diff --git a/docs/sdk/handlers.md b/docs/sdk/core/handlers.md similarity index 100% rename from docs/sdk/handlers.md rename to docs/sdk/core/handlers.md diff --git a/docs/sdk/keepers.md b/docs/sdk/core/keepers.md similarity index 100% rename from docs/sdk/keepers.md rename to docs/sdk/core/keepers.md diff --git a/docs/sdk/messages.md b/docs/sdk/core/messages.md similarity index 100% rename from docs/sdk/messages.md rename to docs/sdk/core/messages.md diff --git a/docs/sdk/store.md b/docs/sdk/core/store.md similarity index 81% rename from docs/sdk/store.md rename to docs/sdk/core/store.md index 46616a8ebf..b0ebb306c7 100644 --- a/docs/sdk/store.md +++ b/docs/sdk/core/store.md @@ -52,3 +52,18 @@ cat KVStore are stored separately in catDB with the prefix of disambiguate store items from other items of non-storage concern. + +## + +Mounting an IAVLStore +TODO: + +IAVLStore: Fast balanced dynamic Merkle store. +supports iteration. +MultiStore: multiple Merkle tree backends in a single store +allows using Ethereum Patricia Trie and Tendermint IAVL in same app +Provide caching for intermediate state during execution of blocks and +transactions (including for iteration) +Historical state pruning and snapshotting. +Query proofs (existence, absence, range, etc.) on current and retained +historical state. diff --git a/docs/sdk/transactions.md b/docs/sdk/core/transactions.md similarity index 100% rename from docs/sdk/transactions.md rename to docs/sdk/core/transactions.md diff --git a/docs/sdk/install.md b/docs/sdk/install.md new file mode 100644 index 0000000000..bafdfc4bde --- /dev/null +++ b/docs/sdk/install.md @@ -0,0 +1,59 @@ +# Install + +The fastest and easiest way to install the Cosmos SDK binaries +is to run [this script](https://github.com/cosmos/cosmos-sdk/blob/develop/scripts/install_sdk_ubuntu.sh) on a fresh Ubuntu instance. Similarly, you can run [this script](https://github.com/cosmos/cosmos-sdk/blob/develop/scripts/install_sdk_bsd.sh) on a fresh FreeBSD instance. Read the scripts before running them to ensure no untrusted connection is being made, for example we're making curl requests to download golang. Also read the comments / instructions carefully (i.e., reset your terminal after running the script). + +Cosmos SDK can be installed to +`$GOPATH/src/github.com/cosmos/cosmos-sdk` like a normal Go program: + +``` +go get github.com/cosmos/cosmos-sdk +``` + +If the dependencies have been updated with breaking changes, or if +another branch is required, `dep` is used for dependency management. +Thus, assuming you've already run `go get` or otherwise cloned the repo, +the correct way to install is: + +``` +cd $GOPATH/src/github.com/cosmos/cosmos-sdk +make get_tools +make get_vendor_deps +make install +make install_examples +``` + +This will install `gaiad` and `gaiacli` and four example binaries: +`basecoind`, `basecli`, `democoind`, and `democli`. + +Verify that everything is OK by running: + +``` +gaiad version +``` + +you should see: + +``` +0.17.3-a5a78eb +``` + +then with: + +``` +gaiacli version +``` +you should see the same version (or a later one for both). + +## Update + +Get latest code (you can also `git fetch` only the version desired), +ensure the dependencies are up to date, then recompile. + +``` +cd $GOPATH/src/github.com/cosmos/cosmos-sdk +git fetch -a origin +git checkout VERSION +make get_vendor_deps +make install +``` diff --git a/docs/sdk/overview.md b/docs/sdk/overview.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/sdk/overview/apps.md b/docs/sdk/overview/apps.md new file mode 100644 index 0000000000..01210cb662 --- /dev/null +++ b/docs/sdk/overview/apps.md @@ -0,0 +1,70 @@ +# Apps in the SDK + +The SDK has multiple levels of "application": the ABCI app, the BaseApp, the BasecoinApp, and now your App. + +## ABCI App + +The basic ABCI interface allowing Tendermint to drive the applications state machine with transaction blocks. + +## BaseApp + +Implements an ABCI App using a MultiStore for persistence and a Router to handle transactions. +The goal is to provide a secure interface between the store and the extensible state machine +while defining as little about that state machine as possible (staying true to the ABCI). + +BaseApp requires stores to be mounted via capabilities keys - handlers can only access +stores they're given the key for. The BaseApp ensures all stores are properly loaded, cached, and committed. +One mounted store is considered the "main" - it holds the latest block header, from which we can find and load the +most recent state ([TODO](https://github.com/cosmos/cosmos-sdk/issues/522)). + +BaseApp distinguishes between two handler types - the `AnteHandler` and the `MsgHandler`. +The former is a global validity check (checking nonces, sigs and sufficient balances to pay fees, +e.g. things that apply to all transaction from all modules), the later is the full state transition function. +During CheckTx the state transition function is only applied to the checkTxState and should return +before any expensive state transitions are run (this is up to each developer). It also needs to return the estimated +gas cost. +During DeliverTx the state transition function is applied to the blockchain state and the transactions +need to be fully executed. + +BaseApp is responsible for managing the context passed into handlers - +it makes the block header available and provides the right stores for CheckTx and DeliverTx. + +BaseApp is completely agnostic to serialization formats. + +## Basecoin + +Basecoin is the first complete application in the stack. +Complete applications require extensions to the core modules of the SDK to actually implement handler functionality. +The native extensions of the SDK, useful for building Cosmos Zones, live under `x`. +Basecoin implements a `BaseApp` state machine using the `x/auth` and `x/bank` extensions, +which define how transaction signers are authenticated and how coins are transferred. +It should also use `x/ibc` and probably a simple staking extension. + +Basecoin and the native `x` extensions use go-amino for all serialization needs, +including for transactions and accounts. + +## Your Cosmos App + +Your Cosmos App is a fork of Basecoin - copy the `examples/basecoin` directory and modify it to your needs. +You might want to: + +- add fields to accounts +- copy and modify handlers +- add new handlers for new transaction types +- add new stores for better isolation across handlers + +The Cosmos Hub takes Basecoin and adds more stores and extensions to handle additional +transaction types and logic, like the advanced staking logic and the governance process. + +## Ethermint + +Ethermint is a new implementation of `BaseApp` that does not depend on Basecoin. +Instead of `cosmos-sdk/x/` it has its own `ethermint/x` based on `go-ethereum`. + +Ethermint uses a Patricia store for its accounts, and an IAVL store for IBC. +It has `x/ante`, which is quite similar to Basecoin's but uses RLP instead of go-amino. +Instead of `x/bank`, it has `x/eth`, which defines the single Ethereum transaction type +and all the semantics of the Ethereum state machine. + +Within `x/eth`, transactions sent to particular addresses can be handled in unique ways, +for instance to handle IBC and staking. diff --git a/docs/sdk/overview/capabilities.md b/docs/sdk/overview/capabilities.md new file mode 100644 index 0000000000..ded5928a99 --- /dev/null +++ b/docs/sdk/overview/capabilities.md @@ -0,0 +1,118 @@ +Overview +======== + +The SDK design optimizes flexibility and security. The framework is +designed around a modular execution stack which allows applications to +mix and match elements as desired. In addition, all modules are +sandboxed for greater application security. + +Framework Overview +------------------ + +### Object-Capability Model + +When thinking about security, it's good to start with a specific threat +model. Our threat model is the following: + + We assume that a thriving ecosystem of Cosmos-SDK modules that are easy to compose into a blockchain application will contain faulty or malicious modules. + +The Cosmos-SDK is designed to address this threat by being the +foundation of an object capability system. + + The structural properties of object capability systems favor + modularity in code design and ensure reliable encapsulation in + code implementation. + + These structural properties facilitate the analysis of some + security properties of an object-capability program or operating + system. Some of these — in particular, information flow properties + — can be analyzed at the level of object references and + connectivity, independent of any knowledge or analysis of the code + that determines the behavior of the objects. As a consequence, + these security properties can be established and maintained in the + presence of new objects that contain unknown and possibly + malicious code. + + These structural properties stem from the two rules governing + access to existing objects: + + 1) An object A can send a message to B only if object A holds a + reference to B. + + 2) An object A can obtain a reference to C only + if object A receives a message containing a reference to C. As a + consequence of these two rules, an object can obtain a reference + to another object only through a preexisting chain of references. + In short, "Only connectivity begets connectivity." + +See the [wikipedia +article](https://en.wikipedia.org/wiki/Object-capability_model) for more +information. + +Strictly speaking, Golang does not implement object capabilities +completely, because of several issues: + +- pervasive ability to import primitive modules (e.g. "unsafe", "os") +- pervasive ability to override module vars + +- data-race vulnerability where 2+ goroutines can create illegal + interface values + +The first is easy to catch by auditing imports and using a proper +dependency version control system like Dep. The second and third are +unfortunate but it can be audited with some cost. + +Perhaps [Go2 will implement the object capability +model](https://github.com/golang/go/issues/23157). + +#### What does it look like? + +Only reveal what is necessary to get the work done. + +For example, the following code snippet violates the object capabilities +principle: + + type AppAccount struct {...} + var account := &AppAccount{ + Address: pub.Address(), + Coins: sdk.Coins{{"ATM", 100}}, + } + var sumValue := externalModule.ComputeSumValue(account) + +The method "ComputeSumValue" implies a pure function, yet the implied +capability of accepting a pointer value is the capability to modify that +value. The preferred method signature should take a copy instead. + + var sumValue := externalModule.ComputeSumValue(*account) + +In the Cosmos SDK, you can see the application of this principle in the +basecoin examples folder. + + // File: cosmos-sdk/examples/basecoin/app/init_handlers.go + package app + + import ( + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/sketchy" + ) + + func (app *BasecoinApp) initRouterHandlers() { + + // All handlers must be added here. + // The order matters. + app.router.AddRoute("bank", bank.NewHandler(app.accountMapper)) + app.router.AddRoute("sketchy", sketchy.NewHandler()) + } + +In the Basecoin example, the sketchy handler isn't provided an account +mapper, which does provide the bank handler with the capability (in +conjunction with the context of a transaction run). + +### Capabilities systems + +TODO: + +- Need for module isolation +- Capability is implied permission +- Link to thesis + diff --git a/docs/sdk/overview/overview.md b/docs/sdk/overview/overview.md new file mode 100644 index 0000000000..9da8c233bc --- /dev/null +++ b/docs/sdk/overview/overview.md @@ -0,0 +1,34 @@ +# Overview + +The Cosmos-SDK is a framework for building Tendermint ABCI applications in +Golang. It is designed to allow developers to easily create custom interoperable +blockchain applications within the Cosmos Network. + +We envision the SDK as the `npm`-like framework to build secure blockchain applications on top of Tendermint. + +To achieve its goals of flexibility and security, the SDK makes extensive use of +the [object-capability +model](https://en.wikipedia.org/wiki/Object-capability_model) +and the [principle of least +privelege](https://en.wikipedia.org/wiki/Principle_of_least_privilege). + +For an introduction to object-capabilities, see this [article](http://habitatchronicles.com/2017/05/what-are-capabilities/). + +## Languages + +The Cosmos-SDK is currently writen in [Golang](https://golang.org/), though the +framework could be implemented similarly in other languages. +Contact us for information about funding an implementation in another language. + +## Directory Structure + +The SDK is laid out in the following directories: + +- `baseapp`: Defines the template for a basic [ABCI](https://cosmos.network/whitepaper#abci) application so that your Cosmos-SDK application can communicate with the underlying Tendermint node. +- `client`: CLI and REST server tooling for interacting with SDK application. +- `examples`: Examples of how to build working standalone applications. +- `server`: The full node server for running an SDK application on top of + Tendermint. +- `store`: The database of the SDK - a Merkle multistore supporting multiple types of underling Merkle key-value stores. +- `types`: Common types in SDK applications. +- `x`: Extensions to the core, where all messages and handlers are defined. diff --git a/docs/spec/README.md b/docs/spec/README.md index 4b58baf9e1..1b9f523859 100644 --- a/docs/spec/README.md +++ b/docs/spec/README.md @@ -6,7 +6,7 @@ the Cosmos Hub. NOTE: the specifications are not yet complete and very much a work in progress. - [Store](store) - The core Merkle store that holds the state. -- [Auth](auth) - The structure and authnentication of accounts and transactions. +- [Auth](auth) - The structure and authentication of accounts and transactions. - [Bank](bank) - Sending tokens. - [Governance](governance) - Proposals and voting. - [IBC](ibc) - Inter-Blockchain Communication (IBC) protocol. From a051091219c2dbea74d9f206c4ff7ad5ca808308 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 16 Jun 2018 17:31:26 -0700 Subject: [PATCH 04/13] docs/spec: update readme --- docs/spec/README.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/spec/README.md b/docs/spec/README.md index 1b9f523859..0b708aba26 100644 --- a/docs/spec/README.md +++ b/docs/spec/README.md @@ -1,20 +1,27 @@ # Cosmos Hub Spec -This directory contains specifications for the application level components of -the Cosmos Hub. +This directory contains specifications for the state transition machine of the +Cosmos Hub. -NOTE: the specifications are not yet complete and very much a work in progress. +The Cosmos Hub holds all of its state in a Merkle store. Updates to +the store may be made during transactions and at the beginning and end of every +block. + +While the first implementation of the Cosmos Hub is built using the Cosmos-SDK, +these specifications aim to be independent of any implementation details. That +said, they provide a detailed resource for understanding the Cosmos-SDK. - [Store](store) - The core Merkle store that holds the state. - [Auth](auth) - The structure and authentication of accounts and transactions. - [Bank](bank) - Sending tokens. - [Governance](governance) - Proposals and voting. -- [IBC](ibc) - Inter-Blockchain Communication (IBC) protocol. - [Staking](staking) - Proof-of-stake bonding, delegation, etc. - [Slashing](slashing) - Validator punishment mechanisms. - [Provisioning](provisioning) - Fee distribution, and atom provision distribution +- [IBC](ibc) - Inter-Blockchain Communication (IBC) protocol. - [Other](other) - Other components of the Cosmos Hub, including the reserve pool, All in Bits vesting, etc. -The [specification for Tendermint](https://github.com/tendermint/tendermint/tree/develop/docs/specification/new-spec), -i.e. the underlying blockchain, can be found elsewhere. +For details on the underlying blockchain and p2p protocols, see +the [Tendermint specification](https://github.com/tendermint/tendermint/tree/develop/docs/spec). + From 7f603c8d570cd11aa87bc940d282b96a65e174c2 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 16 Jun 2018 20:25:56 -0700 Subject: [PATCH 05/13] deprecate /docs/guides/sdk --- docs/guides/guide.md | 464 ------------------ docs/guides/sdk/README.md | 3 + docs/guides/sdk/apps.md | 70 +-- docs/guides/sdk/install.md | 60 +-- docs/guides/sdk/key-management.md | 8 +- docs/guides/sdk/lcd-rest-api.yaml | 782 +----------------------------- docs/guides/sdk/overview.rst | 421 +--------------- 7 files changed, 8 insertions(+), 1800 deletions(-) delete mode 100644 docs/guides/guide.md create mode 100644 docs/guides/sdk/README.md diff --git a/docs/guides/guide.md b/docs/guides/guide.md deleted file mode 100644 index 21e8b70fe1..0000000000 --- a/docs/guides/guide.md +++ /dev/null @@ -1,464 +0,0 @@ -## Introduction - -If you want to see some examples, take a look at the [examples/basecoin](/examples/basecoin) directory. - -## Design Goals - -The design of the Cosmos SDK is based on the principles of "capabilities systems". - -## Capabilities systems - -### Need for module isolation -### Capability is implied permission -### TODO Link to thesis - -## Tx & Msg - -The SDK distinguishes between transactions (Tx) and messages -(Msg). A Tx is a list of Msgs wrapped with authentication and fee data. - -### Messages - -Users can create messages containing arbitrary information by -implementing the `Msg` interface: - -```go -type Msg interface { - - // Return the message type. - // Must be alphanumeric or empty. - Type() string - - // Get the canonical byte representation of the Msg. - GetSignBytes() []byte - - // ValidateBasic does a simple validation check that - // doesn't require access to any other information. - ValidateBasic() error - - // Signers returns the addrs of signers that must sign. - // CONTRACT: All signatures must be present to be valid. - // CONTRACT: Returns addrs in some deterministic order. - GetSigners() []Address -} - -``` - -Messages must specify their type via the `Type()` method. The type should -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 -`GetSignBytes()` method returns the bytes that must be signed for a signature -to be valid. - -Addresses in the SDK are arbitrary byte arrays that are hex-encoded when -displayed as a string or rendered in JSON. - -Messages can specify basic self-consistency checks using the `ValidateBasic()` -method to enforce that message contents are well formed before any actual logic -begins. - -For instance, the `Basecoin` message types are defined in `x/bank/tx.go`: - -```go -type MsgSend struct { - Inputs []Input `json:"inputs"` - Outputs []Output `json:"outputs"` -} - -type MsgIssue struct { - Banker sdk.Address `json:"banker"` - Outputs []Output `json:"outputs"` -} -``` - -Each specifies the addresses that must sign the message: - -```go -func (msg MsgSend) GetSigners() []sdk.Address { - addrs := make([]sdk.Address, len(msg.Inputs)) - for i, in := range msg.Inputs { - addrs[i] = in.Address - } - return addrs -} - -func (msg MsgIssue) GetSigners() []sdk.Address { - return []sdk.Address{msg.Banker} -} -``` - -### Transactions - -A transaction is a list of messages with additional information for authentication: - -```go -type Tx interface { - - GetMsgs() Msg -} -``` - -The standard way to create a transaction from a message is to use the `StdTx` struct defined in the `x/auth` module. - -```go -type StdTx struct { - Msg sdk.Msg `json:"msg"` - Fee StdFee `json:"fee"` - Signatures []StdSignature `json:"signatures"` -} -``` - -The `StdTx.GetSignatures()` method returns a list of signatures, which must match -the list of addresses returned by `tx.Msg.GetSigners()`. The signatures come in -a standard form: - -```go -type StdSignature struct { - crypto.PubKey // optional - crypto.Signature - AccountNumber int64 - Sequence int64 -} -``` - -It contains the signature itself, as well as the corresponding account's -sequence number. The sequence number is expected to increment every time a -message is signed by a given account. This prevents "replay attacks", where -the same message could be executed over and over again. - -The `StdSignature` can also optionally include the public key for verifying the -signature. An application can store the public key for each address it knows -about, making it optional to include the public key in the transaction. In the -case of Basecoin, the public key only needs to be included in the first -transaction send by a given account - after that, the public key is forever -stored by the application and can be left out of transactions. - -The address responsible for paying the transactions fee is the first address -returned by msg.GetSigners(). The convenience function `FeePayer(tx Tx)` is provided -to return this. - -The standard bytes for signers to sign over is provided by: - -```go -func StdSignByes(chainID string, accnums []int64, sequences []int64, fee StdFee, msg sdk.Msg) []byte -``` - -in `x/auth`. The standard way to construct fees to pay for the processing of transactions is: - -```go -// StdFee includes the amount of coins paid in fees and the maximum -// gas to be used by the transaction. The ratio yields an effective "gasprice", -// which must be above some miminum to be accepted into the mempool. -type StdFee struct { - Amount sdk.Coins `json:"amount"` - Gas int64 `json:"gas"` -} -``` - -### Encoding and Decoding Transactions - -Messages and transactions are designed to be generic enough for developers to -specify their own encoding schemes. This enables the SDK to be used as the -framwork for constructing already specified cryptocurrency state machines, for -instance Ethereum. - -When initializing an application, a developer can specify a `TxDecoder` -function which determines how an arbitrary byte array should be unmarshalled -into a `Tx`: - -```go -type TxDecoder func(txBytes []byte) (Tx, error) -``` - -The default tx decoder is the Tendermint wire format which uses the go-amino library -for encoding and decoding all message types. - -In `Basecoin`, we use the default transaction decoder. The `go-amino` library has the nice -property that it can unmarshal into interface types, but it requires the -relevant types to be registered ahead of type. Registration happens on a -`Codec` object, so as not to taint the global name space. - -For instance, in `Basecoin`, we wish to register the `MsgSend` and `MsgIssue` -types: - -```go -cdc.RegisterInterface((*sdk.Msg)(nil), nil) -cdc.RegisterConcrete(bank.MsgSend{}, "cosmos-sdk/MsgSend", nil) -cdc.RegisterConcrete(bank.MsgIssue{}, "cosmos-sdk/MsgIssue", nil) -``` - -Note how each concrete type is given a name - these name determine the type's -unique "prefix bytes" during encoding. A registered type will always use the -same prefix-bytes, regardless of what interface it is satisfying. For more -details, see the [go-amino documentation](https://github.com/tendermint/go-amino/blob/develop). - -If you wish to use a custom encoding scheme, you must define a TxDecoder function -and set it as the decoder in your extended baseapp using the `SetTxDecoder(decoder sdk.TxDecoder)`. - -Ex: - -```go -app.SetTxDecoder(CustomTxDecodeFn) -``` - -## Storage - -### MultiStore - -MultiStore is like a root filesystem of an operating system, except -all the entries are fully Merkleized. You mount onto a MultiStore -any number of Stores. Currently only KVStores are supported, but in -the future we may support more kinds of stores, such as a HeapStore -or a NDStore for multidimensional storage. - -The MultiStore as well as all mounted stores provide caching (aka -cache-wrapping) for intermediate state (aka software transactional -memory) during the execution of transactions. In the case of the -KVStore, this also works for iterators. For example, after running -the app's AnteHandler, the MultiStore is cache-wrapped (and each -store is also cache-wrapped) so that should processing of the -transaction fail, at least the transaction fees are paid and -sequence incremented. - -The MultiStore as well as all stores support (or will support) -historical state pruning and snapshotting and various kinds of -queries with proofs. - -### KVStore - -Here we'll focus on the IAVLStore, which is a kind of KVStore. - -IAVLStore is a fast balanced dynamic Merkle store that also supports -iteration, and of course cache-wrapping, state pruning, and various -queries with proofs, such as proofs of existence, absence, range, -and so on. - -Here's how you mount them to a MultiStore. - -```go -mainDB, catDB := dbm.NewMemDB(), dbm.NewMemDB() -fooKey := sdk.NewKVStoreKey("foo") -barKey := sdk.NewKVStoreKey("bar") -catKey := sdk.NewKVStoreKey("cat") -ms := NewCommitMultiStore(mainDB) -ms.MountStoreWithDB(fooKey, sdk.StoreTypeIAVL, nil) -ms.MountStoreWithDB(barKey, sdk.StoreTypeIAVL, nil) -ms.MountStoreWithDB(catKey, sdk.StoreTypeIAVL, catDB) -``` - -In the example above, all IAVL nodes (inner and leaf) will be stored -in mainDB with the prefix of "s/k:foo/" and "s/k:bar/" respectively, -thus sharing the mainDB. All IAVL nodes (inner and leaf) for the -cat KVStore are stored separately in catDB with the prefix of -"s/\_/". The "s/k:KEY/" and "s/\_/" prefixes are there to -disambiguate store items from other items of non-storage concern. - - -## Context - -The SDK uses a `Context` to propogate common information across functions. The -`Context` is modeled after the Golang `context.Context` object, which has -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. -Effectively, the context contains all data that may be necessary for processing -a transaction. - -Many methods on SDK objects receive a context as the first argument. - -## Handler - -Message processing in the SDK is defined through `Handler` functions: - -```go -type Handler func(ctx Context, msg Msg) Result -``` - -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. - -```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} - ... - } -} -``` - -## AnteHandler - -The AnteHandler is used to do all transaction-level processing (i.e. Fee payment, signature verification) -before passing the message to its respective handler. - -```go -type AnteHandler func(ctx Context, tx Tx) (newCtx Context, result Result, abort bool) -``` - -The antehandler takes a Context and a transaction and returns a new Context, a Result, and the abort boolean. -As with the handler, all information necessary for processing a message should be available in the -context. - -If the transaction fails, then the application should not waste time processing the message. Thus, the antehandler should -return an Error's Result method and set the abort boolean to `true` so that the application knows not to process the message in a handler. - -Most applications can use the provided antehandler implementation in `x/auth` which handles signature verification -as well as collecting fees. - -Note: Signatures must be over `auth.StdSignDoc` introduced above to use the provided antehandler. - -```go -// File: cosmos-sdk/examples/basecoin/app/app.go -app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper)) -``` - -### Handling Fee payment -### Handling Authentication - -The antehandler is responsible for handling all authentication of a transaction before passing the message onto its handler. -This generally involves signature verification. The antehandler should check that all of the addresses that are returned in -`tx.GetMsg().GetSigners()` signed the message and that they signed over `tx.GetMsg().GetSignBytes()`. - -## Accounts and x/auth - -### auth.Account - -```go -// Account is a standard account using a sequence number for replay protection -// and a pubkey for authentication. -type Account interface { - GetAddress() sdk.Address - SetAddress(sdk.Address) error // errors if already set. - - GetPubKey() crypto.PubKey // can return nil. - SetPubKey(crypto.PubKey) error - - GetAccountNumber() int64 - SetAccountNumber(int64) error - - GetSequence() int64 - SetSequence(int64) error - - GetCoins() sdk.Coins - SetCoins(sdk.Coins) error -} -``` - -Accounts are the standard way for an application to keep track of addresses and their associated balances. - -### auth.BaseAccount - -```go -// BaseAccount - base account structure. -// Extend this by embedding this in your AppAccount. -// See the examples/basecoin/types/account.go for an example. -type BaseAccount struct { - Address sdk.Address `json:"address"` - Coins sdk.Coins `json:"coins"` - PubKey crypto.PubKey `json:"public_key"` - AccountNumber int64 `json:"account_number"` - Sequence int64 `json:"sequence"` -} -``` - -The `auth.BaseAccount` struct provides a standard implementation of the Account interface with replay protection. -BaseAccount can be extended by embedding it in your own Account struct. - -### auth.AccountMapper - -```go -// This AccountMapper encodes/decodes accounts using the -// go-amino (binary) encoding/decoding library. -type AccountMapper struct { - - // The (unexposed) key used to access the store from the Context. - key sdk.StoreKey - - // The prototypical Account concrete type. - proto Account - - // The wire codec for binary encoding/decoding of accounts. - cdc *wire.Codec -} -``` - -The AccountMapper is responsible for managing and storing the state of all accounts in the application. - -Example Initialization: - -```go -// File: examples/basecoin/app/app.go -// Define the accountMapper. -app.accountMapper = auth.NewAccountMapper( - cdc, - app.keyAccount, // target store - &types.AppAccount{}, // prototype -) -``` - -The accountMapper allows you to retrieve the current account state by `GetAccount(ctx Context, addr auth.Address)` and change the state by -`SetAccount(ctx Context, acc Account)`. - -Note: To update an account you will first have to get the account, update the appropriate fields with its associated setter method, and then call -`SetAccount(ctx Context, acc updatedAccount)`. - -Updating accounts is made easier by using the `Keeper` struct in the `x/bank` module. - -Example Initialization: - -```go -// File: examples/basecoin/app/app.go -app.coinKeeper = bank.NewKeeper(app.accountMapper) -``` - -Example Usage: - -```go -// Finds account with addr in accountmapper -// Adds coins to account's coin array -// Sets updated account in accountmapper -app.coinKeeper.AddCoins(ctx, addr, coins) -``` - -## Wire codec - -### Why another codec? -### vs encoding/json -### vs protobuf - -## KVStore example - -## Basecoin example - -The quintessential SDK application is Basecoin - a simple -multi-asset cryptocurrency. Basecoin consists of a set of -accounts stored in a Merkle tree, where each account may have -many coins. There are two message types: MsgSend and MsgIssue. -MsgSend allows coins to be sent around, while MsgIssue allows a -set of predefined users to issue new coins. - -## Conclusion diff --git a/docs/guides/sdk/README.md b/docs/guides/sdk/README.md new file mode 100644 index 0000000000..2986bc4b9c --- /dev/null +++ b/docs/guides/sdk/README.md @@ -0,0 +1,3 @@ +DEPRECATED + +See the [docs](/docs/sdk) diff --git a/docs/guides/sdk/apps.md b/docs/guides/sdk/apps.md index 01210cb662..442c1c8899 100644 --- a/docs/guides/sdk/apps.md +++ b/docs/guides/sdk/apps.md @@ -1,70 +1,2 @@ -# Apps in the SDK +[Moved](/docs/sdk/overview/apps.md) -The SDK has multiple levels of "application": the ABCI app, the BaseApp, the BasecoinApp, and now your App. - -## ABCI App - -The basic ABCI interface allowing Tendermint to drive the applications state machine with transaction blocks. - -## BaseApp - -Implements an ABCI App using a MultiStore for persistence and a Router to handle transactions. -The goal is to provide a secure interface between the store and the extensible state machine -while defining as little about that state machine as possible (staying true to the ABCI). - -BaseApp requires stores to be mounted via capabilities keys - handlers can only access -stores they're given the key for. The BaseApp ensures all stores are properly loaded, cached, and committed. -One mounted store is considered the "main" - it holds the latest block header, from which we can find and load the -most recent state ([TODO](https://github.com/cosmos/cosmos-sdk/issues/522)). - -BaseApp distinguishes between two handler types - the `AnteHandler` and the `MsgHandler`. -The former is a global validity check (checking nonces, sigs and sufficient balances to pay fees, -e.g. things that apply to all transaction from all modules), the later is the full state transition function. -During CheckTx the state transition function is only applied to the checkTxState and should return -before any expensive state transitions are run (this is up to each developer). It also needs to return the estimated -gas cost. -During DeliverTx the state transition function is applied to the blockchain state and the transactions -need to be fully executed. - -BaseApp is responsible for managing the context passed into handlers - -it makes the block header available and provides the right stores for CheckTx and DeliverTx. - -BaseApp is completely agnostic to serialization formats. - -## Basecoin - -Basecoin is the first complete application in the stack. -Complete applications require extensions to the core modules of the SDK to actually implement handler functionality. -The native extensions of the SDK, useful for building Cosmos Zones, live under `x`. -Basecoin implements a `BaseApp` state machine using the `x/auth` and `x/bank` extensions, -which define how transaction signers are authenticated and how coins are transferred. -It should also use `x/ibc` and probably a simple staking extension. - -Basecoin and the native `x` extensions use go-amino for all serialization needs, -including for transactions and accounts. - -## Your Cosmos App - -Your Cosmos App is a fork of Basecoin - copy the `examples/basecoin` directory and modify it to your needs. -You might want to: - -- add fields to accounts -- copy and modify handlers -- add new handlers for new transaction types -- add new stores for better isolation across handlers - -The Cosmos Hub takes Basecoin and adds more stores and extensions to handle additional -transaction types and logic, like the advanced staking logic and the governance process. - -## Ethermint - -Ethermint is a new implementation of `BaseApp` that does not depend on Basecoin. -Instead of `cosmos-sdk/x/` it has its own `ethermint/x` based on `go-ethereum`. - -Ethermint uses a Patricia store for its accounts, and an IAVL store for IBC. -It has `x/ante`, which is quite similar to Basecoin's but uses RLP instead of go-amino. -Instead of `x/bank`, it has `x/eth`, which defines the single Ethereum transaction type -and all the semantics of the Ethereum state machine. - -Within `x/eth`, transactions sent to particular addresses can be handled in unique ways, -for instance to handle IBC and staking. diff --git a/docs/guides/sdk/install.md b/docs/guides/sdk/install.md index bafdfc4bde..9b72e7a96c 100644 --- a/docs/guides/sdk/install.md +++ b/docs/guides/sdk/install.md @@ -1,59 +1 @@ -# Install - -The fastest and easiest way to install the Cosmos SDK binaries -is to run [this script](https://github.com/cosmos/cosmos-sdk/blob/develop/scripts/install_sdk_ubuntu.sh) on a fresh Ubuntu instance. Similarly, you can run [this script](https://github.com/cosmos/cosmos-sdk/blob/develop/scripts/install_sdk_bsd.sh) on a fresh FreeBSD instance. Read the scripts before running them to ensure no untrusted connection is being made, for example we're making curl requests to download golang. Also read the comments / instructions carefully (i.e., reset your terminal after running the script). - -Cosmos SDK can be installed to -`$GOPATH/src/github.com/cosmos/cosmos-sdk` like a normal Go program: - -``` -go get github.com/cosmos/cosmos-sdk -``` - -If the dependencies have been updated with breaking changes, or if -another branch is required, `dep` is used for dependency management. -Thus, assuming you've already run `go get` or otherwise cloned the repo, -the correct way to install is: - -``` -cd $GOPATH/src/github.com/cosmos/cosmos-sdk -make get_tools -make get_vendor_deps -make install -make install_examples -``` - -This will install `gaiad` and `gaiacli` and four example binaries: -`basecoind`, `basecli`, `democoind`, and `democli`. - -Verify that everything is OK by running: - -``` -gaiad version -``` - -you should see: - -``` -0.17.3-a5a78eb -``` - -then with: - -``` -gaiacli version -``` -you should see the same version (or a later one for both). - -## Update - -Get latest code (you can also `git fetch` only the version desired), -ensure the dependencies are up to date, then recompile. - -``` -cd $GOPATH/src/github.com/cosmos/cosmos-sdk -git fetch -a origin -git checkout VERSION -make get_vendor_deps -make install -``` +[Moved](/docs/sdk/install.md) diff --git a/docs/guides/sdk/key-management.md b/docs/guides/sdk/key-management.md index 1474989b93..3620760f78 100644 --- a/docs/guides/sdk/key-management.md +++ b/docs/guides/sdk/key-management.md @@ -1,7 +1 @@ -# Key Management - -Here we cover many aspects of handling keys within the Cosmos SDK -framework. - -// TODO add relevant key discussion -(related https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/encoding.md#public-key-cryptography) +[Moved](/docs/sdk/clients/key-management.md) diff --git a/docs/guides/sdk/lcd-rest-api.yaml b/docs/guides/sdk/lcd-rest-api.yaml index a39b7bf089..5af0fa2496 100644 --- a/docs/guides/sdk/lcd-rest-api.yaml +++ b/docs/guides/sdk/lcd-rest-api.yaml @@ -1,781 +1 @@ -swagger: '2.0' -info: - version: '1.1.0' - title: Light client daemon to interface with Cosmos baseserver via REST - description: Specification for the LCD provided by `gaiacli advanced rest-server` - - -securityDefinitions: - kms: - type: basic - -paths: - /version: - get: - summary: Version of the light client daemon - description: Get the version of the LCD running locally to compare against expected - responses: - 200: - description: Plaintext version i.e. "v0.5.0" - /node_version: - get: - summary: Version of the connected node - description: Get the version of the SDK running on the connected node to compare against expected - responses: - 200: - description: Plaintext version i.e. "v0.5.0" - /node_info: - get: - description: Only the node info. Block information can be queried via /block/latest - summary: The propertied of the connected node - produces: - - application/json - responses: - 200: - description: Node status - schema: - type: object - properties: - pub_key: - $ref: '#/definitions/PubKey' - moniker: - type: string - example: 159.89.198.221 - network: - type: string - example: gaia-2 - remote_addr: - type: string - listen_addr: - type: string - example: 192.168.56.1:26656 - version: - description: Tendermint version - type: string - example: 0.15.0 - other: - description: more information on versions - type: array - items: - type: string - /syncing: - get: - summary: Syncing state of node - description: Get if the node is currently syning with other nodes - responses: - 200: - description: '"true" or "false"' - - /keys: - get: - summary: List of accounts stored locally - produces: - - application/json - responses: - 200: - description: Array of accounts - schema: - type: array - items: - $ref: '#/definitions/Account' - post: - summary: Create a new account locally - consumes: - - application/json - parameters: - - in: body - name: account - description: The account to create - schema: - type: object - required: - - name - - password - - seed - properties: - name: - type: string - password: - type: string - seed: - type: string - responses: - 200: - description: Returns address of the account created - /keys/seed: - get: - summary: Create a new seed to create a new account with - produces: - - application/json - responses: - 200: - description: 16 word Seed - schema: - type: string - /keys/{name}: - parameters: - - in: path - name: name - description: Account name - required: true - type: string - get: - summary: Get a certain locally stored account - produces: - - application/json - responses: - 200: - description: Locally stored account - schema: - $ref: "#/definitions/Account" - 404: - description: Account is not available - put: - summary: Update the password for this account in the KMS - consumes: - - application/json - parameters: - - in: body - name: account - description: The new and old password - schema: - type: object - required: - - new_password - - old_password - properties: - new_password: - type: string - old_password: - type: string - responses: - 200: - description: Updated password - 401: - description: Password is wrong - 404: - description: Account is not available - delete: - summary: Remove an account - consumes: - - application/json - parameters: - - in: body - name: account - description: The password of the account to remove from the KMS - schema: - type: object - required: - - password - properties: - password: - type: string - responses: - 200: - description: Removed account - 401: - description: Password is wrong - 404: - description: Account is not available -# /accounts/send: - # post: - # summary: Send coins (build -> sign -> send) - # security: - # - sign: [] - # requestBody: - # content: - # application/json: - # schema: - # type: object - # properties: - # fees: - # $ref: "#/definitions/Coins" - # outputs: - # type: array - # items: - # type: object - # properties: - # pub_key: - # $ref: "#/definitions/PubKey" - # amount: - # type: array - # items: - # $ref: "#/definitions/Coins" - # responses: - # 202: - # description: Tx was send and will probably be added to the next block - # 400: - # description: The Tx was malformated - - /accounts/{address}: - parameters: - - in: path - name: address - description: Account address in bech32 format - required: true - type: string - get: - summary: Get the account balances - produces: - - application/json - responses: - 200: - description: Account balances - schema: - $ref: "#/definitions/Balance" - 204: - description: There is no data for the requested account. This is not a 404 as the account might exist, just does not hold data. - /accounts/{address}/send: - parameters: - - in: path - name: address - description: Account address in bech32 format - required: true - type: string - post: - summary: Send coins (build -> sign -> send) - security: - - kms: [] - consumes: - - application/json - parameters: - - in: body - name: account - description: The password of the account to remove from the KMS - schema: - type: object - properties: - name: - type: string - password: - type: string - amount: - type: array - items: - $ref: "#/definitions/Coins" - chain_id: - type: string - squence: - type: number - responses: - 202: - description: Tx was send and will probably be added to the next block - 400: - description: The Tx was malformated - /blocks/latest: - get: - summary: Get the latest block - produces: - - application/json - responses: - 200: - description: The latest block - schema: - $ref: "#/definitions/Block" - /blocks/{height}: - parameters: - - in: path - name: height - description: Block height - required: true - type: number - get: - summary: Get a block at a certain height - produces: - - application/json - responses: - 200: - description: The block at a specific height - schema: - $ref: "#/definitions/Block" - 404: - description: Block at height is not available - /validatorsets/latest: - get: - summary: Get the latest validator set - produces: - - application/json - responses: - 200: - description: The validator set at the latest block height - schema: - type: object - properties: - block_height: - type: number - validators: - type: array - items: - $ref: "#/definitions/Validator" - /validatorsets/{height}: - parameters: - - in: path - name: height - description: Block height - required: true - type: number - get: - summary: Get a validator set a certain height - produces: - - application/json - responses: - 200: - description: The validator set at a specific block height - schema: - type: object - properties: - block_height: - type: number - validators: - type: array - items: - $ref: "#/definitions/Validator" - 404: - description: Block at height not available - # /txs: - # parameters: - # - in: query - # name: tag - # schema: - # type: string - # example: "coin.sender=EE5F3404034C524501629B56E0DDC38FAD651F04" - # required: true - # - in: query - # name: page - # description: Pagination page - # schema: - # type: number - # default: 0 - # - in: query - # name: size - # description: Pagination size - # schema: - # type: number - # default: 50 - # get: - # summary: Query Tx - # responses: - # 200: - # description: All Tx matching the provided tags - # content: - # application/json: - # schema: - # type: array - # items: - # $ref: "#/definitions/Tx" - # 404: - # description: Pagination is out of bounds - # /txs/sign: - # post: - # summary: Sign a Tx - # description: Sign a Tx providing locally stored account and according password - # security: - # - sign: [] - # requestBody: - # content: - # application/json: - # schema: - # $ref: "#/definitions/TxBuild" - # responses: - # 200: - # description: The signed Tx - # content: - # application/json: - # schema: - # $ref: "#/definitions/TxSigned" - # 401: - # description: Account name and/or password where wrong - # /txs/broadcast: - # post: - # summary: Send signed Tx - # requestBody: - # content: - # application/json: - # schema: - # $ref: "#/definitions/TxSigned" - # responses: - # 202: - # description: Tx was send and will probably be added to the next block - # 400: - # description: The Tx was malformated - /txs/{hash}: - parameters: - - in: path - name: hash - description: Tx hash - required: true - type: string - get: - summary: Get a Tx by hash - produces: - - application/json - responses: - 200: - description: Tx with the provided hash - schema: - $ref: "#/definitions/Tx" - 404: - description: Tx not available for provided hash - # /delegates: - # parameters: - # - in: query - # name: delegator - # description: Query for all delegates a delegator has stake with - # schema: - # $ref: "#/definitions/Address" - # get: - # summary: Get a list of canidates/delegates/validators (optionally filtered by delegator) - # responses: - # 200: - # description: List of delegates, filtered by provided delegator address - # content: - # application/json: - # schema: - # type: array - # items: - # $ref: "#/definitions/Delegate" - # /delegates/bond: - # post: - # summary: Bond atoms (build -> sign -> send) - # security: - # - sign: [] - # requestBody: - # content: - # application/json: - # schema: - # type: array - # items: - # type: object - # properties: - # amount: - # $ref: "#/definitions/Coins" - # pub_key: - # $ref: "#/definitions/PubKey" - # responses: - # 202: - # description: Tx was send and will probably be added to the next block - # 400: - # description: The Tx was malformated - # /delegates/unbond: - # post: - # summary: Unbond atoms (build -> sign -> send) - # security: - # - sign: [] - # requestBody: - # content: - # application/json: - # schema: - # type: array - # items: - # type: object - # properties: - # amount: - # $ref: "#/definitions/Coins" - # pub_key: - # $ref: "#/definitions/PubKey" - # responses: - # 202: - # description: Tx was send and will probably be added to the next block - # 400: - # description: The Tx was malformated - # /delegates/{pubkey}: - # parameters: - # - in: path - # name: pubkey - # description: Pubkey of a delegate - # required: true - # schema: - # type: string - # example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958 - # get: - # summary: Get a certain canidate/delegate/validator - # responses: - # 200: - # description: Delegate for specified pub_key - # content: - # application/json: - # schema: - # $ref: "#/definitions/Delegate" - # 404: - # description: No delegate found for provided pub_key - # /delegates/{pubkey}/bond: - # parameters: - # - in: path - # name: pubkey - # description: Pubkey of a delegate - # required: true - # schema: - # type: string - # example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958 - # post: - # summary: Bond atoms (build -> sign -> send) - # security: - # - sign: [] - # requestBody: - # content: - # application/json: - # schema: - # type: object - # properties: - # amount: - # $ref: "#/definitions/Coins" - # responses: - # 202: - # description: Tx was send and will probably be added to the next block - # 400: - # description: The Tx was malformated - # /delegates/{pubkey}/unbond: - # parameters: - # - in: path - # name: pubkey - # description: Pubkey of a delegate - # required: true - # schema: - # type: string - # example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958 - # post: - # summary: Unbond atoms (build -> sign -> send) - # security: - # - sign: [] - # requestBody: - # content: - # application/json: - # schema: - # type: object - # properties: - # amount: - # $ref: "#/definitions/Coins" - # responses: - # 202: - # description: Tx was send and will probably be added to the next block - # 400: - # description: The Tx was malformated - -definitions: - Address: - type: string - description: bech32 encoded addres - example: cosmosaccaddr:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq - ValidatorAddress: - type: string - description: bech32 encoded addres - example: cosmosvaladdr:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq - PubKey: - type: string - description: bech32 encoded public key - example: cosmosaccpub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq - ValidatorPubKey: - type: string - description: bech32 encoded public key - example: cosmosvalpub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq - Coins: - type: object - properties: - denom: - type: string - example: steak - amount: - type: number - example: 50 - Hash: - type: string - example: EE5F3404034C524501629B56E0DDC38FAD651F04 - Tx: - type: object - properties: - type: - type: string - enum: - - stake/delegate - data: - type: object - TxChain: - type: object - properties: - type: - type: string - default: chain/tx - data: - type: object - properties: - chain_id: - type: string - example: gaia-2 - expires_at: - type: number - example: 0 - tx: - type: object - properties: - type: - type: string - default: nonce - data: - type: object - properties: - sequence: - type: number - example: 0 - signers: - type: array - items: - type: object - properties: - chain: - type: string - example: '' - app: - type: string - default: sigs - addr: - $ref: "#/definitions/Address" - tx: - $ref: "#/definitions/Tx" - TxBuild: - type: object - properties: - type: - type: string - default: sigs/one - data: - type: object - properties: - tx: - $ref: "#/definitions/Tx" - signature: - type: object - properties: - Sig: - type: string - default: '' - Pubkey: - type: string - default: '' - TxSigned: - type: object - properties: - type: - type: string - default: sigs/one - data: - type: object - properties: - tx: - $ref: "#/definitions/Tx" - signature: - type: object - properties: - Sig: - type: string - example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958 - Pubkey: - $ref: "#/definitions/PubKey" - Account: - type: object - properties: - name: - type: string - example: Main Account - address: - $ref: "#/definitions/Address" - pub_key: - $ref: "#/definitions/PubKey" - Balance: - type: object - properties: - height: - type: number - example: 123456 - coins: - type: array - items: - $ref: "#/definitions/Coins" - credit: - type: array - items: - type: object - BlockID: - type: object - properties: - hash: - $ref: "#/definitions/Hash" - parts: - type: object - properties: - total: - type: number - example: 0 - hash: - $ref: "#/definitions/Hash" - Block: - type: object - properties: - header: - type: object - properties: - chain_id: - type: string - example: gaia-2 - height: - type: number - example: 1 - time: - type: string - example: '2017-12-30T05:53:09.287+01:00' - num_txs: - type: number - example: 0 - last_block_id: - $ref: "#/definitions/BlockID" - total_txs: - type: number - example: 35 - last_commit_hash: - $ref: "#/definitions/Hash" - data_hash: - $ref: "#/definitions/Hash" - validators_hash: - $ref: "#/definitions/Hash" - consensus_hash: - $ref: "#/definitions/Hash" - app_hash: - $ref: "#/definitions/Hash" - last_results_hash: - $ref: "#/definitions/Hash" - evidence_hash: - $ref: "#/definitions/Hash" - txs: - type: array - items: - $ref: "#/definitions/Tx" - evidence: - type: array - items: - type: object - last_commit: - type: object - properties: - blockID: - $ref: "#/definitions/BlockID" - precommits: - type: array - items: - type: object - Validator: - type: object - properties: - address: - $ref: '#/definitions/ValidatorAddress' - pub_key: - $ref: "#/definitions/ValidatorPubKey" - power: - type: number - example: 1000 - accum: - type: number - example: 1000 -# Added by API Auto Mocking Plugin -host: virtserver.swaggerhub.com -basePath: /faboweb1/Cosmos-LCD-2/1.0.0 -schemes: - - https +[Moved](/docs/sdk/clients/lcd-rest-api.yaml) diff --git a/docs/guides/sdk/overview.rst b/docs/guides/sdk/overview.rst index 0cb7e73042..c7a9adc6d5 100644 --- a/docs/guides/sdk/overview.rst +++ b/docs/guides/sdk/overview.rst @@ -1,420 +1 @@ -Overview -======== - -The SDK design optimizes flexibility and security. The -framework is designed around a modular execution stack which allows -applications to mix and match elements as desired. In addition, -all modules are sandboxed for greater application security. - -Framework Overview ------------------- - -Object-Capability Model -~~~~~~~~~~~~~~~~~~~~~~~ - -When thinking about security, it's good to start with a specific threat model. Our threat model is the following: - -:: - - We assume that a thriving ecosystem of Cosmos-SDK modules that are easy to compose into a blockchain application will contain faulty or malicious modules. - -The Cosmos-SDK is designed to address this threat by being the foundation of an object capability system. - -:: - - The structural properties of object capability systems favor - modularity in code design and ensure reliable encapsulation in - code implementation. - - These structural properties facilitate the analysis of some - security properties of an object-capability program or operating - system. Some of these — in particular, information flow properties - — can be analyzed at the level of object references and - connectivity, independent of any knowledge or analysis of the code - that determines the behavior of the objects. As a consequence, - these security properties can be established and maintained in the - presence of new objects that contain unknown and possibly - malicious code. - - These structural properties stem from the two rules governing - access to existing objects: - - 1) An object A can send a message to B only if object A holds a - reference to B. - - 2) An object A can obtain a reference to C only - if object A receives a message containing a reference to C. As a - consequence of these two rules, an object can obtain a reference - to another object only through a preexisting chain of references. - In short, "Only connectivity begets connectivity." - -See the `wikipedia article `__ for more information. - -Strictly speaking, Golang does not implement object capabilities completely, because of several issues: - -* pervasive ability to import primitive modules (e.g. "unsafe", "os") -* pervasive ability to override module vars https://github.com/golang/go/issues/23161 -* data-race vulnerability where 2+ goroutines can create illegal interface values - -The first is easy to catch by auditing imports and using a proper dependency version control system like Dep. The second and third are unfortunate but it can be audited with some cost. - -Perhaps `Go2 will implement the object capability model `__. - -What does it look like? -^^^^^^^^^^^^^^^^^^^^^^^ - -Only reveal what is necessary to get the work done. - -For example, the following code snippet violates the object capabilities principle: - -:: - - type AppAccount struct {...} - var account := &AppAccount{ - Address: pub.Address(), - Coins: sdk.Coins{{"ATM", 100}}, - } - var sumValue := externalModule.ComputeSumValue(account) - -The method "ComputeSumValue" implies a pure function, yet the implied capability of accepting a pointer value is the capability to modify that value. The preferred method signature should take a copy instead. - -:: - - var sumValue := externalModule.ComputeSumValue(*account) - -In the Cosmos SDK, you can see the application of this principle in the basecoin examples folder. - -:: - - // File: cosmos-sdk/examples/basecoin/app/init_handlers.go - package app - - import ( - "github.com/cosmos/cosmos-sdk/x/bank" - "github.com/cosmos/cosmos-sdk/x/sketchy" - ) - - func (app *BasecoinApp) initRouterHandlers() { - - // All handlers must be added here. - // The order matters. - app.router.AddRoute("bank", bank.NewHandler(app.accountMapper)) - app.router.AddRoute("sketchy", sketchy.NewHandler()) - } - -In the Basecoin example, the sketchy handler isn't provided an account mapper, which does provide the bank handler with the capability (in conjunction with the context of a transaction run). - -Security Overview ------------------ - -For examples, see the `examples `__ directory. - -Design Goals -~~~~~~~~~~~~ - -The design of the Cosmos SDK is based on the principles of "capabilities systems". - -Capabilities systems -~~~~~~~~~~~~~~~~~~~~ - -TODO: - -* Need for module isolation -* Capability is implied permission -* Link to thesis - -Tx & Msg -~~~~~~~~ - -The SDK distinguishes between transactions (Tx) and messages -(Msg). A Tx is a Msg wrapped with authentication and fee data. - -Messages -^^^^^^^^ - -Users can create messages containing arbitrary information by -implementing the ``Msg`` interface: - -:: - - type Msg interface { - - // Return the message type. - // Must be alphanumeric or empty. - Type() string - - // Get the canonical byte representation of the Msg. - GetSignBytes() []byte - - // ValidateBasic does a simple validation check that - // doesn't require access to any other information. - ValidateBasic() error - - // Signers returns the addrs of signers that must sign. - // CONTRACT: All signatures must be present to be valid. - // CONTRACT: Returns addrs in some deterministic order. - GetSigners() []Address - } - -Messages must specify their type via the ``Type()`` method. The type should -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 -``GetSignBytes()`` method returns the bytes that must be signed for a signature -to be valid. - -Addresses in the SDK are arbitrary byte arrays that are hex-encoded when -displayed as a string or rendered in JSON. - -Messages can specify basic self-consistency checks using the ``ValidateBasic()`` -method to enforce that message contents are well formed before any actual logic -begins. - -For instance, the ``Basecoin`` message types are defined in ``x/bank/tx.go``: - -:: - - type SendMsg struct { - Inputs []Input `json:"inputs"` - Outputs []Output `json:"outputs"` - } - - type IssueMsg struct { - Banker sdk.Address `json:"banker"` - Outputs []Output `json:"outputs"` - } - -Each specifies the addresses that must sign the message: - -:: - - func (msg SendMsg) GetSigners() []sdk.Address { - addrs := make([]sdk.Address, len(msg.Inputs)) - for i, in := range msg.Inputs { - addrs[i] = in.Address - } - return addrs - } - - func (msg IssueMsg) GetSigners() []sdk.Address { - return []sdk.Address{msg.Banker} - } - -Transactions -^^^^^^^^^^^^ - -A transaction is a message with additional information for authentication: - -:: - - type Tx interface { - - GetMsg() Msg - - // Signatures returns the signature of signers who signed the Msg. - // CONTRACT: Length returned is same as length of - // pubkeys returned from MsgKeySigners, and the order - // matches. - // CONTRACT: If the signature is missing (ie the Msg is - // invalid), then the corresponding signature is - // .Empty(). - GetSignatures() []StdSignature - } - -The ``tx.GetSignatures()`` method returns a list of signatures, which must match -the list of addresses returned by ``tx.Msg.GetSigners()``. The signatures come in -a standard form: - -:: - - type StdSignature struct { - crypto.PubKey // optional - crypto.Signature - AccountNumber int64 - Sequence int64 - } - -It contains the signature itself, as well as the corresponding account's account and -sequence numbers. The sequence number is expected to increment every time a -message is signed by a given account. The account number stays the same and is assigned -when the account is first generated. These prevent "replay attacks", where -the same message could be executed over and over again. - -The ``StdSignature`` can also optionally include the public key for verifying the -signature. An application can store the public key for each address it knows -about, making it optional to include the public key in the transaction. In the -case of Basecoin, the public key only needs to be included in the first -transaction send by a given account - after that, the public key is forever -stored by the application and can be left out of transactions. - -The standard way to create a transaction from a message is to use the ``StdTx``: - -:: - - type StdTx struct { - Msg - Signatures []StdSignature - } - -Encoding and Decoding Transactions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Messages and transactions are designed to be generic enough for developers to -specify their own encoding schemes. This enables the SDK to be used as the -framwork for constructing already specified cryptocurrency state machines, for -instance Ethereum. - -When initializing an application, a developer must specify a ``TxDecoder`` -function which determines how an arbitrary byte array should be unmarshalled -into a ``Tx``: - -:: - - type TxDecoder func(txBytes []byte) (Tx, error) - -In ``Basecoin``, we use the Tendermint wire format and the ``go-amino`` library for -encoding and decoding all message types. The ``go-amino`` library has the nice -property that it can unmarshal into interface types, but it requires the -relevant types to be registered ahead of type. Registration happens on a -``Codec`` object, so as not to taint the global name space. - -For instance, in ``Basecoin``, we wish to register the ``SendMsg`` and ``IssueMsg`` -types: - -:: - - cdc.RegisterInterface((*sdk.Msg)(nil), nil) - cdc.RegisterConcrete(bank.SendMsg{}, "cosmos-sdk/SendMsg", nil) - cdc.RegisterConcrete(bank.IssueMsg{}, "cosmos-sdk/IssueMsg", nil) - -Note how each concrete type is given a name - these name determine the type's -unique "prefix bytes" during encoding. A registered type will always use the -same prefix-bytes, regardless of what interface it is satisfying. For more -details, see the `go-amino documentation `__. - - -MultiStore -~~~~~~~~~~ - -MultiStore is like a filesystem -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Mounting an IAVLStore -^^^^^^^^^^^^^^^^^^^^^ - -TODO: - -* IAVLStore: Fast balanced dynamic Merkle store. - - * supports iteration. - -* MultiStore: multiple Merkle tree backends in a single store - - * allows using Ethereum Patricia Trie and Tendermint IAVL in same app - -* Provide caching for intermediate state during execution of blocks and transactions (including for iteration) -* Historical state pruning and snapshotting. -* Query proofs (existence, absence, range, etc.) on current and retained historical state. - -Context -------- - -The SDK uses a ``Context`` to propogate common information across functions. The -``Context`` is modelled after the Golang ``context.Context`` object, which has -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. -Effectively, the context contains all data that may be necessary for processing -a transaction. - -Many methods on SDK objects receive a context as the first argument. - -Handler -------- - -Transaction processing in the SDK is defined through ``Handler`` functions: - -:: - - type Handler func(ctx Context, tx Tx) Result - -A handler takes a context and a transaction and returns a result. All -information necessary for processing a transaction 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. - -:: - - // 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} - ... - } - } - -AnteHandler ------------ - -Handling Fee payment -~~~~~~~~~~~~~~~~~~~~ - -Handling Authentication -~~~~~~~~~~~~~~~~~~~~~~~ - -Accounts and x/auth -------------------- - -sdk.Account -~~~~~~~~~~~ - -auth.BaseAccount -~~~~~~~~~~~~~~~~ - -auth.AccountMapper -~~~~~~~~~~~~~~~~~~ - -Wire codec ----------- - -Why another codec? -~~~~~~~~~~~~~~~~~~ - -vs encoding/json -~~~~~~~~~~~~~~~~ - -vs protobuf -~~~~~~~~~~~ - -KVStore example ---------------- - -Basecoin example ----------------- - -The quintessential SDK application is Basecoin - a simple -multi-asset cryptocurrency. Basecoin consists of a set of -accounts stored in a Merkle tree, where each account may have -many coins. There are two message types: SendMsg and IssueMsg. -SendMsg allows coins to be sent around, while IssueMsg allows a -set of predefined users to issue new coins. +[Moved](/docs/sdk) From aafd06ed9130cd0586a456477d6da5c6db673f02 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 16 Jun 2018 21:13:55 -0700 Subject: [PATCH 06/13] update store.md --- docs/sdk/core/store.md | 87 +++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 47 deletions(-) diff --git a/docs/sdk/core/store.md b/docs/sdk/core/store.md index b0ebb306c7..a96eca90fb 100644 --- a/docs/sdk/core/store.md +++ b/docs/sdk/core/store.md @@ -1,69 +1,62 @@ - ## Storage -### MultiStore +## MultiStore -MultiStore is like a root filesystem of an operating system, except -all the entries are fully Merkleized. You mount onto a MultiStore -any number of Stores. Currently only KVStores are supported, but in -the future we may support more kinds of stores, such as a HeapStore +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 +MultiStore during application setup. Stores are mounted to the MultiStore using a capabilities key, +ensuring that only parts of the program with access to the key can access the store. + +The goals of the MultiStore are as follows: + +- Enforce separation of concerns at the storage level +- Restrict access to storage using capabilities +- Support multiple Store implementations in a single MultiStore, for instance the Tendermint IAVL tree and + the Ethereum Patricia Trie +- Merkle proofs for various queries (existence, absence, range, etc.) on current and retained historical state +- Allow for iteration within Stores +- Provide caching for intermediate state during execution of blocks and transactions (including for iteration) +- Support historical state pruning and snapshotting + +Currently, all Stores in the MultiStore must satisfy the `KVStore` interface, +which defines a simple key-value store. In the future, +we may support more kinds of stores, such as a HeapStore or a NDStore for multidimensional storage. -The MultiStore as well as all mounted stores provide caching (aka -cache-wrapping) for intermediate state (aka software transactional -memory) during the execution of transactions. In the case of the -KVStore, this also works for iterators. For example, after running -the app's AnteHandler, the MultiStore is cache-wrapped (and each -store is also cache-wrapped) so that should processing of the -transaction fail, at least the transaction fees are paid and -sequence incremented. +## Mounting Stores -The MultiStore as well as all stores support (or will support) -historical state pruning and snapshotting and various kinds of -queries with proofs. +Stores are mounted during application setup. To mount some stores, first create +their capability-keys: -### KVStore - -Here we'll focus on the IAVLStore, which is a kind of KVStore. - -IAVLStore is a fast balanced dynamic Merkle store that also supports -iteration, and of course cache-wrapping, state pruning, and various -queries with proofs, such as proofs of existence, absence, range, -and so on. - -Here's how you mount them to a MultiStore. - -```go -mainDB, catDB := dbm.NewMemDB(), dbm.NewMemDB() +``` fooKey := sdk.NewKVStoreKey("foo") 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 +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) ``` +## 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. + +## Notes + In the example above, all IAVL nodes (inner and leaf) will be stored in mainDB with the prefix of "s/k:foo/" and "s/k:bar/" respectively, thus sharing the mainDB. All IAVL nodes (inner and leaf) for the cat KVStore are stored separately in catDB with the prefix of "s/\_/". The "s/k:KEY/" and "s/\_/" prefixes are there to disambiguate store items from other items of non-storage concern. - - - -## - -Mounting an IAVLStore -TODO: - -IAVLStore: Fast balanced dynamic Merkle store. -supports iteration. -MultiStore: multiple Merkle tree backends in a single store -allows using Ethereum Patricia Trie and Tendermint IAVL in same app -Provide caching for intermediate state during execution of blocks and -transactions (including for iteration) -Historical state pruning and snapshotting. -Query proofs (existence, absence, range, etc.) on current and retained -historical state. From bfe6eed02cc6c3457da6cc6892389eb071cfdaf4 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 16 Jun 2018 21:18:24 -0700 Subject: [PATCH 07/13] update readmes --- README.md | 3 ++- docs/sdk/README.md | 2 ++ examples/{examples.md => README.md} | 0 3 files changed, 4 insertions(+), 1 deletion(-) rename examples/{examples.md => README.md} (100%) diff --git a/README.md b/README.md index 247d883b07..06991580fa 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,8 @@ See the [install instructions](/docs/install.md) ## Quick Start -TODO +- [Documentation](/docs/sdk) +- [Examples](/examples) ## Disambiguation diff --git a/docs/sdk/README.md b/docs/sdk/README.md index 059970cb24..5a71378ef1 100644 --- a/docs/sdk/README.md +++ b/docs/sdk/README.md @@ -1,5 +1,7 @@ # Cosmos SDK Documentation +NOTE: This documentation is a work-in-progress! + - [Overview](overview) - [Overview](overview/overview.md) - An overview of the Cosmos-SDK - [The Object-Capability Model](overview/capabilities.md) - diff --git a/examples/examples.md b/examples/README.md similarity index 100% rename from examples/examples.md rename to examples/README.md From 671956c74c74b55d7ec83d349ed5eec25b5c0894 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 16 Jun 2018 22:14:38 -0700 Subject: [PATCH 08/13] baseapp --- docs/sdk/README.md | 11 ++++++----- docs/sdk/core/baseapp.md | 19 +++++++++++++++++++ docs/sdk/core/{store.md => multistore.md} | 0 3 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 docs/sdk/core/baseapp.md rename docs/sdk/core/{store.md => multistore.md} (100%) diff --git a/docs/sdk/README.md b/docs/sdk/README.md index 5a71378ef1..d64408e6b9 100644 --- a/docs/sdk/README.md +++ b/docs/sdk/README.md @@ -4,12 +4,13 @@ NOTE: This documentation is a work-in-progress! - [Overview](overview) - [Overview](overview/overview.md) - An overview of the Cosmos-SDK - - [The Object-Capability Model](overview/capabilities.md) - - - [Application Architecture](overview/apps.md) - Understanding SDK - application architecture -- [Install](install.md) - Install the SDK library and example applications + - [The Object-Capability Model](overview/capabilities.md) - Security by + least-privilege + - [Application Architecture](overview/apps.md) - Layers in the application architecture +- [Install](install.md) - Install the library and example applications - [Core](core) - - [The Store](core/store.md) - How to work with the database + - [BaseApp](core/baseapp.md) - BaseApp is the base layer of the appication + - [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! - [Amino](core/amino.md) - Amino is the primary serialization library used in the SDK diff --git a/docs/sdk/core/baseapp.md b/docs/sdk/core/baseapp.md new file mode 100644 index 0000000000..7029b16ea4 --- /dev/null +++ b/docs/sdk/core/baseapp.md @@ -0,0 +1,19 @@ +# BaseApp + +The BaseApp is an abstraction over the [Tendermint +ABCI](https://github.com/tendermint/abci) that +simplifies application development by handling common low-level concerns. +It serves as the mediator between the two key components of an SDK app: the store +and the message handlers. + +The BaseApp implements the +[`abci.Application`](https://godoc.org/github.com/tendermint/abci/types#Application) interface. +It uses a `MultiStore` to manage the state, a `Router` for transaction handling, and +`Set` methods to specify functions to run at the beginning and end of every +block. + +Every SDK app begins with a BaseApp: + +``` +app := baseapp.NewBaseApp(appName, cdc, logger, db), +``` diff --git a/docs/sdk/core/store.md b/docs/sdk/core/multistore.md similarity index 100% rename from docs/sdk/core/store.md rename to docs/sdk/core/multistore.md From 03f3b96085f1502fa06baf389abd6522b7c0a6d0 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 16 Jun 2018 22:56:53 -0700 Subject: [PATCH 09/13] 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 From 45692154fd5cc96eba94c8967ea09a9adea0bd6f Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 16 Jun 2018 23:01:22 -0700 Subject: [PATCH 10/13] rocket.chat -> riot.im --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 06991580fa..5b4ebfde26 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![version](https://img.shields.io/github/tag/cosmos/cosmos-sdk.svg)](https://github.com/cosmos/cosmos-sdk/releases/latest) [![API Reference](https://godoc.org/github.com/cosmos/cosmos-sdk?status.svg )](https://godoc.org/github.com/cosmos/cosmos-sdk) -[![Rocket.Chat](https://demo.rocket.chat/images/join-chat.svg)](https://cosmos.rocket.chat/) +[![riot.im](https://img.shields.io/badge/riot.im-JOIN%20CHAT-green.svg)](https://riot.im/app/#/room/#cosmos-sdk:matrix.org) [![license](https://img.shields.io/github/license/cosmos/cosmos-sdk.svg)](https://github.com/cosmos/cosmos-sdk/blob/master/LICENSE) [![LoC](https://tokei.rs/b1/github/cosmos/cosmos-sdk)](https://github.com/cosmos/cosmos-sdk) [![Go Report Card](https://goreportcard.com/badge/github.com/cosmos/cosmos-sdk)](https://goreportcard.com/report/github.com/cosmos/cosmos-sdk) From 84f0c6d609a89eb91549026fe99640e46e0135fa Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 18 Jun 2018 12:14:08 -0700 Subject: [PATCH 11/13] updates from feedback --- docs/sdk/README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/sdk/README.md b/docs/sdk/README.md index b6c16bec3a..38609c5850 100644 --- a/docs/sdk/README.md +++ b/docs/sdk/README.md @@ -9,14 +9,19 @@ 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 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! + - [BaseApp](core/baseapp.md) - BaseApp is the base layer of the application + - [The MultiStore](core/multistore.md) - MultiStore is a rich Merkle database - [Amino](core/amino.md) - Amino is the primary serialization library used in the SDK - [Accounts](core/accounts.md) - Accounts are the prototypical object kept in the store - [Transactions](core/transactions.md) - Transactions wrap messages and provide authentication - [Keepers](core/keepers.md) - Keepers are the interfaces between handlers + - [Clients](core/clients.md) - Hook up your app to standard CLI and REST + interfaces for clients to use! + - [Advanced](core/advanced.md) - Trigger logic on a timer, use custom + serialization formats, advanced Merkle proofs, and more! + - [Modules](modules) - [Bank](modules/bank.md) - [Staking](modules/staking.md) @@ -24,8 +29,9 @@ NOTE: This documentation is a work-in-progress! - [Provisions](modules/provisions.md) - [Governance](modules/governance.md) - [IBC](modules/ibc.md) + - [Clients](clients) - - [Running a Node](clients/node.md) + - [Running a Node](clients/node.md) - Run a full node! - [Key Management](clients/keys.md) - Managing user keys - [CLI](clients/cli.md) - Queries and transactions via command line - [Light Client Daemon](clients/lcd.md) - Queries and transactions via REST From f0c3f0e47a6b8a010540251bce65b4887d03756f Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 18 Jun 2018 12:31:57 -0700 Subject: [PATCH 12/13] remove old files. move rest to _attic --- docs/Makefile | 20 -- docs/conf.py | 176 ------------- docs/guides/sdk/README.md | 3 - docs/guides/sdk/apps.md | 2 - docs/guides/sdk/install.md | 1 - docs/guides/sdk/key-management.md | 1 - docs/guides/sdk/lcd-rest-api.yaml | 1 - docs/guides/sdk/overview.rst | 1 - docs/guides/staking/intro.rst | 402 ------------------------------ docs/guides/staking/overview.md | 216 ---------------- docs/guides/staking/testnet.md | 94 ------- docs/guides/staking/testnet.rst | 82 ------ docs/index.rst | 60 ----- docs/make.bat | 36 --- 14 files changed, 1095 deletions(-) delete mode 100644 docs/Makefile delete mode 100644 docs/conf.py delete mode 100644 docs/guides/sdk/README.md delete mode 100644 docs/guides/sdk/apps.md delete mode 100644 docs/guides/sdk/install.md delete mode 100644 docs/guides/sdk/key-management.md delete mode 100644 docs/guides/sdk/lcd-rest-api.yaml delete mode 100644 docs/guides/sdk/overview.rst delete mode 100644 docs/guides/staking/intro.rst delete mode 100644 docs/guides/staking/overview.md delete mode 100644 docs/guides/staking/testnet.md delete mode 100644 docs/guides/staking/testnet.rst delete mode 100644 docs/index.rst delete mode 100644 docs/make.bat diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index f4bccf3bd3..0000000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = python -msphinx -SPHINXPROJ = Cosmos-SDK -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100644 index 3f7cb19b57..0000000000 --- a/docs/conf.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Cosmos-SDK documentation build configuration file, created by -# sphinx-quickstart on Fri Sep 1 21:37:02 2017. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - -import sphinx_rtd_theme - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: - -from recommonmark.parser import CommonMarkParser - -source_parsers = { - '.md': CommonMarkParser, -} - -source_suffix = ['.rst', '.md'] -#source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'Cosmos-SDK' -copyright = u'2018, The Authors' -author = u'The Authors' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = u'' -# The full version, including alpha/beta/rc tags. -release = u'' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '_attic', 'spec'] - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'sphinx_rtd_theme' -# html_theme = 'alabaster' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -# html_theme_options = {} - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Custom sidebar templates, must be a dictionary that maps document names -# to template names. -# -# This is required for the alabaster theme -# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars -html_sidebars = { - '**': [ - 'about.html', - 'navigation.html', - 'relations.html', # needs 'show_related': True theme option to display - 'searchbox.html', - 'donate.html', - ] -} - - -# -- Options for HTMLHelp output ------------------------------------------ - -# Output file base name for HTML help builder. -htmlhelp_basename = 'Cosmos-SDKdoc' - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'Cosmos-SDK.tex', u'Cosmos-SDK Documentation', - u'The Authors', 'manual'), -] - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'cosmos-sdk', u'Cosmos-SDK Documentation', - [author], 1) -] - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'Cosmos-SDK', u'Cosmos-SDK Documentation', - author, 'Cosmos-SDK', 'One line description of project.', - 'Miscellaneous'), -] diff --git a/docs/guides/sdk/README.md b/docs/guides/sdk/README.md deleted file mode 100644 index 2986bc4b9c..0000000000 --- a/docs/guides/sdk/README.md +++ /dev/null @@ -1,3 +0,0 @@ -DEPRECATED - -See the [docs](/docs/sdk) diff --git a/docs/guides/sdk/apps.md b/docs/guides/sdk/apps.md deleted file mode 100644 index 442c1c8899..0000000000 --- a/docs/guides/sdk/apps.md +++ /dev/null @@ -1,2 +0,0 @@ -[Moved](/docs/sdk/overview/apps.md) - diff --git a/docs/guides/sdk/install.md b/docs/guides/sdk/install.md deleted file mode 100644 index 9b72e7a96c..0000000000 --- a/docs/guides/sdk/install.md +++ /dev/null @@ -1 +0,0 @@ -[Moved](/docs/sdk/install.md) diff --git a/docs/guides/sdk/key-management.md b/docs/guides/sdk/key-management.md deleted file mode 100644 index 3620760f78..0000000000 --- a/docs/guides/sdk/key-management.md +++ /dev/null @@ -1 +0,0 @@ -[Moved](/docs/sdk/clients/key-management.md) diff --git a/docs/guides/sdk/lcd-rest-api.yaml b/docs/guides/sdk/lcd-rest-api.yaml deleted file mode 100644 index 5af0fa2496..0000000000 --- a/docs/guides/sdk/lcd-rest-api.yaml +++ /dev/null @@ -1 +0,0 @@ -[Moved](/docs/sdk/clients/lcd-rest-api.yaml) diff --git a/docs/guides/sdk/overview.rst b/docs/guides/sdk/overview.rst deleted file mode 100644 index c7a9adc6d5..0000000000 --- a/docs/guides/sdk/overview.rst +++ /dev/null @@ -1 +0,0 @@ -[Moved](/docs/sdk) diff --git a/docs/guides/staking/intro.rst b/docs/guides/staking/intro.rst deleted file mode 100644 index 3ed20852b4..0000000000 --- a/docs/guides/staking/intro.rst +++ /dev/null @@ -1,402 +0,0 @@ -Using The Staking Module -======================== - -This project is a demonstration of the Cosmos Hub staking functionality; it is -designed to get validator acquianted with staking concepts and procedures. - -Potential validators will be declaring their candidacy, after which users can -delegate and, if they so wish, unbond. This can be practiced using a local or -public testnet. - -This example covers initial setup of a two-node testnet between a server in the cloud and a local machine. Begin this tutorial from a cloud machine that you've ``ssh``'d into. - -Install -------- - -The ``gaiad`` and ``gaiacli`` binaries: - -:: - - go get github.com/cosmos/cosmos-sdk - cd $GOPATH/src/github.com/cosmos/cosmos-sdk - make get_vendor_deps - make install - -Let's jump right into it. First, we initialize some default files: - -:: - - gaiad init - -which will output: - -:: - - I[03-30|11:20:13.365] Found private validator module=main path=/root/.gaiad/config/priv_validator.json - I[03-30|11:20:13.365] Found genesis file module=main path=/root/.gaiad/config/genesis.json - Secret phrase to access coins: - citizen hungry tennis noise park hire glory exercise link glow dolphin labor design grit apple abandon - -This tell us we have a ``priv_validator.json`` and ``genesis.json`` in the ``~/.gaiad/config`` directory. A ``config.toml`` was also created in the same directory. It is a good idea to get familiar with those files. Write down the seed. - -The next thing we'll need to is add the key from ``priv_validator.json`` to the ``gaiacli`` key manager. For this we need a seed and a password: - -:: - - gaiacli keys add alice --recover - -which will give you three prompts: - -:: - - Enter a passphrase for your key: - Repeat the passphrase: - Enter your recovery seed phrase: - -create a password and copy in your seed phrase. The name and address of the key will be output: - -:: - NAME: ADDRESS: PUBKEY: - alice 67997DD03D527EB439B7193F2B813B05B219CC02 1624DE6220BB89786C1D597050438C728202436552C6226AB67453CDB2A4D2703402FB52B6 - -You can see all available keys with: - -:: - - gaiacli keys list - -Setup Testnet -------------- - -Next, we start the daemon (do this in another window): - -:: - - gaiad start - -and you'll see blocks start streaming through. - -For this example, we're doing the above on a cloud machine. The next steps should be done on your local machine or another server in the cloud, which will join the running testnet then bond/unbond. - -Accounts --------- - -We have: - -- ``alice`` the initial validator (in the cloud) -- ``bob`` receives tokens from ``alice`` then declares candidacy (from local machine) -- ``charlie`` will bond and unbond to ``bob`` (from local machine) - -Remember that ``alice`` was already created. On your second machine, install the binaries and create two new keys: - -:: - - gaiacli keys add bob - gaiacli keys add charlie - -both of which will prompt you for a password. Now we need to copy the ``genesis.json`` and ``config.toml`` from the first machine (with ``alice``) to the second machine. This is a good time to look at both these files. - -The ``genesis.json`` should look something like: - -:: - - { - "app_state": { - "accounts": [ - { - "address": "1D9B2356CAADF46D3EE3488E3CCE3028B4283DEE", - "coins": [ - { - "denom": "steak", - "amount": 100000 - } - ] - } - ], - "stake": { - "pool": { - "total_supply": 0, - "bonded_shares": { - "num": 0, - "denom": 1 - }, - "unbonded_shares": { - "num": 0, - "denom": 1 - }, - "bonded_pool": 0, - "unbonded_pool": 0, - "inflation_last_time": 0, - "inflation": { - "num": 7, - "denom": 100 - } - }, - "params": { - "inflation_rate_change": { - "num": 13, - "denom": 100 - }, - "inflation_max": { - "num": 20, - "denom": 100 - }, - "inflation_min": { - "num": 7, - "denom": 100 - }, - "goal_bonded": { - "num": 67, - "denom": 100 - }, - "max_validators": 100, - "bond_denom": "steak" - } - } - }, - "validators": [ - { - "pub_key": { - "type": "AC26791624DE60", - "value": "rgpc/ctVld6RpSfwN5yxGBF17R1PwMTdhQ9gKVUZp5g=" - }, - "power": 10, - "name": "" - } - ], - "app_hash": "", - "genesis_time": "0001-01-01T00:00:00Z", - "chain_id": "test-chain-Uv1EVU" - } - - -To notice is that the ``accounts`` field has a an address and a whole bunch of "mycoin". This is ``alice``'s address (todo: dbl check). Under ``validators`` we see the ``pub_key.data`` field, which will match the same field in the ``priv_validator.json`` file. - -The ``config.toml`` is long so let's focus on one field: - -:: - - # Comma separated list of seed nodes to connect to - seeds = "" - -On the ``alice`` cloud machine, we don't need to do anything here. Instead, we need its IP address. After copying this file (and the ``genesis.json`` to your local machine, you'll want to put the IP in the ``seeds = "138.197.161.74"`` field, in this case, we have a made-up IP. For joining testnets with many nodes, you can add more comma-seperated IPs to the list. - - -Now that your files are all setup, it's time to join the network. On your local machine, run: - -:: - - gaiad start - -and your new node will connect to the running validator (``alice``). - -Sending Tokens --------------- - -We'll have ``alice`` send some ``mycoin`` to ``bob``, who has now joined the network: - -:: - - gaiacli send --amount=1000mycoin --sequence=0 --name=alice --to=5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6 --chain-id=test-chain-Uv1EVU - -where the ``--sequence`` flag is to be incremented for each transaction, the ``--name`` flag is the sender (alice), and the ``--to`` flag takes ``bob``'s address. You'll see something like: - -:: - - Please enter passphrase for alice: - { - "check_tx": { - "gas": 30 - }, - "deliver_tx": { - "tags": [ - { - "key": "height", - "value_type": 1, - "value_int": 2963 - }, - { - "key": "coin.sender", - "value_string": "5D93A6059B6592833CBC8FA3DA90EE0382198985" - }, - { - "key": "coin.receiver", - "value_string": "5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6" - } - ] - }, - "hash": "423BD7EA3C4B36AF8AFCCA381C0771F8A698BA77", - "height": 2963 - } - -TODO: check the above with current actual output. - -Check out ``bob``'s account, which should now have 1000 mycoin: - -:: - - gaiacli account 5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6 - -Adding a Second Validator -------------------------- - -**This section is wrong/needs to be updated** - -Next, let's add the second node as a validator. - -First, we need the pub_key data: - -** need to make bob a priv_Val above? - -:: - - cat $HOME/.gaia2/priv_validator.json - -the first part will look like: - -:: - - {"address":"7B78527942C831E16907F10C3263D5ED933F7E99","pub_key":{"type":"ed25519","data":"96864CE7085B2E342B0F96F2E92B54B18C6CC700186238810D5AA7DFDAFDD3B2"}, - -and you want the ``pub_key`` ``data`` that starts with ``96864CE``. - -Now ``bob`` can create a validator with that pubkey. - -:: - - gaiacli stake create-validator --amount=10mycoin --name=bob --address-validator=
--pub-key= --moniker=bobby - -with an output like: - -:: - - Please enter passphrase for bob: - { - "check_tx": { - "gas": 30 - }, - "deliver_tx": {}, - "hash": "2A2A61FFBA1D7A59138E0068C82CC830E5103799", - "height": 4075 - } - - -We should see ``bob``'s account balance decrease by 10 mycoin: - -:: - - gaiacli account 5D93A6059B6592833CBC8FA3DA90EE0382198985 - -To confirm for certain the new validator is active, ask the tendermint node: - -:: - - curl localhost:26657/validators - -If you now kill either node, blocks will stop streaming in, because -there aren't enough validators online. Turn it back on and they will -start streaming again. - -Now that ``bob`` has declared candidacy, which essentially bonded 10 mycoin and made him a validator, we're going to get ``charlie`` to delegate some coins to ``bob``. - -Delegating ----------- - -First let's have ``alice`` send some coins to ``charlie``: - -:: - - gaiacli send --amount=1000mycoin --sequence=2 --name=alice --to=48F74F48281C89E5E4BE9092F735EA519768E8EF - -Then ``charlie`` will delegate some mycoin to ``bob``: - -:: - - gaiacli stake delegate --amount=10mycoin --address-delegator= --address-validator= --name=charlie - -You'll see output like: - -:: - - Please enter passphrase for charlie: - { - "check_tx": { - "gas": 30 - }, - "deliver_tx": {}, - "hash": "C3443BA30FCCC1F6E3A3D6AAAEE885244F8554F0", - "height": 51585 - } - -And that's it. You can query ``charlie``'s account to see the decrease in mycoin. - -To get more information about the candidate, try: - -:: - - gaiacli stake validator
- -and you'll see output similar to: - -:: - - { - "height": 51899, - "data": { - "pub_key": { - "type": "ed25519", - "data": "52D6FCD8C92A97F7CCB01205ADF310A18411EA8FDCC10E65BF2FCDB05AD1689B" - }, - "owner": { - "chain": "", - "app": "sigs", - "addr": "5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6" - }, - "shares": 20, - "voting_power": 20, - "description": { - "moniker": "bobby", - "identity": "", - "website": "", - "details": "" - } - } - } - -It's also possible the query the delegator's bond like so: - -:: - - gaiacli stake delegation --address-delegator=
--address-validator=
- -with an output similar to: - -:: - - { - "height": 325782, - "data": { - "PubKey": { - "type": "ed25519", - "data": "52D6FCD8C92A97F7CCB01205ADF310A18411EA8FDCC10E65BF2FCDB05AD1689B" - }, - "Shares": 20 - } - } - - -where the ``--address-delegator`` is ``charlie``'s address and the ``--address-validator`` is ``bob``'s address. - - -Unbonding ---------- - -Finally, to relinquish your voting power, unbond some coins. You should see -your VotingPower reduce and your account balance increase. - -:: - - gaiacli stake unbond --amount=5mycoin --name=charlie --address-delegator=
--address-validator=
- gaiacli account 48F74F48281C89E5E4BE9092F735EA519768E8EF - -See the bond decrease with ``gaiacli stake delegation`` like above. diff --git a/docs/guides/staking/overview.md b/docs/guides/staking/overview.md deleted file mode 100644 index 79033fe1ea..0000000000 --- a/docs/guides/staking/overview.md +++ /dev/null @@ -1,216 +0,0 @@ -//TODO update .rst - -# Staking Module - -## Overview - -The Cosmos Hub is a Tendermint-based Delegated Proof of Stake (DPos) blockchain -system that serves as a backbone of the Cosmos ecosystem. It is operated and -secured by an open and globally decentralized set of validators. Tendermint is -a Byzantine fault-tolerant distributed protocol for consensus among distrusting -parties, in this case the group of validators which produce the blocks for the -Cosmos Hub. To avoid the nothing-at-stake problem, a validator in Tendermint -needs to lock up coins in a bond deposit. Each bond's atoms are illiquid, they -cannot be transferred - in order to become liquid, they must be unbonded, a -process which will take 3 weeks by default at Cosmos Hub launch. Tendermint -protocol messages are signed by the validator's private key and are therefor -attributable. Validators acting outside protocol specifications can be made -accountable through punishing by slashing (burning) their bonded Atoms. On the -other hand, validators are rewarded for their service of securing blockchain -network by the inflationary provisions and transactions fees. This incentivizes -correct behavior of the validators and provides the economic security of the -network. - -The native token of the Cosmos Hub is called the Atom; becoming a validator of the -Cosmos Hub requires holding Atoms. However, not all Atom holders are validators -of the Cosmos Hub. More precisely, there is a selection process that determines -the validator set as a subset of all validators (Atom holders that -want to become a validator). The other option for Atom holders is to delegate -their atoms to validators, i.e., being a delegator. A delegator is an Atom -holder that has put its Atoms at stake by delegating it to a validator. By bonding -Atoms to secure the network (and taking a risk of being slashed in case of -misbehaviour), a user is rewarded with inflationary provisions and transaction -fees proportional to the amount of its bonded Atoms. The Cosmos Hub is -designed to efficiently facilitate a small numbers of validators (hundreds), -and large numbers of delegators (tens of thousands). More precisely, it is the -role of the Staking module of the Cosmos Hub to support various staking -functionality including validator set selection, delegating, bonding and -withdrawing Atoms, and the distribution of inflationary provisions and -transaction fees. - -## Basic Terms and Definitions - -* Cosmsos Hub - a Tendermint-based Delegated Proof of Stake (DPos) - blockchain system -* Atom - native token of the Cosmsos Hub -* Atom holder - an entity that holds some amount of Atoms -* Pool - Global object within the Cosmos Hub which accounts global state - including the total amount of bonded, unbonding, and unbonded atoms -* Validator Share - Share which a validator holds to represent its portion of - bonded, unbonding or unbonded atoms in the pool -* Delegation Share - Shares which a delegation bond holds to represent its - portion of bonded, unbonding or unbonded shares in a validator -* Bond Atoms - a process of locking Atoms in a delegation share which holds them - under protocol control. -* Slash Atoms - the process of burning atoms in the pool and assoiated - validator shares of a misbehaving validator, (not behaving according to the - protocol specification). This process devalues the worth of delegation shares - of the given validator -* Unbond Shares - Process of retrieving atoms from shares. If the shares are - bonded the shares must first remain in an inbetween unbonding state for the - duration of the unbonding period -* Redelegating Shares - Process of redelegating atoms from one validator to - another. This process is instantaneous, but the redelegated atoms are - retrospecively slashable if the old validator is found to misbehave for any - blocks before the redelegation. These atoms are simultaniously slashable - for any new blocks which the new validator misbehavess -* Validator - entity with atoms which is either actively validating the Tendermint - protocol (bonded validator) or vying to validate . -* Bonded Validator - a validator whose atoms are currently bonded and liable to - be slashed. These validators are to be able to sign protocol messages for - Tendermint consensus. At Cosmos Hub genesis there is a maximum of 100 - bonded validator positions. Only Bonded Validators receive atom provisions - and fee rewards. -* Delegator - an Atom holder that has bonded Atoms to a validator -* Unbonding period - time required in the unbonding state when unbonding - shares. Time slashable to old validator after a redelegation. Time for which - validators can be slashed after an infraction. To provide the requisite - cryptoeconomic security guarantees, all of these must be equal. -* Atom provisions - The process of increasing the Atom supply. Atoms are - periodically created on the Cosmos Hub and issued to bonded Atom holders. - The goal of inflation is to incentize most of the Atoms in existence to be - bonded. Atoms are distributed unbonded and using the fee_distribution mechanism -* Transaction fees - transaction fee is a fee that is included in a Cosmsos Hub - transaction. The fees are collected by the current validator set and - distributed among validators and delegators in proportion to their bonded - Atom share -* Commission fee - a fee taken from the transaction fees by a validator for - their service - -## The pool and the share - -At the core of the Staking module is the concept of a pool which denotes a -collection of Atoms contributed by different Atom holders. There are three -pools in the Staking module: the bonded, unbonding, and unbonded pool. Bonded -Atoms are part of the global bonded pool. If a validator or delegator wants to -unbond its shares, these Shares are moved to the the unbonding pool for the -duration of the unbonding period. From here normally Atoms will be moved -directly into the delegators wallet, however under the situation thatn an -entire validator gets unbonded, the Atoms of the delegations will remain with -the validator and moved to the unbonded pool. For each pool, the total amount -of bonded, unbonding, or unbonded Atoms are tracked as well as the current -amount of issued pool-shares, the specific holdings of these shares by -validators are tracked in protocol by the validator object. - -A share is a unit of Atom distribution and the value of the share -(share-to-atom exchange rate) can change during system execution. The -share-to-atom exchange rate can be computed as: - -`share-to-atom-exchange-rate = size of the pool / ammount of issued shares` - -Then for each validator (in a per validator data structure) the protocol keeps -track of the amount of shares the validator owns in a pool. At any point in -time, the exact amount of Atoms a validator has in the pool can be computed as -the number of shares it owns multiplied with the current share-to-atom exchange -rate: - -`validator-coins = validator.Shares * share-to-atom-exchange-rate` - -The benefit of such accounting of the pool resources is the fact that a -modification to the pool from bonding/unbonding/slashing of Atoms affects only -global data (size of the pool and the number of shares) and not the related -validator data structure, i.e., the data structure of other validators do not -need to be modified. This has the advantage that modifying global data is much -cheaper computationally than modifying data of every validator. Let's explain -this further with several small examples: - -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -XXX TODO make way less verbose lets use bullet points to describe the example -XXX Also need to update to not include bonded atom provisions all atoms are -XXX redistributed with the fee pool now - -We consider initially 4 validators p1, p2, p3 and p4, and that each validator -has bonded 10 Atoms to the bonded pool. Furthermore, let's assume that we have -issued initially 40 shares (note that the initial distribution of the shares, -i.e., share-to-atom exchange rate can be set to any meaningful value), i.e., -share-to-atom-ex-rate = 1 atom per share. Then at the global pool level we -have, the size of the pool is 40 Atoms, and the amount of issued shares is -equal to 40. And for each validator we store in their corresponding data -structure that each has 10 shares of the bonded pool. Now lets assume that the -validator p4 starts process of unbonding of 5 shares. Then the total size of -the pool is decreased and now it will be 35 shares and the amount of Atoms is -35 . Note that the only change in other data structures needed is reducing the -number of shares for a validator p4 from 10 to 5. - -Let's consider now the case where a validator p1 wants to bond 15 more atoms to -the pool. Now the size of the pool is 50, and as the exchange rate hasn't -changed (1 share is still worth 1 Atom), we need to create more shares, i.e. we -now have 50 shares in the pool in total. Validators p2, p3 and p4 still have -(correspondingly) 10, 10 and 5 shares each worth of 1 atom per share, so we -don't need to modify anything in their corresponding data structures. But p1 -now has 25 shares, so we update the amount of shares owned by p1 in its -data structure. Note that apart from the size of the pool that is in Atoms, all -other data structures refer only to shares. - -Finally, let's consider what happens when new Atoms are created and added to -the pool due to inflation. Let's assume that the inflation rate is 10 percent -and that it is applied to the current state of the pool. This means that 5 -Atoms are created and added to the pool and that each validator now -proportionally increase it's Atom count. Let's analyse how this change is -reflected in the data structures. First, the size of the pool is increased and -is now 55 atoms. As a share of each validator in the pool hasn't changed, this -means that the total number of shares stay the same (50) and that the amount of -shares of each validator stays the same (correspondingly 25, 10, 10, 5). But -the exchange rate has changed and each share is now worth 55/50 Atoms per -share, so each validator has effectively increased amount of Atoms it has. So -validators now have (correspondingly) 55/2, 55/5, 55/5 and 55/10 Atoms. - -The concepts of the pool and its shares is at the core of the accounting in the -Staking module. It is used for managing the global pools (such as bonding and -unbonding pool), but also for distribution of Atoms between validator and its -delegators (we will explain this in section X). - -#### Delegator shares - -A validator is, depending on its status, contributing Atoms to either the -unbonding or unbonded pool - the validator in turn holds some amount of pool -shares. Not all of a validator's Atoms (and respective shares) are necessarily -owned by the validator, some may be owned by delegators to that validator. The -mechanism for distribution of Atoms (and shares) between a validator and its -delegators is based on a notion of delegator shares. More precisely, every -validator is issuing (local) delegator shares -(`Validator.IssuedDelegatorShares`) that represents some portion of global -shares managed by the validator (`Validator.GlobalStakeShares`). The principle -behind managing delegator shares is the same as described in [Section](#The -pool and the share). We now illustrate it with an example. - -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -XXX TODO make way less verbose lets use bullet points to describe the example -XXX Also need to update to not include bonded atom provisions all atoms are -XXX redistributed with the fee pool now - -Let's consider 4 validators p1, p2, p3 and p4, and assume that each validator -has bonded 10 Atoms to the bonded pool. Furthermore, let's assume that we have -issued initially 40 global shares, i.e., that -`share-to-atom-exchange-rate = 1 atom per share`. So we will set -`GlobalState.BondedPool = 40` and `GlobalState.BondedShares = 40` and in the -Validator data structure of each validator `Validator.GlobalStakeShares = 10`. -Furthermore, each validator issued 10 delegator shares which are initially -owned by itself, i.e., `Validator.IssuedDelegatorShares = 10`, where -`delegator-share-to-global-share-ex-rate = 1 global share per delegator share`. -Now lets assume that a delegator d1 delegates 5 atoms to a validator p1 and -consider what are the updates we need to make to the data structures. First, -`GlobalState.BondedPool = 45` and `GlobalState.BondedShares = 45`. Then, for -validator p1 we have `Validator.GlobalStakeShares = 15`, but we also need to -issue also additional delegator shares, i.e., -`Validator.IssuedDelegatorShares = 15` as the delegator d1 now owns 5 delegator -shares of validator p1, where each delegator share is worth 1 global shares, -i.e, 1 Atom. Lets see now what happens after 5 new Atoms are created due to -inflation. In that case, we only need to update `GlobalState.BondedPool` which -is now equal to 50 Atoms as created Atoms are added to the bonded pool. Note -that the amount of global and delegator shares stay the same but they are now -worth more as share-to-atom-exchange-rate is now worth 50/45 Atoms per share. -Therefore, a delegator d1 now owns: - -`delegatorCoins = 5 (delegator shares) * 1 (delegator-share-to-global-share-ex-rate) * 50/45 (share-to-atom-ex-rate) = 5.55 Atoms` - diff --git a/docs/guides/staking/testnet.md b/docs/guides/staking/testnet.md deleted file mode 100644 index b2bbd8f1a3..0000000000 --- a/docs/guides/staking/testnet.md +++ /dev/null @@ -1,94 +0,0 @@ -# Testnet Setup - -**Note:** This document is incomplete and may not be up-to-date with the -state of the code. - -See the [installation guide](../sdk/install.html) for details on -installation. - -Here is a quick example to get you off your feet: - -First, generate a couple of genesis transactions to be incorporated into -the genesis file, this will create two keys with the password -`1234567890`: - -``` -gaiad init gen-tx --name=foo --home=$HOME/.gaiad1 -gaiad init gen-tx --name=bar --home=$HOME/.gaiad2 -gaiacli keys list -``` - -**Note:** If you've already run these tests you may need to overwrite -keys using the `--owk` flag When you list the keys you should see two -addresses, we'll need these later so take note. Now let's actually -create the genesis files for both nodes: - -``` -cp -a ~/.gaiad2/config/gentx/. ~/.gaiad1/config/gentx/ -cp -a ~/.gaiad1/config/gentx/. ~/.gaiad2/config/gentx/ -gaiad init --gen-txs --home=$HOME/.gaiad1 --chain-id=test-chain -gaiad init --gen-txs --home=$HOME/.gaiad2 --chain-id=test-chain -``` - -**Note:** If you've already run these tests you may need to overwrite -genesis using the `-o` flag. What we just did is copy the genesis -transactions between each of the nodes so there is a common genesis -transaction set; then we created both genesis files independently from -each home directory. Importantly both nodes have independently created -their `genesis.json` and `config.toml` files, which should be identical -between nodes. - -Great, now that we've initialized the chains, we can start both nodes in -the background: - -``` -gaiad start --home=$HOME/.gaiad1 &> gaia1.log & -NODE1_PID=$! -gaia start --home=$HOME/.gaiad2 &> gaia2.log & -NODE2_PID=$! -``` - -Note that we save the PID so we can later kill the processes. You can -peak at your logs with `tail gaia1.log`, or follow them for a bit with -`tail -f gaia1.log`. - -Nice. We can also lookup the validator set: - -``` -gaiacli validatorset -``` - -Then, we try to transfer some `steak` to another account: - -``` -gaiacli account -gaiacli account -gaiacli send --amount=10steak --to= --name=foo --chain-id=test-chain -``` - -**Note:** We need to be careful with the `chain-id` and `sequence` - -Check the balance & sequence with: - -``` -gaiacli account -``` - -To confirm for certain the new validator is active, check tendermint: - -``` -curl localhost:46657/validators -``` - -Finally, to relinquish all your power, unbond some coins. You should see -your VotingPower reduce and your account balance increase. - -``` -gaiacli unbond --chain-id= --name=test -``` - -That's it! - -**Note:** TODO demonstrate edit-candidacy **Note:** TODO demonstrate -delegation **Note:** TODO demonstrate unbond of delegation **Note:** -TODO demonstrate unbond candidate diff --git a/docs/guides/staking/testnet.rst b/docs/guides/staking/testnet.rst deleted file mode 100644 index 0e86a952d2..0000000000 --- a/docs/guides/staking/testnet.rst +++ /dev/null @@ -1,82 +0,0 @@ -Testnet Setup -============= - -**Note:** This document is incomplete and may not be up-to-date with the state of the code. - -See the `installation guide <../sdk/install.html>`__ for details on installation. - -Here is a quick example to get you off your feet: - -First, generate a couple of genesis transactions to be incorparated into the genesis file, this will create two keys with the password ``1234567890`` - -:: - - gaiad init gen-tx --name=foo --home=$HOME/.gaiad1 - gaiad init gen-tx --name=bar --home=$HOME/.gaiad2 - gaiacli keys list - -**Note:** If you've already run these tests you may need to overwrite keys using the ``--OWK`` flag -When you list the keys you should see two addresses, we'll need these later so take note. -Now let's actually create the genesis files for both nodes: - -:: - - cp -a ~/.gaiad2/config/gentx/. ~/.gaiad1/config/gentx/ - cp -a ~/.gaiad1/config/gentx/. ~/.gaiad2/config/gentx/ - gaiad init --gen-txs --home=$HOME/.gaiad1 --chain-id=test-chain - gaiad init --gen-txs --home=$HOME/.gaiad2 --chain-id=test-chain - -**Note:** If you've already run these tests you may need to overwrite genesis using the ``-o`` flag -What we just did is copy the genesis transactions between each of the nodes so there is a common genesis transaction set; then we created both genesis files independently from each home directory. Importantly both nodes have independently created their ``genesis.json`` and ``config.toml`` files, which should be identical between nodes. - -Great, now that we've initialized the chains, we can start both nodes in the background: - -:: - - gaiad start --home=$HOME/.gaiad1 &> gaia1.log & - NODE1_PID=$! - gaia start --home=$HOME/.gaiad2 &> gaia2.log & - NODE2_PID=$! - -Note that we save the PID so we can later kill the processes. You can peak at your logs with ``tail gaia1.log``, or follow them for a bit with ``tail -f gaia1.log``. - -Nice. We can also lookup the validator set: - -:: - - gaiacli advanced tendermint validator-set - -Then, we try to transfer some ``steak`` to another account: - -:: - - gaiacli account - gaiacli account - gaiacli send --amount=10steak --to= --name=foo --chain-id=test-chain - -**Note:** We need to be careful with the ``chain-id`` and ``sequence`` - -Check the balance & sequence with: - -:: - - gaiacli account - -To confirm for certain the new validator is active, check tendermint: - -:: - - curl localhost:26657/validators - -Finally, to relinquish all your power, unbond some coins. You should see your VotingPower reduce and your account balance increase. - -:: - - gaiacli stake unbond --chain-id= --name=test - -That's it! - -**Note:** TODO demonstrate edit-candidacy -**Note:** TODO demonstrate delegation -**Note:** TODO demonstrate unbond of delegation -**Note:** TODO demonstrate unbond candidate diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index 3a2237a3c0..0000000000 --- a/docs/index.rst +++ /dev/null @@ -1,60 +0,0 @@ -.. Cosmos-SDK documentation master file, created by - sphinx-quickstart on Fri Sep 1 21:37:02 2017. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to the Cosmos SDK! -========================== - -.. image:: graphics/cosmos-sdk-image.png - :height: 250px - :width: 500px - :align: center - -SDK ---- - -.. toctree:: - :maxdepth: 1 - - guides/sdk/install.md - guides/sdk/key-management.md - -.. sdk/overview.rst # needs to be updated -.. old/glossary.rst # not completely up to date but has good content - -.. Basecoin -.. -------- - -.. .. toctree:: - :maxdepth: 2 - -.. old/basecoin/basics.rst # has a decent getting-start tutorial that's relatively up to date, should be consolidated with the other getting started doc - -.. Extensions -.. ---------- - -.. old/basecoin/extensions.rst # probably not worth salvaging - -.. Replay Protection -.. ~~~~~~~~~~~~~~~~~ - -.. old/replay-protection.rst # not sure if worth salvaging - - -Staking -~~~~~~~ - -.. toctree:: - :maxdepth: 1 - - guides/staking/testnet.md -.. staking/intro.rst -.. staking/key-management.rst -.. staking/local-testnet.rst -.. staking/public-testnet.rst - -.. IBC -.. --- - -.. old/ibc.rst # needs to be updated diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 916e57ee79..0000000000 --- a/docs/make.bat +++ /dev/null @@ -1,36 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=python -msphinx -) -set SOURCEDIR=. -set BUILDDIR=_build -set SPHINXPROJ=Cosmos-SDK - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The Sphinx module was not found. Make sure you have Sphinx installed, - echo.then set the SPHINXBUILD environment variable to point to the full - echo.path of the 'sphinx-build' executable. Alternatively you may add the - echo.Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% - -:end -popd From b983bd3ddf28ab0e0cdb83b02c5c60c63bbd1a16 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 18 Jun 2018 12:32:17 -0700 Subject: [PATCH 13/13] /docs/sdk -> /docs --- docs/{sdk => }/README.md | 0 docs/{sdk => }/clients/key-management.md | 0 docs/{sdk => }/clients/lcd-rest-api.yaml | 0 docs/{sdk => }/core/accounts.md | 0 docs/{sdk => }/core/amino.md | 0 docs/{sdk => }/core/baseapp.md | 0 docs/{sdk => }/core/handlers.md | 0 docs/{sdk => }/core/keepers.md | 0 docs/{sdk => }/core/messages.md | 0 docs/{sdk => }/core/multistore.md | 0 docs/{sdk => }/core/transactions.md | 0 docs/{sdk => }/install.md | 0 docs/{sdk => }/overview/apps.md | 0 docs/{sdk => }/overview/capabilities.md | 0 docs/{sdk => }/overview/overview.md | 0 15 files changed, 0 insertions(+), 0 deletions(-) rename docs/{sdk => }/README.md (100%) rename docs/{sdk => }/clients/key-management.md (100%) rename docs/{sdk => }/clients/lcd-rest-api.yaml (100%) rename docs/{sdk => }/core/accounts.md (100%) rename docs/{sdk => }/core/amino.md (100%) rename docs/{sdk => }/core/baseapp.md (100%) rename docs/{sdk => }/core/handlers.md (100%) rename docs/{sdk => }/core/keepers.md (100%) rename docs/{sdk => }/core/messages.md (100%) rename docs/{sdk => }/core/multistore.md (100%) rename docs/{sdk => }/core/transactions.md (100%) rename docs/{sdk => }/install.md (100%) rename docs/{sdk => }/overview/apps.md (100%) rename docs/{sdk => }/overview/capabilities.md (100%) rename docs/{sdk => }/overview/overview.md (100%) diff --git a/docs/sdk/README.md b/docs/README.md similarity index 100% rename from docs/sdk/README.md rename to docs/README.md diff --git a/docs/sdk/clients/key-management.md b/docs/clients/key-management.md similarity index 100% rename from docs/sdk/clients/key-management.md rename to docs/clients/key-management.md diff --git a/docs/sdk/clients/lcd-rest-api.yaml b/docs/clients/lcd-rest-api.yaml similarity index 100% rename from docs/sdk/clients/lcd-rest-api.yaml rename to docs/clients/lcd-rest-api.yaml diff --git a/docs/sdk/core/accounts.md b/docs/core/accounts.md similarity index 100% rename from docs/sdk/core/accounts.md rename to docs/core/accounts.md diff --git a/docs/sdk/core/amino.md b/docs/core/amino.md similarity index 100% rename from docs/sdk/core/amino.md rename to docs/core/amino.md diff --git a/docs/sdk/core/baseapp.md b/docs/core/baseapp.md similarity index 100% rename from docs/sdk/core/baseapp.md rename to docs/core/baseapp.md diff --git a/docs/sdk/core/handlers.md b/docs/core/handlers.md similarity index 100% rename from docs/sdk/core/handlers.md rename to docs/core/handlers.md diff --git a/docs/sdk/core/keepers.md b/docs/core/keepers.md similarity index 100% rename from docs/sdk/core/keepers.md rename to docs/core/keepers.md diff --git a/docs/sdk/core/messages.md b/docs/core/messages.md similarity index 100% rename from docs/sdk/core/messages.md rename to docs/core/messages.md diff --git a/docs/sdk/core/multistore.md b/docs/core/multistore.md similarity index 100% rename from docs/sdk/core/multistore.md rename to docs/core/multistore.md diff --git a/docs/sdk/core/transactions.md b/docs/core/transactions.md similarity index 100% rename from docs/sdk/core/transactions.md rename to docs/core/transactions.md diff --git a/docs/sdk/install.md b/docs/install.md similarity index 100% rename from docs/sdk/install.md rename to docs/install.md diff --git a/docs/sdk/overview/apps.md b/docs/overview/apps.md similarity index 100% rename from docs/sdk/overview/apps.md rename to docs/overview/apps.md diff --git a/docs/sdk/overview/capabilities.md b/docs/overview/capabilities.md similarity index 100% rename from docs/sdk/overview/capabilities.md rename to docs/overview/capabilities.md diff --git a/docs/sdk/overview/overview.md b/docs/overview/overview.md similarity index 100% rename from docs/sdk/overview/overview.md rename to docs/overview/overview.md