basecoin upgrade without CLI

This commit is contained in:
rigelrozanski 2018-03-03 17:30:08 +00:00
parent 6dec9353be
commit 131130b7a4
7 changed files with 200 additions and 168 deletions

View File

@ -16,6 +16,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/examples/basecoin/types"
"github.com/cosmos/cosmos-sdk/examples/basecoin/x/cool"
"github.com/cosmos/cosmos-sdk/examples/basecoin/x/sketchy"
)
@ -53,8 +54,10 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp {
// add handlers
coinKeeper := bank.NewCoinKeeper(app.accountMapper)
coolMapper := cool.NewMapper(app.capKeyMainStore)
app.Router().
AddRoute("bank", bank.NewHandler(coinKeeper)).
AddRoute("cool", cool.NewHandler(coinKeeper, coolMapper)).
AddRoute("sketchy", sketchy.NewHandler())
// initialize BaseApp
@ -73,39 +76,34 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp {
}
// custom tx codec
// TODO: use new go-wire
func MakeCodec() *wire.Codec {
// XXX: Using old wire for now :)
const (
msgTypeSend = 0x1
msgTypeIssue = 0x2
)
const msgTypeSend = 0x1
const msgTypeIssue = 0x2
var _ = oldwire.RegisterInterface(
struct{ sdk.Msg }{},
oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend},
oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue},
)
const (
accTypeApp = 0x1
)
const accTypeApp = 0x1
var _ = oldwire.RegisterInterface(
struct{ sdk.Account }{},
oldwire.ConcreteType{&types.AppAccount{}, accTypeApp},
)
cdc := wire.NewCodec()
// TODO: use new go-wire
// cdc.RegisterInterface((*sdk.Msg)(nil), nil)
// bank.RegisterWire(cdc) // Register bank.[SendMsg,IssueMsg] types.
// crypto.RegisterWire(cdc) // Register crypto.[PubKey,PrivKey,Signature] types.
return cdc
}
// custom logic for transaction decoding
func (app *BasecoinApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) {
var tx = sdk.StdTx{}
// StdTx.Msg is an interface. The concrete types
// are registered by MakeTxCodec in bank.RegisterWire.
err := app.cdc.UnmarshalBinary(txBytes, &tx)

View File

@ -0,0 +1,57 @@
package cool
import (
"fmt"
"reflect"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank"
)
// This is just an example to demonstrate a functional custom module
// with full feature set functionality.
//
// /$$$$$$$ /$$$$$$ /$$$$$$ /$$
// /$$_____/ /$$__ $$ /$$__ $$| $$
//| $$ | $$ \ $$| $$ \ $$| $$
//| $$ | $$ | $$| $$ | $$| $$
//| $$$$$$$| $$$$$$/| $$$$$$/| $$$$$$$
// \_______/ \______/ \______/ |______/
// Handle all "coolmodule" type objects
func NewHandler(ck bank.CoinKeeper, cm Mapper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
switch msg := msg.(type) {
case SetWhatCoolMsg:
return handleSetWhatCoolMsg(ctx, cm, msg)
case WhatCoolMsg:
return handleWhatCoolMsg(ctx, ck, cm, msg)
default:
errMsg := fmt.Sprintf("Unrecognized cool Msg type: %v", reflect.TypeOf(msg).Name())
return sdk.ErrUnknownRequest(errMsg).Result()
}
}
}
// Handle WhatCoolMsg This is the engine of your module
func handleSetWhatCoolMsg(ctx sdk.Context, cm Mapper, msg SetWhatCoolMsg) sdk.Result {
cm.SetWhatCool(ctx, msg.WhatCool)
return sdk.Result{}
}
// Handle WhatCoolMsg This is the engine of your module
func handleWhatCoolMsg(ctx sdk.Context, ck bank.CoinKeeper, cm Mapper, msg WhatCoolMsg) sdk.Result {
whatsCool := cm.GetWhatCool(ctx)
if msg.CoolerThanCool == whatsCool {
bonusCoins := sdk.Coins{{whatsCool, 69}}
_, err := ck.AddCoins(ctx, msg.Sender, bonusCoins)
if err != nil {
return err.Result()
}
}
return sdk.Result{}
}

View File

