From 7566ac2a9475f07dd505f90037386196df4522b1 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 26 Jun 2018 17:21:46 -0400 Subject: [PATCH] consolidate files into appX.md --- docs/core/accounts.md | 101 ------------------------ docs/core/{amino.md => app2.md} | 0 docs/core/{transactions.md => app3.md} | 102 +++++++++++++++++++++++++ docs/core/{keepers.md => app4.md} | 0 docs/core/baseapp.md | 19 ----- docs/core/handlers.md | 25 +----- docs/core/intro.md | 17 +++++ docs/core/messages.md | 76 ------------------ docs/core/multistore.md | 6 ++ 9 files changed, 127 insertions(+), 219 deletions(-) delete mode 100644 docs/core/accounts.md rename docs/core/{amino.md => app2.md} (100%) rename docs/core/{transactions.md => app3.md} (67%) rename docs/core/{keepers.md => app4.md} (100%) delete mode 100644 docs/core/baseapp.md create mode 100644 docs/core/intro.md delete mode 100644 docs/core/messages.md diff --git a/docs/core/accounts.md b/docs/core/accounts.md deleted file mode 100644 index 194c5e4d5..000000000 --- a/docs/core/accounts.md +++ /dev/null @@ -1,101 +0,0 @@ -# Accounts - -### 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/core/amino.md b/docs/core/app2.md similarity index 100% rename from docs/core/amino.md rename to docs/core/app2.md diff --git a/docs/core/transactions.md b/docs/core/app3.md similarity index 67% rename from docs/core/transactions.md rename to docs/core/app3.md index aafcb105c..5d14adf4e 100644 --- a/docs/core/transactions.md +++ b/docs/core/app3.md @@ -152,3 +152,105 @@ app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeepe 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 + +### 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/core/keepers.md b/docs/core/app4.md similarity index 100% rename from docs/core/keepers.md rename to docs/core/app4.md diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md deleted file mode 100644 index 7029b16ea..000000000 --- a/docs/core/baseapp.md +++ /dev/null @@ -1,19 +0,0 @@ -# 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/core/handlers.md b/docs/core/handlers.md index 5dbc22ef3..8b2ef8f82 100644 --- a/docs/core/handlers.md +++ b/docs/core/handlers.md @@ -1,26 +1,4 @@ -# Message Handling - -## 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, 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 -``` +# Handlers A handler takes a context and a message and returns a result. All information necessary for processing a message should be available in the @@ -50,3 +28,4 @@ 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/core/intro.md b/docs/core/intro.md new file mode 100644 index 000000000..df5c928d5 --- /dev/null +++ b/docs/core/intro.md @@ -0,0 +1,17 @@ +# Introduction + +Welcome to the Cosmos-SDK Core Documentation. + +Here you will learn how to use the Cosmos-SDK to build Basecoin, a +complete proof-of-stake cryptocurrency system + +We proceed through a series of increasingly advanced and complete implementations of +the Basecoin application, with each implementation showcasing a new component of +the SDK: + +- App1 - The Basics - Messages, Stores, Handlers, BaseApp +- App2 - Amino - Unmarshalling into interfaces +- App3 - Authentication - Accounts and Transactions, Signatures and Replay protection +- App4 - Access Control - Keepers selective expose access to stores +- App5 - Validator Set Changes - Change the Tendermint validator set +- App6 - Basecoin - Bringing it all together diff --git a/docs/core/messages.md b/docs/core/messages.md deleted file mode 100644 index 15190a886..000000000 --- a/docs/core/messages.md +++ /dev/null @@ -1,76 +0,0 @@ -# Messages - -Messages are the primary inputs to application state machines. -Developers 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 SDK 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 -// 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"` -} -``` - -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/core/multistore.md b/docs/core/multistore.md index 1ac80af8e..9b7f6cd19 100644 --- a/docs/core/multistore.md +++ b/docs/core/multistore.md @@ -1,5 +1,7 @@ # MultiStore +TODO: reconcile this + 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, @@ -14,6 +16,7 @@ The goals of the MultiStore are as follows: - 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, @@ -55,9 +58,12 @@ through the `Context`. ## Notes +TODO: move this to the spec + 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. +