Skip to content

Commit 527b9fd

Browse files
authored
Merge pull request Agoric#43 from cosmos/sunny/combine-stores
R4R: Combined three stores into one with Whois struct as value Agoric#2
2 parents 5dc438f + 2d344d6 commit 527b9fd

14 files changed

+244
-186
lines changed

Gopkg.lock

+11-11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app.go

+4-12
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ type nameServiceApp struct {
3030

3131
keyMain *sdk.KVStoreKey
3232
keyAccount *sdk.KVStoreKey
33-
keyNSnames *sdk.KVStoreKey
34-
keyNSowners *sdk.KVStoreKey
35-
keyNSprices *sdk.KVStoreKey
33+
keyNS *sdk.KVStoreKey
3634
keyFeeCollection *sdk.KVStoreKey
3735
keyParams *sdk.KVStoreKey
3836
tkeyParams *sdk.TransientStoreKey
@@ -60,9 +58,7 @@ func NewNameServiceApp(logger log.Logger, db dbm.DB) *nameServiceApp {
6058

6159
keyMain: sdk.NewKVStoreKey("main"),
6260
keyAccount: sdk.NewKVStoreKey("acc"),
63-
keyNSnames: sdk.NewKVStoreKey("ns_names"),
64-
keyNSowners: sdk.NewKVStoreKey("ns_owners"),
65-
keyNSprices: sdk.NewKVStoreKey("ns_prices"),
61+
keyNS: sdk.NewKVStoreKey("ns"),
6662
keyFeeCollection: sdk.NewKVStoreKey("fee_collection"),
6763
keyParams: sdk.NewKVStoreKey("params"),
6864
tkeyParams: sdk.NewTransientStoreKey("transient_params"),
@@ -93,9 +89,7 @@ func NewNameServiceApp(logger log.Logger, db dbm.DB) *nameServiceApp {
9389
// It handles interactions with the namestore
9490
app.nsKeeper = nameservice.NewKeeper(
9591
app.bankKeeper,
96-
app.keyNSnames,
97-
app.keyNSowners,
98-
app.keyNSprices,
92+
app.keyNS,
9993
app.cdc,
10094
)
10195

@@ -118,9 +112,7 @@ func NewNameServiceApp(logger log.Logger, db dbm.DB) *nameServiceApp {
118112
app.MountStores(
119113
app.keyMain,
120114
app.keyAccount,
121-
app.keyNSnames,
122-
app.keyNSowners,
123-
app.keyNSprices,
115+
app.keyNS,
124116
app.keyFeeCollection,
125117
app.keyParams,
126118
app.tkeyParams,

tutorial/README.md

+14-12
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ Through the course of this tutorial you will create the following files that mak
3939
├── handler.go
4040
├── keeper.go
4141
├── msgs.go
42-
└── querier.go
42+
├── querier.go
43+
└── types.go
4344
```
4445

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

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

7375
## [Click here](./app-design.md) to get started with the tutorial!

tutorial/app-complete.md

+12-21
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,7 @@ type nameServiceApp struct {
4242

4343
keyMain *sdk.KVStoreKey
4444
keyAccount *sdk.KVStoreKey
45-
keyNSnames *sdk.KVStoreKey
46-
keyNSowners *sdk.KVStoreKey
47-
keyNSprices *sdk.KVStoreKey
45+
keyNS *sdk.KVStoreKey
4846
keyFeeCollection *sdk.KVStoreKey
4947
keyParams *sdk.KVStoreKey
5048
tkeyParams *sdk.TransientStoreKey
@@ -56,30 +54,29 @@ type nameServiceApp struct {
5654
nsKeeper nameservice.Keeper
5755
}
5856

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

61-
// First define the top level codec that will be shared by the different modules
62-
cdc := MakeCodec()
60+
// First define the top level codec that will be shared by the different modules
61+
cdc := MakeCodec()
6362

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

67-
// Here you initialize your application with the store keys it requires
66+
// Here you initialize your application with the store keys it requires
6867
var app = &nameServiceApp{
6968
BaseApp: bApp,
7069
cdc: cdc,
7170

7271
keyMain: sdk.NewKVStoreKey("main"),
7372
keyAccount: sdk.NewKVStoreKey("acc"),
74-
keyNSnames: sdk.NewKVStoreKey("ns_names"),
75-
keyNSowners: sdk.NewKVStoreKey("ns_owners"),
76-
keyNSprices: sdk.NewKVStoreKey("ns_prices"),
73+
keyNS: sdk.NewKVStoreKey("ns"),
7774
keyFeeCollection: sdk.NewKVStoreKey("fee_collection"),
7875
keyParams: sdk.NewKVStoreKey("params"),
7976
tkeyParams: sdk.NewTransientStoreKey("transient_params"),
8077
}
8178

82-
return app
79+
return app
8380
}
8481
```
8582

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

112109
keyMain: sdk.NewKVStoreKey("main"),
113110
keyAccount: sdk.NewKVStoreKey("acc"),
114-
keyNSnames: sdk.NewKVStoreKey("ns_names"),
115-
keyNSowners: sdk.NewKVStoreKey("ns_owners"),
116-
keyNSprices: sdk.NewKVStoreKey("ns_prices"),
111+
keyNS: sdk.NewKVStoreKey("ns"),
117112
keyFeeCollection: sdk.NewKVStoreKey("fee_collection"),
118113
keyParams: sdk.NewKVStoreKey("params"),
119114
tkeyParams: sdk.NewTransientStoreKey("transient_params"),
@@ -144,9 +139,7 @@ func NewNameServiceApp(logger log.Logger, db dbm.DB) *nameServiceApp {
144139
// It handles interactions with the namestore
145140
app.nsKeeper = nameservice.NewKeeper(
146141
app.bankKeeper,
147-
app.keyNSnames,
148-
app.keyNSowners,
149-
app.keyNSprices,
142+
app.keyNS,
150143
app.cdc,
151144
)
152145

@@ -169,9 +162,7 @@ func NewNameServiceApp(logger log.Logger, db dbm.DB) *nameServiceApp {
169162
app.MountStores(
170163
app.keyMain,
171164
app.keyAccount,
172-
app.keyNSnames,
173-
app.keyNSowners,
174-
app.keyNSprices,
165+
app.keyNS,
175166
app.keyFeeCollection,
176167
app.keyParams,
177168
app.tkeyParams,

tutorial/app-design.md

+4-7
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,16 @@ The state represents your application at a given moment. It tells how much token
2323

2424
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.
2525

26-
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:
27-
28-
- A mapping of `name` to `value`. Create a `nameStore` in the `multistore` to hold this data.
29-
- A mapping of `name` to `owner`. Create a `ownerStore` in the `multistore` to hold this data.
30-
- A mapping of `name` to `price`. Create a `priceStore` in the `multistore` to hold this data.
26+
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.
3127

3228
## Messages
3329

3430
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:
3531

3632
- `MsgSetName`: This message allows name owners to set a value for a given name in the `nameStore`.
37-
- `MsgBuyName`: This message allows accounts to buy a name and become their owner in the `ownerStore`.
33+
- `MsgBuyName`: This message allows accounts to buy a name and become its owner in the `ownerStore`.
34+
- 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.
3835

3936
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.
4037

41-
### 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)
38+
### 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)

tutorial/app-init.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,4 @@ Great! You now have the skeleton of your application; however, it still lacks fu
9595

9696
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.
9797

98-
### 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.
98+
### 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.

tutorial/cli.md

+5-6
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919

2020
"github.com/cosmos/cosmos-sdk/client/context"
2121
"github.com/cosmos/cosmos-sdk/codec"
22-
sdk "github.com/cosmos/cosmos-sdk/types"
22+
"github.com/cosmos/sdk-application-tutorial/x/nameservice"
2323
"github.com/spf13/cobra"
2424
)
2525

@@ -75,11 +75,7 @@ func GetCmdWhois(queryRoute string, cdc *codec.Codec) *cobra.Command {
7575
}
7676
}
7777

78-
type whoIsRes struct {
79-
Value string `json:"value"`
80-
Owner sdk.AccAddress `json:"owner"`
81-
Price sdk.Coins `json:"price"`
82-
}
78+
type whoIsRes nameservice.Whois
8379

8480
func (w whoIsRes) String() string {
8581
return strings.TrimSpace(fmt.Sprintf(`Owner: %s
@@ -96,6 +92,9 @@ Notes on the above code:
9692
- The second piece (`nameservice`) is the name of the module to route the query to.
9793
- Finally there is the specific querier in the module that will be called.
9894
- 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).
95+
- Each output type should be something that is both JSON marshallable and stringable (implements the Golang `fmt.Stringer` interface).
96+
- 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.
97+
- For the output of Whois, the normal Whois struct is already JSON marshalable, but we need to add a `.String()` method on it.
9998

10099
## Transactions
101100

0 commit comments

Comments
 (0)