@ -0,0 +1,30 @@
package cool
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// This Cool Mapper handlers sets/gets of custom variables for your module
type Mapper struct {
key sdk.StoreKey // The (unexposed) key used to access the store from the Context.
}
func NewMapper(key sdk.StoreKey) Mapper {
return Mapper{key}
}
// Key to knowing whats cool
var whatCoolKey = []byte("WhatsCoolKey")
// Implements sdk.AccountMapper.
func (am Mapper) GetWhatCool(ctx sdk.Context) string {
store := ctx.KVStore(am.key)
bz := store.Get(whatCoolKey)
return string(bz)
}
// Implements sdk.AccountMapper.
func (am Mapper) SetWhatCool(ctx sdk.Context, whatscool string) {
store := ctx.KVStore(am.key)
store.Set(whatCoolKey, []byte(whatscool))
}

View File

@ -0,0 +1,103 @@
package cool
import (
"encoding/json"
"fmt"
"strings"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// A really cool msg type, these fields are can be entirely arbitrary and
// custom to your message
type SetWhatCoolMsg struct {
Sender sdk.Address
WhatCool string
}
// New cool message
func NewSetWhatCoolMsg(sender sdk.Address, whatcool string) SetWhatCoolMsg {
return SetWhatCoolMsg{
Sender: sender,
WhatCool: whatcool,
}
}
// enforce the msg type at compile time
var _ sdk.Msg = SetWhatCoolMsg{}
// nolint
func (msg SetWhatCoolMsg) Type() string { return "cool" }
func (msg SetWhatCoolMsg) Get(key interface{}) (value interface{}) { return nil }
func (msg SetWhatCoolMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} }
func (msg SetWhatCoolMsg) String() string {
return fmt.Sprintf("SetWhatCoolMsg{Sender: %v, WhatCool: %v}", msg.Sender, msg.WhatCool)
}
// Validate Basic is used to quickly disqualify obviously invalid messages quickly
func (msg SetWhatCoolMsg) ValidateBasic() sdk.Error {
if len(msg.Sender) == 0 {
return sdk.ErrUnrecognizedAddress(msg.Sender).Trace("")
}
if strings.Contains(msg.WhatCool, "hot") {
return sdk.ErrUnauthorized("").Trace("hot is not cool")
}
if strings.Contains(msg.WhatCool, "warm") {
return sdk.ErrUnauthorized("").Trace("warm is not very cool")
}
return nil
}
// Get the bytes for the message signer to sign on
func (msg SetWhatCoolMsg) GetSignBytes() []byte {
b, err := json.Marshal(msg)
if err != nil {
panic(err)
}
return b
}
//_______________________________________________________________________
// A really cool msg type, these fields are can be entirely arbitrary and
// custom to your message
type WhatCoolMsg struct {
Sender sdk.Address
CoolerThanCool string
}
// New cool message
func NewWhatCoolMsg(sender sdk.Address, coolerthancool string) WhatCoolMsg {
return WhatCoolMsg{
Sender: sender,
CoolerThanCool: coolerthancool,
}
}
// enforce the msg type at compile time
var _ sdk.Msg = WhatCoolMsg{}
// nolint
func (msg WhatCoolMsg) Type() string { return "cool" }
func (msg WhatCoolMsg) Get(key interface{}) (value interface{}) { return nil }
func (msg WhatCoolMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} }
func (msg WhatCoolMsg) String() string {
return fmt.Sprintf("WhatCoolMsg{Sender: %v, CoolerThanCool: %v}", msg.Sender, msg.CoolerThanCool)
}
// Validate Basic is used to quickly disqualify obviously invalid messages quickly
func (msg WhatCoolMsg) ValidateBasic() sdk.Error {
if len(msg.Sender) == 0 {
return sdk.ErrUnrecognizedAddress(msg.Sender).Trace("")
}
return nil
}
// Get the bytes for the message signer to sign on
func (msg WhatCoolMsg) GetSignBytes() []byte {
b, err := json.Marshal(msg)
if err != nil {
panic(err)
}
return b
}

View File

