Skip to content

Commit

Permalink
Merge pull request Agoric#43 from cosmos/sunny/combine-stores
Browse files Browse the repository at this point in the history
R4R: Combined three stores into one with Whois struct as value  Agoric#2
  • Loading branch information
sunnya97 committed Mar 7, 2019
2 parents 5dc438f + 2d344d6 commit 527b9fd
Show file tree
Hide file tree
Showing 14 changed files with 244 additions and 186 deletions.
22 changes: 11 additions & 11 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 4 additions & 12 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ type nameServiceApp struct {

keyMain *sdk.KVStoreKey
keyAccount *sdk.KVStoreKey
keyNSnames *sdk.KVStoreKey
keyNSowners *sdk.KVStoreKey
keyNSprices *sdk.KVStoreKey
keyNS *sdk.KVStoreKey
keyFeeCollection *sdk.KVStoreKey
keyParams *sdk.KVStoreKey
tkeyParams *sdk.TransientStoreKey
Expand Down Expand Up @@ -60,9 +58,7 @@ func NewNameServiceApp(logger log.Logger, db dbm.DB) *nameServiceApp {

keyMain: sdk.NewKVStoreKey("main"),
keyAccount: sdk.NewKVStoreKey("acc"),
keyNSnames: sdk.NewKVStoreKey("ns_names"),
keyNSowners: sdk.NewKVStoreKey("ns_owners"),
keyNSprices: sdk.NewKVStoreKey("ns_prices"),
keyNS: sdk.NewKVStoreKey("ns"),
keyFeeCollection: sdk.NewKVStoreKey("fee_collection"),
keyParams: sdk.NewKVStoreKey("params"),
tkeyParams: sdk.NewTransientStoreKey("transient_params"),
Expand Down Expand Up @@ -93,9 +89,7 @@ func NewNameServiceApp(logger log.Logger, db dbm.DB) *nameServiceApp {
// It handles interactions with the namestore
app.nsKeeper = nameservice.NewKeeper(
app.bankKeeper,
app.keyNSnames,
app.keyNSowners,
app.keyNSprices,
app.keyNS,
app.cdc,
)

Expand All @@ -118,9 +112,7 @@ func NewNameServiceApp(logger log.Logger, db dbm.DB) *nameServiceApp {
app.MountStores(
app.keyMain,
app.keyAccount,
app.keyNSnames,
app.keyNSowners,
app.keyNSprices,
app.keyNS,
app.keyFeeCollection,
app.keyParams,
app.tkeyParams,
Expand Down
26 changes: 14 additions & 12 deletions tutorial/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ Through the course of this tutorial you will create the following files that mak
├── handler.go
├── keeper.go
├── msgs.go
└── querier.go
├── querier.go
└── types.go
```

Start by creating a new git repository:
Expand All @@ -56,18 +57,19 @@ Then, just follow along! The first step describes the design of your application

1. [Design](./app-design.md) the application.
2. Begin the implementation of your application in [`./app.go`](./app-init.md).
3. Start building your module with the [`Keeper`](./keeper.md).
4. Define state transitions through [`Msgs` and `Handlers`](./msgs-handlers.md).
3. Start building your module by defining some basic [`Types`](./types.md).
4. Create the main core of the module using the [`Keeper`](./keeper.md).
5. Define state transitions through [`Msgs` and `Handlers`](./msgs-handlers.md).
* [`SetName`](./set-name.md)
* [`BuyName`](./buy-name.md)
5. Make views on your state machine with [`Queriers`](./queriers.md).
6. Register your types in the encoding format using [`sdk.Codec`](./codec.md).
7. Create [CLI interactions for your module](./cli.md).
8. Create [HTTP routes for clients to access your nameservice](./rest.md)
9. Import your module and [finish building your application](./app-complete.md)!
10. Create the [`nsd` and `nscli` entry points](./entrypoint.md) to your application.
11. Setup [dependency management using `dep`](./dep.md).
12. [Build and run](./build-run.md) the example.
13. [Run REST routes](./run-rest.md).
6. Make views on your state machine with [`Queriers`](./queriers.md).
7. Register your types in the encoding format using [`sdk.Codec`](./codec.md).
8. Create [CLI interactions for your module](./cli.md).
9. Create [HTTP routes for clients to access your nameservice](./rest.md)
10. Import your module and [finish building your application](./app-complete.md)!
11. Create the [`nsd` and `nscli` entry points](./entrypoint.md) to your application.
12. Setup [dependency management using `dep`](./dep.md).
13. [Build and run](./build-run.md) the example.
14. [Run REST routes](./run-rest.md).

## [Click here](./app-design.md) to get started with the tutorial!
33 changes: 12 additions & 21 deletions tutorial/app-complete.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ type nameServiceApp struct {

keyMain *sdk.KVStoreKey
keyAccount *sdk.KVStoreKey
keyNSnames *sdk.KVStoreKey
keyNSowners *sdk.KVStoreKey
keyNSprices *sdk.KVStoreKey
keyNS *sdk.KVStoreKey
keyFeeCollection *sdk.KVStoreKey
keyParams *sdk.KVStoreKey
tkeyParams *sdk.TransientStoreKey
Expand All @@ -56,30 +54,29 @@ type nameServiceApp struct {
nsKeeper nameservice.Keeper
}

// NewNameServiceApp is a constructor function for nameServiceApp
func NewNameServiceApp(logger log.Logger, db dbm.DB) *nameServiceApp {

// First define the top level codec that will be shared by the different modules
cdc := MakeCodec()
// First define the top level codec that will be shared by the different modules
cdc := MakeCodec()

// BaseApp handles interactions with Tendermint through the ABCI protocol
bApp := bam.NewBaseApp(appName, logger, db, auth.DefaultTxDecoder(cdc))
// BaseApp handles interactions with Tendermint through the ABCI protocol
bApp := bam.NewBaseApp(appName, logger, db, auth.DefaultTxDecoder(cdc))

// Here you initialize your application with the store keys it requires
// Here you initialize your application with the store keys it requires
var app = &nameServiceApp{
BaseApp: bApp,
cdc: cdc,

keyMain: sdk.NewKVStoreKey("main"),
keyAccount: sdk.NewKVStoreKey("acc"),
keyNSnames: sdk.NewKVStoreKey("ns_names"),
keyNSowners: sdk.NewKVStoreKey("ns_owners"),
keyNSprices: sdk.NewKVStoreKey("ns_prices"),
keyNS: sdk.NewKVStoreKey("ns"),
keyFeeCollection: sdk.NewKVStoreKey("fee_collection"),
keyParams: sdk.NewKVStoreKey("params"),
tkeyParams: sdk.NewTransientStoreKey("transient_params"),
}

return app
return app
}
```

Expand Down Expand Up @@ -111,9 +108,7 @@ func NewNameServiceApp(logger log.Logger, db dbm.DB) *nameServiceApp {

keyMain: sdk.NewKVStoreKey("main"),
keyAccount: sdk.NewKVStoreKey("acc"),
keyNSnames: sdk.NewKVStoreKey("ns_names"),
keyNSowners: sdk.NewKVStoreKey("ns_owners"),
keyNSprices: sdk.NewKVStoreKey("ns_prices"),
keyNS: sdk.NewKVStoreKey("ns"),
keyFeeCollection: sdk.NewKVStoreKey("fee_collection"),
keyParams: sdk.NewKVStoreKey("params"),
tkeyParams: sdk.NewTransientStoreKey("transient_params"),
Expand Down Expand Up @@ -144,9 +139,7 @@ func NewNameServiceApp(logger log.Logger, db dbm.DB) *nameServiceApp {
// It handles interactions with the namestore
app.nsKeeper = nameservice.NewKeeper(
app.bankKeeper,
app.keyNSnames,
app.keyNSowners,
app.keyNSprices,
app.keyNS,
app.cdc,
)

Expand All @@ -169,9 +162,7 @@ func NewNameServiceApp(logger log.Logger, db dbm.DB) *nameServiceApp {
app.MountStores(
app.keyMain,
app.keyAccount,
app.keyNSnames,
app.keyNSowners,
app.keyNSprices,
app.keyNS,
app.keyFeeCollection,
app.keyParams,
app.tkeyParams,
Expand Down
11 changes: 4 additions & 7 deletions tutorial/app-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,16 @@ The state represents your application at a given moment. It tells how much token

The state of tokens and accounts is defined by the `auth` and `bank` modules, which means you don't have to concern yourself with it for now. What you need to do is define the part of the state that relates specifically to your `nameservice` module.

In the SDK, everything is stored in one store called the `multistore`. Any number of key/value stores (called [`KVStores`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#KVStore) in the Cosmos SDK) can be created in this multistore. For your application, you need to store:

- A mapping of `name` to `value`. Create a `nameStore` in the `multistore` to hold this data.
- A mapping of `name` to `owner`. Create a `ownerStore` in the `multistore` to hold this data.
- A mapping of `name` to `price`. Create a `priceStore` in the `multistore` to hold this data.
In the SDK, everything is stored in one store called the `multistore`. Any number of key/value stores (called [`KVStores`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#KVStore) in the Cosmos SDK) can be created in this multistore. For this application, we will use one store to map `name`s to its respective `whois`, a struct that holds a name's value, owner, and price.

## Messages

Messages are contained in transactions. They trigger state transitions. Each module defines a list of messages and how to handle them. Here are the messages you need to implement the desired functionality for your nameservice application:

- `MsgSetName`: This message allows name owners to set a value for a given name in the `nameStore`.
- `MsgBuyName`: This message allows accounts to buy a name and become their owner in the `ownerStore`.
- `MsgBuyName`: This message allows accounts to buy a name and become its owner in the `ownerStore`.
- When someone buys a name, they are required to pay the previous owner of the name a price higher than the price the previous owner paid for it. If a name does not have a previous owner yet, they must burn a `MinPrice` amount.

When a transaction (included in a block) reaches a Tendermint node, it is passed to the application via the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci) and decoded to get the message. The message is then routed to the appropriate module and handled there according to the logic defined in the `Handler`. If the state needs to be updated, the `Handler` calls the `Keeper` to perform the update. You will learn more about these concepts in the next steps of this tutorial.

### Now that you have decided on how your application functions from a high-level perspective, it is time to [start implementing it](./app-init.md)
### Now that you have decided on how your application functions from a high-level perspective, it is time to [start implementing it](./app-init.md)
2 changes: 1 addition & 1 deletion tutorial/app-init.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,4 @@ Great! You now have the skeleton of your application; however, it still lacks fu

As you have seen in the [application design](./app-design.md) section, you need three modules for your nameservice: `auth`, `bank` and `nameservice`. The first two already exist, but not the last! The `nameservice` module will define the bulk of your state machine. The next step is to build it.

### In order to complete your application, you need to include modules. Go ahead and [start building your nameservice module](./keeper.md). You will come back to `app.go` later.
### In order to complete your application, you need to include modules. Go ahead and [start building your nameservice module](./types.md). You will come back to `app.go` later.
11 changes: 5 additions & 6 deletions tutorial/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (

"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/sdk-application-tutorial/x/nameservice"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -75,11 +75,7 @@ func GetCmdWhois(queryRoute string, cdc *codec.Codec) *cobra.Command {
}
}

type whoIsRes struct {
Value string `json:"value"`
Owner sdk.AccAddress `json:"owner"`
Price sdk.Coins `json:"price"`
}
type whoIsRes nameservice.Whois

func (w whoIsRes) String() string {
return strings.TrimSpace(fmt.Sprintf(`Owner: %s
Expand All @@ -96,6 +92,9 @@ Notes on the above code:
- The second piece (`nameservice`) is the name of the module to route the query to.
- Finally there is the specific querier in the module that will be called.
- In this example the fourth piece is the query. This works because the query parameter is a simple string. To enable more complex query inputs you need to use the second argument of the [`.QueryWithData()`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context#CLIContext.QueryWithData) function to pass in `data`. For an example of this see the [queriers in the Staking module](https://github.com/cosmos/cosmos-sdk/blob/develop/x/stake/querier/querier.go#L103).
- Each output type should be something that is both JSON marshallable and stringable (implements the Golang `fmt.Stringer` interface).
- So for the output type of `resolve` we wrap the resolution string in a struct called `resolveRes` which is both JSON marshallable and has a `.String()` method.
- For the output of Whois, the normal Whois struct is already JSON marshalable, but we need to add a `.String()` method on it.

## Transactions

Expand Down
Loading

0 comments on commit 527b9fd

Please sign in to comment.