@ -1,64 +0,0 @@
package coolmodule
import (
"reflect"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank"
)
// This is just an example to demonstrate a functional custom module
// with full feature set functionality.
//
// /$$$$$$$ /$$$$$$ /$$$$$$ /$$
// /$$_____/ /$$__ $$ /$$__ $$| $$
//| $$ | $$ \ $$| $$ \ $$| $$
//| $$ | $$ | $$| $$ | $$| $$
//| $$$$$$$| $$$$$$/| $$$$$$/| $$$$$$$
// \_______/ \______/ \______/ |______/
// Handle all "coolmodule" type objects
func NewHandler(ck bank.CoinKeeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
switch msg := msg.(type) {
case CoolMsg:
return handleCoolMsg(ctx, ck, msg)
case CoolerThanCoolMsg:
return handleMeltMsg(ctx, ck, msg)
default:
errMsg := "Unrecognized bank Msg type: " + reflect.TypeOf(msg).Name()
return sdk.ErrUnknownRequest(errMsg).Result()
}
}
}
// Handle CoolMsg This is the engine of your module
func handleCoolMsg(ctx sdk.Context, ck CoinKeeper, msg CoolMsg) sdk.Result {
if msg.coolerthancool == "icecold" {
bonusCoins := sdk.Coins{{"icecold", 69}}
_, err := ck.AddCoins(ctx, msg.Address, bonusCoins)
if err != nil {
return err.Result()
}
}
return sdk.Result{}
}
// Handle CoolMsg This is the engine of your module
func handleMeltMsg(ctx sdk.Context, ck CoinKeeper, msg CoolMsg) sdk.Result {
// checks for existence should already have occured
if strings.Prefix(msg.what, "ice") {
return bank.ErrInvalidInput("only frozen coins can use the blow dryer")
}
bonusCoins := sdk.Coins{{"icecold", 69}}
_, err := ck.SubtractCoins(ctx, msg.Address, bonusCoins)
if err != nil {
return err.Result()
}
return sdk.Result{}
}

View File

@ -1,92 +0,0 @@
package coolmodule
import (
"encoding/json"
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// A really cool msg type, these fields are can be entirely arbitrary and
// custom to your message
type CoolMsg struct {
Sender sdk.Address
Coolerthancool string
}
// New cool message
func NewCoolMsg(sender sdk.Address, coolerthancool string) CoolMsg {
return CoolMsg{
Sender: sender,
Coolerthancool: coolerthancool,
}
}
// enforce the msg type at compile time
var _ CoolMsg = sdk.Msg
// nolint
func (msg CoolMsg) Type() string { return "cool" }
func (msg CoolMsg) Get(key interface{}) (value interface{}) { return nil }
func (msg CoolMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} }
func (msg CoolMsg) String() string { return fmt.Sprintf("CoolMsg{%v}", msg) }
// Validate Basic is used to quickly disqualify obviously invalid messages quickly
func (msg CoolMsg) ValidateBasic() sdk.Error {
if msg.Signer.Empty() {
return ErrNoOutputs().Trace("")
}
return nil
}
// Get the bytes for the message signer to sign on
func (msg CoolMsg) GetSignBytes() []byte {
b, err := json.Marshal(msg)
if err != nil {
panic(err)
}
return b
}
//_______________________________________________________________________
// A really cool msg type, these fields are can be entirely arbitrary and
// custom to your message
type BlowDryMsg struct {
Sender sdk.Address
What sdk.Coin
}
// New cool message
func NewBlowDryMsg(sender sdk.Address, what sdk.Coin) BlowDryMsg {
return BlowDryMsg{
Sender: sender,
What: what,
}
}
// enforce the msg type at compile time
var _ BlowDryMsg = sdk.Msg
// nolint
func (msg BlowDryMsg) Type() string { return "cool" }
func (msg BlowDryMsg) Get(key interface{}) (value interface{}) { return nil }
func (msg BlowDryMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} }
func (msg BlowDryMsg) String() string { return fmt.Sprintf("BlowDryMsg{%v}", msg) }
// Validate Basic is used to quickly disqualify obviously invalid messages quickly
func (msg BlowDryMsg) ValidateBasic() sdk.Error {
if msg.Signer.Empty() {
return ErrNoOutputs().Trace("")
}
return nil
}
// Get the bytes for the message signer to sign on
func (msg BlowDryMsg) GetSignBytes() []byte {
b, err := json.Marshal(msg)
if err != nil {
panic(err)
}
return b
}

View File

@ -15,7 +15,7 @@ type SendMsg struct {
Outputs []Output `json:"outputs"`
}
var _ SendMsg = (nil)(sdk.Msg)
var _ sdk.Msg = SendMsg{}
// NewSendMsg - construct arbitrary multi-in, multi-out send msg.
func NewSendMsg(in []Input, out []Output) SendMsg {