Merge pull request #813 from cosmos/rigel/staking-cli
Gaia Refactor / Stake CLI
This commit is contained in:
commit
1b9afdab48
|
@ -31,7 +31,7 @@ jobs:
|
||||||
name: binaries
|
name: binaries
|
||||||
command: |
|
command: |
|
||||||
export PATH="$GOBIN:$PATH"
|
export PATH="$GOBIN:$PATH"
|
||||||
make build
|
make install
|
||||||
- persist_to_workspace:
|
- persist_to_workspace:
|
||||||
root: /tmp/workspace
|
root: /tmp/workspace
|
||||||
paths:
|
paths:
|
||||||
|
@ -59,7 +59,9 @@ jobs:
|
||||||
- run:
|
- run:
|
||||||
name: Run tests
|
name: Run tests
|
||||||
command: |
|
command: |
|
||||||
for pkg in $(go list github.com/cosmos/cosmos-sdk/... | grep -v /vendor/ | circleci tests split --split-by=timings); do
|
export PATH="$GOBIN:$PATH"
|
||||||
|
make install
|
||||||
|
for pkg in $(go list github.com/cosmos/cosmos-sdk/... | grep -v /vendor/ | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test | circleci tests split --split-by=timings); do
|
||||||
id=$(basename "$pkg")
|
id=$(basename "$pkg")
|
||||||
|
|
||||||
go test -timeout 5m -race -coverprofile=/tmp/workspace/profiles/$id.out -covermode=atomic "$pkg"
|
go test -timeout 5m -race -coverprofile=/tmp/workspace/profiles/$id.out -covermode=atomic "$pkg"
|
||||||
|
|
|
@ -7,17 +7,19 @@ FEATURES:
|
||||||
* Add CacheContext
|
* Add CacheContext
|
||||||
* Add auto sequencing to client
|
* Add auto sequencing to client
|
||||||
* Add FeeHandler to ante handler
|
* Add FeeHandler to ante handler
|
||||||
|
* Gaia stake commands include, DeclareCandidacy, EditCandidacy, Delegate, Unbond
|
||||||
|
* MountStoreWithDB without providing a custom store works.
|
||||||
|
|
||||||
BREAKING CHANGES
|
BREAKING CHANGES
|
||||||
|
|
||||||
* Remove go-wire, use go-amino
|
* Remove go-wire, use go-amino
|
||||||
|
* Gaia simple-staking bond and unbond functions replaced
|
||||||
* [store] Add `SubspaceIterator` and `ReverseSubspaceIterator` to `KVStore` interface
|
* [store] Add `SubspaceIterator` and `ReverseSubspaceIterator` to `KVStore` interface
|
||||||
* [basecoin] NewBasecoinApp takes a `dbm.DB` and uses namespaced DBs for substores
|
* [basecoin] NewBasecoinApp takes a `dbm.DB` and uses namespaced DBs for substores
|
||||||
* All module keepers now require a codespace, see basecoin or democoin for usage
|
* All module keepers now require a codespace, see basecoin or democoin for usage
|
||||||
|
|
||||||
BUG FIXES
|
BUG FIXES
|
||||||
|
* Gaia now uses stake, ported from github.com/cosmos/gaia
|
||||||
* MountStoreWithDB without providing a custom store works.
|
|
||||||
|
|
||||||
## 0.14.1 (April 9, 2018)
|
## 0.14.1 (April 9, 2018)
|
||||||
|
|
||||||
|
|
14
Makefile
14
Makefile
|
@ -7,7 +7,7 @@ all: check_tools get_vendor_deps build build_examples test
|
||||||
########################################
|
########################################
|
||||||
### CI
|
### CI
|
||||||
|
|
||||||
ci: get_tools get_vendor_deps build test_cover
|
ci: get_tools get_vendor_deps install test_cover
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
### Build
|
### Build
|
||||||
|
@ -15,11 +15,11 @@ ci: get_tools get_vendor_deps build test_cover
|
||||||
# This can be unified later, here for easy demos
|
# This can be unified later, here for easy demos
|
||||||
build:
|
build:
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
go build $(BUILD_FLAGS) -o build/gaiad.exe ./cmd/gaiad
|
go build $(BUILD_FLAGS) -o build/gaiad.exe ./cmd/gaia/cmd/gaiad
|
||||||
go build $(BUILD_FLAGS) -o build/gaiacli.exe ./cmd/gaiacli
|
go build $(BUILD_FLAGS) -o build/gaiacli.exe ./cmd/gaia/cmd/gaiacli
|
||||||
else
|
else
|
||||||
go build $(BUILD_FLAGS) -o build/gaiad ./cmd/gaiad
|
go build $(BUILD_FLAGS) -o build/gaiad ./cmd/gaia/cmd/gaiad
|
||||||
go build $(BUILD_FLAGS) -o build/gaiacli ./cmd/gaiacli
|
go build $(BUILD_FLAGS) -o build/gaiacli ./cmd/gaia/cmd/gaiacli
|
||||||
endif
|
endif
|
||||||
|
|
||||||
build_examples:
|
build_examples:
|
||||||
|
@ -36,8 +36,8 @@ else
|
||||||
endif
|
endif
|
||||||
|
|
||||||
install:
|
install:
|
||||||
go install $(BUILD_FLAGS) ./cmd/gaiad
|
go install $(BUILD_FLAGS) ./cmd/gaia/cmd/gaiad
|
||||||
go install $(BUILD_FLAGS) ./cmd/gaiacli
|
go install $(BUILD_FLAGS) ./cmd/gaia/cmd/gaiacli
|
||||||
|
|
||||||
install_examples:
|
install_examples:
|
||||||
go install $(BUILD_FLAGS) ./examples/basecoin/cmd/basecoind
|
go install $(BUILD_FLAGS) ./examples/basecoin/cmd/basecoind
|
||||||
|
|
|
@ -322,9 +322,8 @@ func (app *BaseApp) DeliverTx(txBytes []byte) (res abci.ResponseDeliverTx) {
|
||||||
if result.IsOK() {
|
if result.IsOK() {
|
||||||
app.valUpdates = append(app.valUpdates, result.ValidatorUpdates...)
|
app.valUpdates = append(app.valUpdates, result.ValidatorUpdates...)
|
||||||
} else {
|
} else {
|
||||||
// Even though the Code is not OK, there will be some side
|
// Even though the Result.Code is not OK, there are still effects,
|
||||||
// effects, like those caused by fee deductions or sequence
|
// namely fee deductions and sequence incrementing.
|
||||||
// incrementations.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell the blockchain engine (i.e. Tendermint).
|
// Tell the blockchain engine (i.e. Tendermint).
|
||||||
|
@ -453,7 +452,7 @@ func (app *BaseApp) Commit() (res abci.ResponseCommit) {
|
||||||
// Use the header from this latest block.
|
// Use the header from this latest block.
|
||||||
app.setCheckState(header)
|
app.setCheckState(header)
|
||||||
|
|
||||||
// Emtpy the Deliver state
|
// Empty the Deliver state
|
||||||
app.deliverState = nil
|
app.deliverState = nil
|
||||||
|
|
||||||
return abci.ResponseCommit{
|
return abci.ResponseCommit{
|
||||||
|
|
|
@ -11,6 +11,12 @@ func init() {
|
||||||
wire.RegisterCrypto(cdc)
|
wire.RegisterCrypto(cdc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// marshal keys
|
||||||
func MarshalJSON(o interface{}) ([]byte, error) {
|
func MarshalJSON(o interface{}) ([]byte, error) {
|
||||||
return cdc.MarshalJSON(o)
|
return cdc.MarshalJSON(o)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unmarshal json
|
||||||
|
func UnmarshalJSON(bz []byte, ptr interface{}) error {
|
||||||
|
return cdc.UnmarshalJSON(bz, ptr)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,200 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
abci "github.com/tendermint/abci/types"
|
||||||
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
|
dbm "github.com/tendermint/tmlibs/db"
|
||||||
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
|
bam "github.com/cosmos/cosmos-sdk/baseapp"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/wire"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/ibc"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
appName = "GaiaApp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Extended ABCI application
|
||||||
|
type GaiaApp struct {
|
||||||
|
*bam.BaseApp
|
||||||
|
cdc *wire.Codec
|
||||||
|
|
||||||
|
// keys to access the substores
|
||||||
|
capKeyMainStore *sdk.KVStoreKey
|
||||||
|
capKeyAccountStore *sdk.KVStoreKey
|
||||||
|
capKeyIBCStore *sdk.KVStoreKey
|
||||||
|
capKeyStakeStore *sdk.KVStoreKey
|
||||||
|
|
||||||
|
// Manage getting and setting accounts
|
||||||
|
accountMapper sdk.AccountMapper
|
||||||
|
coinKeeper bank.CoinKeeper
|
||||||
|
ibcMapper ibc.IBCMapper
|
||||||
|
stakeKeeper stake.Keeper
|
||||||
|
|
||||||
|
// Handle fees
|
||||||
|
feeHandler sdk.FeeHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp {
|
||||||
|
// create your application object
|
||||||
|
var app = &GaiaApp{
|
||||||
|
BaseApp: bam.NewBaseApp(appName, logger, db),
|
||||||
|
cdc: MakeCodec(),
|
||||||
|
capKeyMainStore: sdk.NewKVStoreKey("main"),
|
||||||
|
capKeyAccountStore: sdk.NewKVStoreKey("acc"),
|
||||||
|
capKeyIBCStore: sdk.NewKVStoreKey("ibc"),
|
||||||
|
capKeyStakeStore: sdk.NewKVStoreKey("stake"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// define the accountMapper
|
||||||
|
app.accountMapper = auth.NewAccountMapper(
|
||||||
|
app.cdc,
|
||||||
|
app.capKeyMainStore, // target store
|
||||||
|
&auth.BaseAccount{}, // prototype
|
||||||
|
).Seal()
|
||||||
|
|
||||||
|
// add handlers
|
||||||
|
app.coinKeeper = bank.NewCoinKeeper(app.accountMapper)
|
||||||
|
app.ibcMapper = ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace))
|
||||||
|
app.stakeKeeper = stake.NewKeeper(app.cdc, app.capKeyStakeStore, app.coinKeeper, app.RegisterCodespace(stake.DefaultCodespace))
|
||||||
|
|
||||||
|
app.Router().
|
||||||
|
AddRoute("bank", bank.NewHandler(app.coinKeeper)).
|
||||||
|
AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)).
|
||||||
|
AddRoute("stake", stake.NewHandler(app.stakeKeeper))
|
||||||
|
|
||||||
|
// Define the feeHandler.
|
||||||
|
app.feeHandler = auth.BurnFeeHandler
|
||||||
|
|
||||||
|
// initialize BaseApp
|
||||||
|
app.SetTxDecoder(app.txDecoder)
|
||||||
|
app.SetInitChainer(app.initChainer)
|
||||||
|
app.SetEndBlocker(stake.NewEndBlocker(app.stakeKeeper))
|
||||||
|
app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyIBCStore, app.capKeyStakeStore)
|
||||||
|
app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeHandler))
|
||||||
|
err := app.LoadLatestVersion(app.capKeyMainStore)
|
||||||
|
if err != nil {
|
||||||
|
cmn.Exit(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return app
|
||||||
|
}
|
||||||
|
|
||||||
|
// custom tx codec
|
||||||
|
func MakeCodec() *wire.Codec {
|
||||||
|
var cdc = wire.NewCodec()
|
||||||
|
|
||||||
|
// Register Msgs
|
||||||
|
cdc.RegisterInterface((*sdk.Msg)(nil), nil)
|
||||||
|
|
||||||
|
ibc.RegisterWire(cdc)
|
||||||
|
bank.RegisterWire(cdc)
|
||||||
|
stake.RegisterWire(cdc)
|
||||||
|
|
||||||
|
// Register AppAccount
|
||||||
|
cdc.RegisterInterface((*sdk.Account)(nil), nil)
|
||||||
|
cdc.RegisterConcrete(&auth.BaseAccount{}, "gaia/Account", nil)
|
||||||
|
|
||||||
|
// Register crypto.
|
||||||
|
wire.RegisterCrypto(cdc)
|
||||||
|
|
||||||
|
return cdc
|
||||||
|
}
|
||||||
|
|
||||||
|
// custom logic for transaction decoding
|
||||||
|
func (app *GaiaApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) {
|
||||||
|
var tx = sdk.StdTx{}
|
||||||
|
|
||||||
|
if len(txBytes) == 0 {
|
||||||
|
return nil, sdk.ErrTxDecode("txBytes are empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
// StdTx.Msg is an interface. The concrete types
|
||||||
|
// are registered by MakeTxCodec
|
||||||
|
err := app.cdc.UnmarshalBinary(txBytes, &tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, sdk.ErrTxDecode("").Trace(err.Error())
|
||||||
|
}
|
||||||
|
return tx, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// custom logic for gaia initialization
|
||||||
|
func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
|
||||||
|
stateJSON := req.AppStateBytes
|
||||||
|
|
||||||
|
genesisState := new(GenesisState)
|
||||||
|
err := json.Unmarshal(stateJSON, genesisState)
|
||||||
|
if err != nil {
|
||||||
|
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468
|
||||||
|
// return sdk.ErrGenesisParse("").TraceCause(err, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the accounts
|
||||||
|
for _, gacc := range genesisState.Accounts {
|
||||||
|
acc := gacc.ToAccount()
|
||||||
|
app.accountMapper.SetAccount(ctx, acc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the initial stake information
|
||||||
|
stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData)
|
||||||
|
|
||||||
|
return abci.ResponseInitChain{}
|
||||||
|
}
|
||||||
|
|
||||||
|
//__________________________________________________________
|
||||||
|
|
||||||
|
// State to Unmarshal
|
||||||
|
type GenesisState struct {
|
||||||
|
Accounts []GenesisAccount `json:"accounts"`
|
||||||
|
StakeData stake.GenesisState `json:"stake"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenesisAccount doesn't need pubkey or sequence
|
||||||
|
type GenesisAccount struct {
|
||||||
|
Address sdk.Address `json:"address"`
|
||||||
|
Coins sdk.Coins `json:"coins"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount {
|
||||||
|
return GenesisAccount{
|
||||||
|
Address: acc.Address,
|
||||||
|
Coins: acc.Coins,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert GenesisAccount to GaiaAccount
|
||||||
|
func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) {
|
||||||
|
return &auth.BaseAccount{
|
||||||
|
Address: ga.Address,
|
||||||
|
Coins: ga.Coins.Sort(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultGenAppState expects two args: an account address
|
||||||
|
// and a coin denomination, and gives lots of coins to that address.
|
||||||
|
func DefaultGenAppState(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error) {
|
||||||
|
|
||||||
|
accAuth := auth.NewBaseAccountWithAddress(addr)
|
||||||
|
accAuth.Coins = sdk.Coins{{"fermion", 100000}}
|
||||||
|
acc := NewGenesisAccount(&accAuth)
|
||||||
|
genaccs := []GenesisAccount{acc}
|
||||||
|
|
||||||
|
genesisState := GenesisState{
|
||||||
|
Accounts: genaccs,
|
||||||
|
StakeData: stake.GetDefaultGenesisState(),
|
||||||
|
}
|
||||||
|
|
||||||
|
stateBytes, err := json.MarshalIndent(genesisState, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return stateBytes, nil
|
||||||
|
}
|
|
@ -0,0 +1,518 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/ibc"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||||
|
|
||||||
|
abci "github.com/tendermint/abci/types"
|
||||||
|
crypto "github.com/tendermint/go-crypto"
|
||||||
|
dbm "github.com/tendermint/tmlibs/db"
|
||||||
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Construct some global addrs and txs for tests.
|
||||||
|
var (
|
||||||
|
chainID = "" // TODO
|
||||||
|
|
||||||
|
accName = "foobart"
|
||||||
|
|
||||||
|
priv1 = crypto.GenPrivKeyEd25519()
|
||||||
|
addr1 = priv1.PubKey().Address()
|
||||||
|
priv2 = crypto.GenPrivKeyEd25519()
|
||||||
|
addr2 = priv2.PubKey().Address()
|
||||||
|
addr3 = crypto.GenPrivKeyEd25519().PubKey().Address()
|
||||||
|
priv4 = crypto.GenPrivKeyEd25519()
|
||||||
|
addr4 = priv4.PubKey().Address()
|
||||||
|
coins = sdk.Coins{{"foocoin", 10}}
|
||||||
|
halfCoins = sdk.Coins{{"foocoin", 5}}
|
||||||
|
manyCoins = sdk.Coins{{"foocoin", 1}, {"barcoin", 1}}
|
||||||
|
fee = sdk.StdFee{
|
||||||
|
sdk.Coins{{"foocoin", 0}},
|
||||||
|
0,
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMsg1 = bank.SendMsg{
|
||||||
|
Inputs: []bank.Input{bank.NewInput(addr1, coins)},
|
||||||
|
Outputs: []bank.Output{bank.NewOutput(addr2, coins)},
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMsg2 = bank.SendMsg{
|
||||||
|
Inputs: []bank.Input{bank.NewInput(addr1, coins)},
|
||||||
|
Outputs: []bank.Output{
|
||||||
|
bank.NewOutput(addr2, halfCoins),
|
||||||
|
bank.NewOutput(addr3, halfCoins),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMsg3 = bank.SendMsg{
|
||||||
|
Inputs: []bank.Input{
|
||||||
|
bank.NewInput(addr1, coins),
|
||||||
|
bank.NewInput(addr4, coins),
|
||||||
|
},
|
||||||
|
Outputs: []bank.Output{
|
||||||
|
bank.NewOutput(addr2, coins),
|
||||||
|
bank.NewOutput(addr3, coins),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMsg4 = bank.SendMsg{
|
||||||
|
Inputs: []bank.Input{
|
||||||
|
bank.NewInput(addr2, coins),
|
||||||
|
},
|
||||||
|
Outputs: []bank.Output{
|
||||||
|
bank.NewOutput(addr1, coins),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMsg5 = bank.SendMsg{
|
||||||
|
Inputs: []bank.Input{
|
||||||
|
bank.NewInput(addr1, manyCoins),
|
||||||
|
},
|
||||||
|
Outputs: []bank.Output{
|
||||||
|
bank.NewOutput(addr2, manyCoins),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func loggerAndDB() (log.Logger, dbm.DB) {
|
||||||
|
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app")
|
||||||
|
db := dbm.NewMemDB()
|
||||||
|
return logger, db
|
||||||
|
}
|
||||||
|
|
||||||
|
func newGaiaApp() *GaiaApp {
|
||||||
|
logger, db := loggerAndDB()
|
||||||
|
return NewGaiaApp(logger, db)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error {
|
||||||
|
genaccs := make([]GenesisAccount, len(accs))
|
||||||
|
for i, acc := range accs {
|
||||||
|
genaccs[i] = NewGenesisAccount(acc)
|
||||||
|
}
|
||||||
|
|
||||||
|
genesisState := GenesisState{
|
||||||
|
Accounts: genaccs,
|
||||||
|
StakeData: stake.GetDefaultGenesisState(),
|
||||||
|
}
|
||||||
|
|
||||||
|
stateBytes, err := json.MarshalIndent(genesisState, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the chain
|
||||||
|
vals := []abci.Validator{}
|
||||||
|
gapp.InitChain(abci.RequestInitChain{vals, stateBytes})
|
||||||
|
gapp.Commit()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//_______________________________________________________________________
|
||||||
|
|
||||||
|
func TestMsgs(t *testing.T) {
|
||||||
|
gapp := newGaiaApp()
|
||||||
|
require.Nil(t, setGenesis(gapp))
|
||||||
|
|
||||||
|
msgs := []struct {
|
||||||
|
msg sdk.Msg
|
||||||
|
}{
|
||||||
|
{sendMsg1},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, m := range msgs {
|
||||||
|
// Run a CheckDeliver
|
||||||
|
SignCheckDeliver(t, gapp, m.msg, []int64{int64(i)}, false, priv1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setGenesisAccounts(gapp *GaiaApp, accs ...*auth.BaseAccount) error {
|
||||||
|
genaccs := make([]GenesisAccount, len(accs))
|
||||||
|
for i, acc := range accs {
|
||||||
|
genaccs[i] = NewGenesisAccount(acc)
|
||||||
|
}
|
||||||
|
|
||||||
|
genesisState := GenesisState{
|
||||||
|
Accounts: genaccs,
|
||||||
|
StakeData: stake.GetDefaultGenesisState(),
|
||||||
|
}
|
||||||
|
|
||||||
|
stateBytes, err := json.MarshalIndent(genesisState, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the chain
|
||||||
|
vals := []abci.Validator{}
|
||||||
|
gapp.InitChain(abci.RequestInitChain{vals, stateBytes})
|
||||||
|
gapp.Commit()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenesis(t *testing.T) {
|
||||||
|
logger, dbs := loggerAndDB()
|
||||||
|
gapp := NewGaiaApp(logger, dbs)
|
||||||
|
|
||||||
|
// Construct some genesis bytes to reflect GaiaAccount
|
||||||
|
pk := crypto.GenPrivKeyEd25519().PubKey()
|
||||||
|
addr := pk.Address()
|
||||||
|
coins, err := sdk.ParseCoins("77foocoin,99barcoin")
|
||||||
|
require.Nil(t, err)
|
||||||
|
baseAcc := &auth.BaseAccount{
|
||||||
|
Address: addr,
|
||||||
|
Coins: coins,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = setGenesis(gapp, baseAcc)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
// A checkTx context
|
||||||
|
ctx := gapp.BaseApp.NewContext(true, abci.Header{})
|
||||||
|
res1 := gapp.accountMapper.GetAccount(ctx, baseAcc.Address)
|
||||||
|
assert.Equal(t, baseAcc, res1)
|
||||||
|
|
||||||
|
// reload app and ensure the account is still there
|
||||||
|
gapp = NewGaiaApp(logger, dbs)
|
||||||
|
ctx = gapp.BaseApp.NewContext(true, abci.Header{})
|
||||||
|
res1 = gapp.accountMapper.GetAccount(ctx, baseAcc.Address)
|
||||||
|
assert.Equal(t, baseAcc, res1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSendMsgWithAccounts(t *testing.T) {
|
||||||
|
gapp := newGaiaApp()
|
||||||
|
|
||||||
|
// Construct some genesis bytes to reflect GaiaAccount
|
||||||
|
// Give 77 foocoin to the first key
|
||||||
|
coins, err := sdk.ParseCoins("77foocoin")
|
||||||
|
require.Nil(t, err)
|
||||||
|
baseAcc := &auth.BaseAccount{
|
||||||
|
Address: addr1,
|
||||||
|
Coins: coins,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct genesis state
|
||||||
|
err = setGenesis(gapp, baseAcc)
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
// A checkTx context (true)
|
||||||
|
ctxCheck := gapp.BaseApp.NewContext(true, abci.Header{})
|
||||||
|
res1 := gapp.accountMapper.GetAccount(ctxCheck, addr1)
|
||||||
|
assert.Equal(t, baseAcc, res1.(*auth.BaseAccount))
|
||||||
|
|
||||||
|
// Run a CheckDeliver
|
||||||
|
SignCheckDeliver(t, gapp, sendMsg1, []int64{0}, true, priv1)
|
||||||
|
|
||||||
|
// Check balances
|
||||||
|
CheckBalance(t, gapp, addr1, "67foocoin")
|
||||||
|
CheckBalance(t, gapp, addr2, "10foocoin")
|
||||||
|
|
||||||
|
// Delivering again should cause replay error
|
||||||
|
SignCheckDeliver(t, gapp, sendMsg1, []int64{0}, false, priv1)
|
||||||
|
|
||||||
|
// bumping the txnonce number without resigning should be an auth error
|
||||||
|
tx := genTx(sendMsg1, []int64{0}, priv1)
|
||||||
|
tx.Signatures[0].Sequence = 1
|
||||||
|
res := gapp.Deliver(tx)
|
||||||
|
|
||||||
|
assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log)
|
||||||
|
|
||||||
|
// resigning the tx with the bumped sequence should work
|
||||||
|
SignCheckDeliver(t, gapp, sendMsg1, []int64{1}, true, priv1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSendMsgMultipleOut(t *testing.T) {
|
||||||
|
gapp := newGaiaApp()
|
||||||
|
|
||||||
|
genCoins, err := sdk.ParseCoins("42foocoin")
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
acc1 := &auth.BaseAccount{
|
||||||
|
Address: addr1,
|
||||||
|
Coins: genCoins,
|
||||||
|
}
|
||||||
|
|
||||||
|
acc2 := &auth.BaseAccount{
|
||||||
|
Address: addr2,
|
||||||
|
Coins: genCoins,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = setGenesis(gapp, acc1, acc2)
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
// Simulate a Block
|
||||||
|
SignCheckDeliver(t, gapp, sendMsg2, []int64{0}, true, priv1)
|
||||||
|
|
||||||
|
// Check balances
|
||||||
|
CheckBalance(t, gapp, addr1, "32foocoin")
|
||||||
|
CheckBalance(t, gapp, addr2, "47foocoin")
|
||||||
|
CheckBalance(t, gapp, addr3, "5foocoin")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSengMsgMultipleInOut(t *testing.T) {
|
||||||
|
gapp := newGaiaApp()
|
||||||
|
|
||||||
|
genCoins, err := sdk.ParseCoins("42foocoin")
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
acc1 := &auth.BaseAccount{
|
||||||
|
Address: addr1,
|
||||||
|
Coins: genCoins,
|
||||||
|
}
|
||||||
|
acc2 := &auth.BaseAccount{
|
||||||
|
Address: addr2,
|
||||||
|
Coins: genCoins,
|
||||||
|
}
|
||||||
|
acc4 := &auth.BaseAccount{
|
||||||
|
Address: addr4,
|
||||||
|
Coins: genCoins,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = setGenesis(gapp, acc1, acc2, acc4)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
// CheckDeliver
|
||||||
|
SignCheckDeliver(t, gapp, sendMsg3, []int64{0, 0}, true, priv1, priv4)
|
||||||
|
|
||||||
|
// Check balances
|
||||||
|
CheckBalance(t, gapp, addr1, "32foocoin")
|
||||||
|
CheckBalance(t, gapp, addr4, "32foocoin")
|
||||||
|
CheckBalance(t, gapp, addr2, "52foocoin")
|
||||||
|
CheckBalance(t, gapp, addr3, "10foocoin")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSendMsgDependent(t *testing.T) {
|
||||||
|
gapp := newGaiaApp()
|
||||||
|
|
||||||
|
genCoins, err := sdk.ParseCoins("42foocoin")
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
acc1 := &auth.BaseAccount{
|
||||||
|
Address: addr1,
|
||||||
|
Coins: genCoins,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = setGenesis(gapp, acc1)
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
// CheckDeliver
|
||||||
|
SignCheckDeliver(t, gapp, sendMsg1, []int64{0}, true, priv1)
|
||||||
|
|
||||||
|
// Check balances
|
||||||
|
CheckBalance(t, gapp, addr1, "32foocoin")
|
||||||
|
CheckBalance(t, gapp, addr2, "10foocoin")
|
||||||
|
|
||||||
|
// Simulate a Block
|
||||||
|
SignCheckDeliver(t, gapp, sendMsg4, []int64{0}, true, priv2)
|
||||||
|
|
||||||
|
// Check balances
|
||||||
|
CheckBalance(t, gapp, addr1, "42foocoin")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIBCMsgs(t *testing.T) {
|
||||||
|
gapp := newGaiaApp()
|
||||||
|
|
||||||
|
sourceChain := "source-chain"
|
||||||
|
destChain := "dest-chain"
|
||||||
|
|
||||||
|
baseAcc := &auth.BaseAccount{
|
||||||
|
Address: addr1,
|
||||||
|
Coins: coins,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := setGenesis(gapp, baseAcc)
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
// A checkTx context (true)
|
||||||
|
ctxCheck := gapp.BaseApp.NewContext(true, abci.Header{})
|
||||||
|
res1 := gapp.accountMapper.GetAccount(ctxCheck, addr1)
|
||||||
|
assert.Equal(t, baseAcc, res1)
|
||||||
|
|
||||||
|
packet := ibc.IBCPacket{
|
||||||
|
SrcAddr: addr1,
|
||||||
|
DestAddr: addr1,
|
||||||
|
Coins: coins,
|
||||||
|
SrcChain: sourceChain,
|
||||||
|
DestChain: destChain,
|
||||||
|
}
|
||||||
|
|
||||||
|
transferMsg := ibc.IBCTransferMsg{
|
||||||
|
IBCPacket: packet,
|
||||||
|
}
|
||||||
|
|
||||||
|
receiveMsg := ibc.IBCReceiveMsg{
|
||||||
|
IBCPacket: packet,
|
||||||
|
Relayer: addr1,
|
||||||
|
Sequence: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
SignCheckDeliver(t, gapp, transferMsg, []int64{0}, true, priv1)
|
||||||
|
CheckBalance(t, gapp, addr1, "")
|
||||||
|
SignCheckDeliver(t, gapp, transferMsg, []int64{1}, false, priv1)
|
||||||
|
SignCheckDeliver(t, gapp, receiveMsg, []int64{2}, true, priv1)
|
||||||
|
CheckBalance(t, gapp, addr1, "10foocoin")
|
||||||
|
SignCheckDeliver(t, gapp, receiveMsg, []int64{3}, false, priv1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStakeMsgs(t *testing.T) {
|
||||||
|
gapp := newGaiaApp()
|
||||||
|
|
||||||
|
genCoins, err := sdk.ParseCoins("42fermion")
|
||||||
|
require.Nil(t, err)
|
||||||
|
bondCoin, err := sdk.ParseCoin("10fermion")
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
acc1 := &auth.BaseAccount{
|
||||||
|
Address: addr1,
|
||||||
|
Coins: genCoins,
|
||||||
|
}
|
||||||
|
acc2 := &auth.BaseAccount{
|
||||||
|
Address: addr2,
|
||||||
|
Coins: genCoins,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = setGenesis(gapp, acc1, acc2)
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
// A checkTx context (true)
|
||||||
|
ctxCheck := gapp.BaseApp.NewContext(true, abci.Header{})
|
||||||
|
res1 := gapp.accountMapper.GetAccount(ctxCheck, addr1)
|
||||||
|
res2 := gapp.accountMapper.GetAccount(ctxCheck, addr2)
|
||||||
|
require.Equal(t, acc1, res1)
|
||||||
|
require.Equal(t, acc2, res2)
|
||||||
|
|
||||||
|
// Declare Candidacy
|
||||||
|
|
||||||
|
description := stake.NewDescription("foo_moniker", "", "", "")
|
||||||
|
declareCandidacyMsg := stake.NewMsgDeclareCandidacy(
|
||||||
|
addr1, priv1.PubKey(), bondCoin, description,
|
||||||
|
)
|
||||||
|
SignCheckDeliver(t, gapp, declareCandidacyMsg, []int64{0}, true, priv1)
|
||||||
|
|
||||||
|
ctxDeliver := gapp.BaseApp.NewContext(false, abci.Header{})
|
||||||
|
res1 = gapp.accountMapper.GetAccount(ctxDeliver, addr1)
|
||||||
|
require.Equal(t, genCoins.Minus(sdk.Coins{bondCoin}), res1.GetCoins())
|
||||||
|
candidate, found := gapp.stakeKeeper.GetCandidate(ctxDeliver, addr1)
|
||||||
|
require.True(t, found)
|
||||||
|
require.Equal(t, candidate.Address, addr1)
|
||||||
|
|
||||||
|
// Edit Candidacy
|
||||||
|
|
||||||
|
description = stake.NewDescription("bar_moniker", "", "", "")
|
||||||
|
editCandidacyMsg := stake.NewMsgEditCandidacy(
|
||||||
|
addr1, description,
|
||||||
|
)
|
||||||
|
SignDeliver(t, gapp, editCandidacyMsg, []int64{1}, true, priv1)
|
||||||
|
|
||||||
|
candidate, found = gapp.stakeKeeper.GetCandidate(ctxDeliver, addr1)
|
||||||
|
require.True(t, found)
|
||||||
|
require.Equal(t, candidate.Description, description)
|
||||||
|
|
||||||
|
// Delegate
|
||||||
|
|
||||||
|
delegateMsg := stake.NewMsgDelegate(
|
||||||
|
addr2, addr1, bondCoin,
|
||||||
|
)
|
||||||
|
SignDeliver(t, gapp, delegateMsg, []int64{0}, true, priv2)
|
||||||
|
|
||||||
|
ctxDeliver = gapp.BaseApp.NewContext(false, abci.Header{})
|
||||||
|
res2 = gapp.accountMapper.GetAccount(ctxDeliver, addr2)
|
||||||
|
require.Equal(t, genCoins.Minus(sdk.Coins{bondCoin}), res2.GetCoins())
|
||||||
|
bond, found := gapp.stakeKeeper.GetDelegatorBond(ctxDeliver, addr2, addr1)
|
||||||
|
require.True(t, found)
|
||||||
|
require.Equal(t, bond.DelegatorAddr, addr2)
|
||||||
|
|
||||||
|
// Unbond
|
||||||
|
|
||||||
|
unbondMsg := stake.NewMsgUnbond(
|
||||||
|
addr2, addr1, "MAX",
|
||||||
|
)
|
||||||
|
SignDeliver(t, gapp, unbondMsg, []int64{1}, true, priv2)
|
||||||
|
|
||||||
|
ctxDeliver = gapp.BaseApp.NewContext(false, abci.Header{})
|
||||||
|
res2 = gapp.accountMapper.GetAccount(ctxDeliver, addr2)
|
||||||
|
require.Equal(t, genCoins, res2.GetCoins())
|
||||||
|
_, found = gapp.stakeKeeper.GetDelegatorBond(ctxDeliver, addr2, addr1)
|
||||||
|
require.False(t, found)
|
||||||
|
}
|
||||||
|
|
||||||
|
//____________________________________________________________________________________
|
||||||
|
|
||||||
|
func CheckBalance(t *testing.T, gapp *GaiaApp, addr sdk.Address, balExpected string) {
|
||||||
|
ctxDeliver := gapp.BaseApp.NewContext(false, abci.Header{})
|
||||||
|
res2 := gapp.accountMapper.GetAccount(ctxDeliver, addr)
|
||||||
|
assert.Equal(t, balExpected, fmt.Sprintf("%v", res2.GetCoins()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func genTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) sdk.StdTx {
|
||||||
|
sigs := make([]sdk.StdSignature, len(priv))
|
||||||
|
for i, p := range priv {
|
||||||
|
sigs[i] = sdk.StdSignature{
|
||||||
|
PubKey: p.PubKey(),
|
||||||
|
Signature: p.Sign(sdk.StdSignBytes(chainID, seq, fee, msg)),
|
||||||
|
Sequence: seq[i],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sdk.NewStdTx(msg, fee, sigs)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func SignCheckDeliver(t *testing.T, gapp *GaiaApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) {
|
||||||
|
|
||||||
|
// Sign the tx
|
||||||
|
tx := genTx(msg, seq, priv...)
|
||||||
|
|
||||||
|
// Run a Check
|
||||||
|
res := gapp.Check(tx)
|
||||||
|
if expPass {
|
||||||
|
require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||||
|
} else {
|
||||||
|
require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simulate a Block
|
||||||
|
gapp.BeginBlock(abci.RequestBeginBlock{})
|
||||||
|
res = gapp.Deliver(tx)
|
||||||
|
if expPass {
|
||||||
|
require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||||
|
} else {
|
||||||
|
require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||||
|
}
|
||||||
|
gapp.EndBlock(abci.RequestEndBlock{})
|
||||||
|
|
||||||
|
// XXX fix code or add explaination as to why using commit breaks a bunch of these tests
|
||||||
|
//gapp.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX the only reason we are using Sign Deliver here is because the tests
|
||||||
|
// break on check tx the second time you use SignCheckDeliver in a test because
|
||||||
|
// the checktx state has not been updated likely because commit is not being
|
||||||
|
// called!
|
||||||
|
func SignDeliver(t *testing.T, gapp *GaiaApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) {
|
||||||
|
|
||||||
|
// Sign the tx
|
||||||
|
tx := genTx(msg, seq, priv...)
|
||||||
|
|
||||||
|
// Simulate a Block
|
||||||
|
gapp.BeginBlock(abci.RequestBeginBlock{})
|
||||||
|
res := gapp.Deliver(tx)
|
||||||
|
if expPass {
|
||||||
|
require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||||
|
} else {
|
||||||
|
require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||||
|
}
|
||||||
|
gapp.EndBlock(abci.RequestEndBlock{})
|
||||||
|
}
|
|
@ -0,0 +1,184 @@
|
||||||
|
package clitest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||||
|
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||||
|
"github.com/cosmos/cosmos-sdk/server"
|
||||||
|
"github.com/cosmos/cosmos-sdk/tests"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||||
|
crypto "github.com/tendermint/go-crypto"
|
||||||
|
crkeys "github.com/tendermint/go-crypto/keys"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGaiaCLISend(t *testing.T) {
|
||||||
|
|
||||||
|
tests.ExecuteT(t, "gaiad unsafe_reset_all", 1)
|
||||||
|
pass := "1234567890"
|
||||||
|
executeWrite(t, "gaiacli keys delete foo", pass)
|
||||||
|
executeWrite(t, "gaiacli keys delete bar", pass)
|
||||||
|
masterKey, chainID := executeInit(t, "gaiad init")
|
||||||
|
|
||||||
|
// get a free port, also setup some common flags
|
||||||
|
servAddr := server.FreeTCPAddr(t)
|
||||||
|
flags := fmt.Sprintf("--node=%v --chain-id=%v", servAddr, chainID)
|
||||||
|
|
||||||
|
// start gaiad server
|
||||||
|
cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr))
|
||||||
|
defer cmd.Process.Kill()
|
||||||
|
|
||||||
|
executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey)
|
||||||
|
executeWrite(t, "gaiacli keys add bar", pass)
|
||||||
|
|
||||||
|
fooAddr, _ := executeGetAddr(t, "gaiacli keys show foo --output=json")
|
||||||
|
barAddr, _ := executeGetAddr(t, "gaiacli keys show bar --output=json")
|
||||||
|
|
||||||
|
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags))
|
||||||
|
assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion"))
|
||||||
|
|
||||||
|
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10fermion --to=%v --name=foo", flags, barAddr), pass)
|
||||||
|
time.Sleep(time.Second * 3) // waiting for some blocks to pass
|
||||||
|
|
||||||
|
barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags))
|
||||||
|
assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("fermion"))
|
||||||
|
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags))
|
||||||
|
assert.Equal(t, int64(99990), fooAcc.GetCoins().AmountOf("fermion"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGaiaCLIDeclareCandidacy(t *testing.T) {
|
||||||
|
|
||||||
|
tests.ExecuteT(t, "gaiad unsafe_reset_all", 1)
|
||||||
|
pass := "1234567890"
|
||||||
|
executeWrite(t, "gaiacli keys delete foo", pass)
|
||||||
|
masterKey, chainID := executeInit(t, "gaiad init")
|
||||||
|
|
||||||
|
// get a free port, also setup some common flags
|
||||||
|
servAddr := server.FreeTCPAddr(t)
|
||||||
|
flags := fmt.Sprintf("--node=%v --chain-id=%v", servAddr, chainID)
|
||||||
|
|
||||||
|
// start gaiad server
|
||||||
|
cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr))
|
||||||
|
defer cmd.Process.Kill()
|
||||||
|
|
||||||
|
executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey)
|
||||||
|
fooAddr, fooPubKey := executeGetAddr(t, "gaiacli keys show foo --output=json")
|
||||||
|
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags))
|
||||||
|
assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion"))
|
||||||
|
|
||||||
|
// declare candidacy
|
||||||
|
declStr := fmt.Sprintf("gaiacli declare-candidacy %v", flags)
|
||||||
|
declStr += fmt.Sprintf(" --name=%v", "foo")
|
||||||
|
declStr += fmt.Sprintf(" --address-candidate=%v", fooAddr)
|
||||||
|
declStr += fmt.Sprintf(" --pubkey=%v", fooPubKey)
|
||||||
|
declStr += fmt.Sprintf(" --amount=%v", "3fermion")
|
||||||
|
declStr += fmt.Sprintf(" --moniker=%v", "foo-vally")
|
||||||
|
fmt.Printf("debug declStr: %v\n", declStr)
|
||||||
|
executeWrite(t, declStr, pass)
|
||||||
|
time.Sleep(time.Second * 3) // waiting for some blocks to pass
|
||||||
|
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags))
|
||||||
|
assert.Equal(t, int64(99997), fooAcc.GetCoins().AmountOf("fermion"))
|
||||||
|
candidate := executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, fooAddr))
|
||||||
|
assert.Equal(t, candidate.Address.String(), fooAddr)
|
||||||
|
assert.Equal(t, int64(3), candidate.Assets.Evaluate())
|
||||||
|
|
||||||
|
// TODO figure out why this times out with connection refused errors in go-bash
|
||||||
|
// unbond a single share
|
||||||
|
unbondStr := fmt.Sprintf("gaiacli unbond %v", flags)
|
||||||
|
unbondStr += fmt.Sprintf(" --name=%v", "foo")
|
||||||
|
unbondStr += fmt.Sprintf(" --address-candidate=%v", fooAddr)
|
||||||
|
unbondStr += fmt.Sprintf(" --address-delegator=%v", fooAddr)
|
||||||
|
unbondStr += fmt.Sprintf(" --shares=%v", "1")
|
||||||
|
unbondStr += fmt.Sprintf(" --sequence=%v", "1")
|
||||||
|
fmt.Printf("debug unbondStr: %v\n", unbondStr)
|
||||||
|
executeWrite(t, unbondStr, pass)
|
||||||
|
time.Sleep(time.Second * 3) // waiting for some blocks to pass
|
||||||
|
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags))
|
||||||
|
assert.Equal(t, int64(99998), fooAcc.GetCoins().AmountOf("fermion"))
|
||||||
|
candidate = executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, fooAddr))
|
||||||
|
assert.Equal(t, int64(2), candidate.Assets.Evaluate())
|
||||||
|
}
|
||||||
|
|
||||||
|
func executeWrite(t *testing.T, cmdStr string, writes ...string) {
|
||||||
|
cmd, wc, _ := tests.GoExecuteT(t, cmdStr)
|
||||||
|
|
||||||
|
for _, write := range writes {
|
||||||
|
_, err := wc.Write([]byte(write + "\n"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
cmd.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
func executeWritePrint(t *testing.T, cmdStr string, writes ...string) {
|
||||||
|
cmd, wc, rc := tests.GoExecuteT(t, cmdStr)
|
||||||
|
|
||||||
|
for _, write := range writes {
|
||||||
|
_, err := wc.Write([]byte(write + "\n"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
cmd.Wait()
|
||||||
|
|
||||||
|
bz := make([]byte, 100000)
|
||||||
|
rc.Read(bz)
|
||||||
|
fmt.Printf("debug read: %v\n", string(bz))
|
||||||
|
}
|
||||||
|
|
||||||
|
func executeInit(t *testing.T, cmdStr string) (masterKey, chainID string) {
|
||||||
|
out := tests.ExecuteT(t, cmdStr, 1)
|
||||||
|
outCut := "{" + strings.SplitN(out, "{", 2)[1] // weird I'm sorry
|
||||||
|
|
||||||
|
var initRes map[string]json.RawMessage
|
||||||
|
err := json.Unmarshal([]byte(outCut), &initRes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = json.Unmarshal(initRes["secret"], &masterKey)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = json.Unmarshal(initRes["chain_id"], &chainID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func executeGetAddr(t *testing.T, cmdStr string) (addr, pubKey string) {
|
||||||
|
out := tests.ExecuteT(t, cmdStr, 2)
|
||||||
|
var info crkeys.Info
|
||||||
|
keys.UnmarshalJSON([]byte(out), &info)
|
||||||
|
pubKey = hex.EncodeToString(info.PubKey.(crypto.PubKeyEd25519).Bytes())
|
||||||
|
|
||||||
|
// TODO this is really wierd, also error that not 64 characters!
|
||||||
|
pubKey = strings.TrimLeft(pubKey, "1624de6220")
|
||||||
|
pubKey = fmt.Sprintf("%064v", pubKey)
|
||||||
|
|
||||||
|
fmt.Printf("debug pubKey: %v\n", pubKey)
|
||||||
|
addr = info.PubKey.Address().String()
|
||||||
|
fmt.Printf("debug addr: %v\n", addr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount {
|
||||||
|
out := tests.ExecuteT(t, cmdStr, 2)
|
||||||
|
var initRes map[string]json.RawMessage
|
||||||
|
err := json.Unmarshal([]byte(out), &initRes)
|
||||||
|
require.NoError(t, err, "out %v, err %v", out, err)
|
||||||
|
value := initRes["value"]
|
||||||
|
var acc auth.BaseAccount
|
||||||
|
_ = json.Unmarshal(value, &acc) //XXX pubkey can't be decoded go amino issue
|
||||||
|
require.NoError(t, err, "value %v, err %v", string(value), err)
|
||||||
|
return acc
|
||||||
|
}
|
||||||
|
|
||||||
|
func executeGetCandidate(t *testing.T, cmdStr string) stake.Candidate {
|
||||||
|
out := tests.ExecuteT(t, cmdStr, 2)
|
||||||
|
var candidate stake.Candidate
|
||||||
|
cdc := app.MakeCodec()
|
||||||
|
err := cdc.UnmarshalJSON([]byte(out), &candidate)
|
||||||
|
require.NoError(t, err, "out %v, err %v", out, err)
|
||||||
|
return candidate
|
||||||
|
}
|
|
@ -17,14 +17,11 @@ import (
|
||||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands"
|
authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands"
|
||||||
bankcmd "github.com/cosmos/cosmos-sdk/x/bank/commands"
|
bankcmd "github.com/cosmos/cosmos-sdk/x/bank/commands"
|
||||||
ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/commands"
|
ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/commands"
|
||||||
simplestakingcmd "github.com/cosmos/cosmos-sdk/x/simplestake/commands"
|
stakecmd "github.com/cosmos/cosmos-sdk/x/stake/commands"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/examples/basecoin/app"
|
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||||
"github.com/cosmos/cosmos-sdk/examples/basecoin/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: distinguish from basecli
|
|
||||||
|
|
||||||
// rootCmd is the entry point for this binary
|
// rootCmd is the entry point for this binary
|
||||||
var (
|
var (
|
||||||
rootCmd = &cobra.Command{
|
rootCmd = &cobra.Command{
|
||||||
|
@ -34,10 +31,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// disable sorting
|
|
||||||
cobra.EnableCommandSorting = false
|
cobra.EnableCommandSorting = false
|
||||||
|
|
||||||
// get the codec
|
|
||||||
cdc := app.MakeCodec()
|
cdc := app.MakeCodec()
|
||||||
|
|
||||||
// TODO: setup keybase, viper object, etc. to be passed into
|
// TODO: setup keybase, viper object, etc. to be passed into
|
||||||
|
@ -53,24 +47,21 @@ func main() {
|
||||||
// add query/post commands (custom to binary)
|
// add query/post commands (custom to binary)
|
||||||
rootCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
client.GetCommands(
|
client.GetCommands(
|
||||||
authcmd.GetAccountCmd("main", cdc, types.GetAccountDecoder(cdc)),
|
authcmd.GetAccountCmd("main", cdc, authcmd.GetAccountDecoder(cdc)),
|
||||||
|
stakecmd.GetCmdQueryCandidate("stake", cdc),
|
||||||
|
//stakecmd.GetCmdQueryCandidates("stake", cdc),
|
||||||
|
stakecmd.GetCmdQueryDelegatorBond("stake", cdc),
|
||||||
|
//stakecmd.GetCmdQueryDelegatorBonds("stake", cdc),
|
||||||
)...)
|
)...)
|
||||||
rootCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
client.PostCommands(
|
client.PostCommands(
|
||||||
bankcmd.SendTxCmd(cdc),
|
bankcmd.SendTxCmd(cdc),
|
||||||
)...)
|
|
||||||
rootCmd.AddCommand(
|
|
||||||
client.PostCommands(
|
|
||||||
ibccmd.IBCTransferCmd(cdc),
|
ibccmd.IBCTransferCmd(cdc),
|
||||||
)...)
|
|
||||||
rootCmd.AddCommand(
|
|
||||||
client.PostCommands(
|
|
||||||
ibccmd.IBCRelayCmd(cdc),
|
ibccmd.IBCRelayCmd(cdc),
|
||||||
simplestakingcmd.BondTxCmd(cdc),
|
stakecmd.GetCmdDeclareCandidacy(cdc),
|
||||||
)...)
|
stakecmd.GetCmdEditCandidacy(cdc),
|
||||||
rootCmd.AddCommand(
|
stakecmd.GetCmdDelegate(cdc),
|
||||||
client.PostCommands(
|
stakecmd.GetCmdUnbond(cdc),
|
||||||
simplestakingcmd.UnbondTxCmd(cdc),
|
|
||||||
)...)
|
)...)
|
||||||
|
|
||||||
// add proxy, version and key info
|
// add proxy, version and key info
|
||||||
|
@ -83,6 +74,6 @@ func main() {
|
||||||
)
|
)
|
||||||
|
|
||||||
// prepare and add flags
|
// prepare and add flags
|
||||||
executor := cli.PrepareMainCmd(rootCmd, "BC", os.ExpandEnv("$HOME/.gaiacli"))
|
executor := cli.PrepareMainCmd(rootCmd, "GA", os.ExpandEnv("$HOME/.gaiacli"))
|
||||||
executor.Execute()
|
executor.Execute()
|
||||||
}
|
}
|
|
@ -11,7 +11,7 @@ import (
|
||||||
dbm "github.com/tendermint/tmlibs/db"
|
dbm "github.com/tendermint/tmlibs/db"
|
||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/examples/basecoin/app"
|
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
"github.com/cosmos/cosmos-sdk/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -25,21 +25,21 @@ var (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: distinguish from basecoin
|
|
||||||
func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
|
func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
|
||||||
dataDir := filepath.Join(rootDir, "data")
|
dataDir := filepath.Join(rootDir, "data")
|
||||||
db, err := dbm.NewGoLevelDB("gaia", dataDir)
|
db, err := dbm.NewGoLevelDB("gaia", dataDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
bapp := app.NewBasecoinApp(logger, db)
|
bapp := app.NewGaiaApp(logger, db)
|
||||||
return bapp, nil
|
return bapp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
server.AddCommands(rootCmd, server.DefaultGenAppState, generateApp, context)
|
server.AddCommands(rootCmd, app.DefaultGenAppState, generateApp, context)
|
||||||
|
|
||||||
// prepare and add flags
|
// prepare and add flags
|
||||||
executor := cli.PrepareBaseCmd(rootCmd, "GA", os.ExpandEnv("$HOME/.gaiad"))
|
rootDir := os.ExpandEnv("$HOME/.gaiad")
|
||||||
|
executor := cli.PrepareBaseCmd(rootCmd, "GA", rootDir)
|
||||||
executor.Execute()
|
executor.Execute()
|
||||||
}
|
}
|
|
@ -70,7 +70,7 @@ func (c initCmd) run(cmd *cobra.Command, args []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate secrete and address
|
// generate secret and address
|
||||||
addr, secret, err := GenerateCoinKey()
|
addr, secret, err := GenerateCoinKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getCmd(t *testing.T, command string) *exec.Cmd {
|
||||||
|
|
||||||
|
//split command into command and args
|
||||||
|
split := strings.Split(command, " ")
|
||||||
|
require.True(t, len(split) > 0, "no command provided")
|
||||||
|
|
||||||
|
var cmd *exec.Cmd
|
||||||
|
if len(split) == 1 {
|
||||||
|
cmd = exec.Command(split[0])
|
||||||
|
} else {
|
||||||
|
cmd = exec.Command(split[0], split[1:]...)
|
||||||
|
}
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the command, return standard output and error, try a few times if requested
|
||||||
|
func ExecuteT(t *testing.T, command string, trials int) (out string) {
|
||||||
|
cmd := getCmd(t, command)
|
||||||
|
bz, err := cmd.CombinedOutput()
|
||||||
|
if err != nil && trials > 1 {
|
||||||
|
fmt.Printf("trial %v, retrying: %v\n", trials, command)
|
||||||
|
time.Sleep(time.Second * 10)
|
||||||
|
return ExecuteT(t, command, trials-1)
|
||||||
|
}
|
||||||
|
require.NoError(t, err, string(bz))
|
||||||
|
out = strings.Trim(string(bz), "\n") //trim any new lines
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// Asynchronously execute the command, return standard output and error
|
||||||
|
func GoExecuteT(t *testing.T, command string) (cmd *exec.Cmd, pipeIn io.WriteCloser, pipeOut io.ReadCloser) {
|
||||||
|
cmd = getCmd(t, command)
|
||||||
|
pipeIn, err := cmd.StdinPipe()
|
||||||
|
require.NoError(t, err)
|
||||||
|
pipeOut, err = cmd.StdoutPipe()
|
||||||
|
require.NoError(t, err)
|
||||||
|
go cmd.Start()
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
return cmd, pipeIn, pipeOut
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ type Result struct {
|
||||||
// GasWanted is the maximum units of work we allow this tx to perform.
|
// GasWanted is the maximum units of work we allow this tx to perform.
|
||||||
GasWanted int64
|
GasWanted int64
|
||||||
|
|
||||||
// GasUsed is the amount of gas actually consumed. NOTE: not used.
|
// GasUsed is the amount of gas actually consumed. NOTE: unimplemented
|
||||||
GasUsed int64
|
GasUsed int64
|
||||||
|
|
||||||
// Tx fee amount and denom.
|
// Tx fee amount and denom.
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
|
|
||||||
// Register concrete types on wire codec
|
// Register concrete types on wire codec
|
||||||
func RegisterWire(cdc *wire.Codec) {
|
func RegisterWire(cdc *wire.Codec) {
|
||||||
// TODO include option to always include prefix bytes.
|
cdc.RegisterConcrete(SendMsg{}, "cosmos-sdk/Send", nil)
|
||||||
//cdc.RegisterConcrete(SendMsg{}, "github.com/cosmos/cosmos-sdk/bank/SendMsg", nil)
|
cdc.RegisterConcrete(IssueMsg{}, "cosmos-sdk/Issue", nil)
|
||||||
//cdc.RegisterConcrete(IssueMsg{}, "github.com/cosmos/cosmos-sdk/bank/IssueMsg", nil)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,6 @@ import (
|
||||||
|
|
||||||
// Register concrete types on wire codec
|
// Register concrete types on wire codec
|
||||||
func RegisterWire(cdc *wire.Codec) {
|
func RegisterWire(cdc *wire.Codec) {
|
||||||
//cdc.RegisterConcrete(IBCTransferMsg{}, "github.com/cosmos/cosmos-sdk/x/ibc/IBCTransferMsg", nil)
|
cdc.RegisterConcrete(IBCTransferMsg{}, "cosmos-sdk/IBCTransferMsg", nil)
|
||||||
//cdc.RegisterConcrete(IBCReceiveMsg{}, "github.com/cosmos/cosmos-sdk/x/ibc/IBCReceiveMsg", nil)
|
cdc.RegisterConcrete(IBCReceiveMsg{}, "cosmos-sdk/IBCReceiveMsg", nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
flag "github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
const (
|
||||||
|
FlagAddressDelegator = "address-delegator"
|
||||||
|
FlagAddressCandidate = "address-candidate"
|
||||||
|
FlagPubKey = "pubkey"
|
||||||
|
FlagAmount = "amount"
|
||||||
|
FlagShares = "shares"
|
||||||
|
|
||||||
|
FlagMoniker = "moniker"
|
||||||
|
FlagIdentity = "keybase-sig"
|
||||||
|
FlagWebsite = "website"
|
||||||
|
FlagDetails = "details"
|
||||||
|
)
|
||||||
|
|
||||||
|
// common flagsets to add to various functions
|
||||||
|
var (
|
||||||
|
fsPk = flag.NewFlagSet("", flag.ContinueOnError)
|
||||||
|
fsAmount = flag.NewFlagSet("", flag.ContinueOnError)
|
||||||
|
fsShares = flag.NewFlagSet("", flag.ContinueOnError)
|
||||||
|
fsDescription = flag.NewFlagSet("", flag.ContinueOnError)
|
||||||
|
fsCandidate = flag.NewFlagSet("", flag.ContinueOnError)
|
||||||
|
fsDelegator = flag.NewFlagSet("", flag.ContinueOnError)
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
fsPk.String(FlagPubKey, "", "PubKey of the validator-candidate")
|
||||||
|
fsAmount.String(FlagAmount, "1fermion", "Amount of coins to bond")
|
||||||
|
fsShares.String(FlagShares, "", "Amount of shares to unbond, either in decimal or keyword MAX (ex. 1.23456789, 99, MAX)")
|
||||||
|
fsDescription.String(FlagMoniker, "", "validator-candidate name")
|
||||||
|
fsDescription.String(FlagIdentity, "", "optional keybase signature")
|
||||||
|
fsDescription.String(FlagWebsite, "", "optional website")
|
||||||
|
fsDescription.String(FlagDetails, "", "optional details")
|
||||||
|
fsCandidate.String(FlagAddressCandidate, "", "hex address of the validator/candidate")
|
||||||
|
fsDelegator.String(FlagAddressDelegator, "", "hex address of the delegator")
|
||||||
|
}
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
flag "github.com/spf13/pflag"
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
crypto "github.com/tendermint/go-crypto"
|
crypto "github.com/tendermint/go-crypto"
|
||||||
|
@ -16,76 +15,55 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||||
)
|
)
|
||||||
|
|
||||||
// XXX remove dependancy
|
//// create command to query for all candidates
|
||||||
func PrefixedKey(app string, key []byte) []byte {
|
//func GetCmdQueryCandidates(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||||
prefix := append([]byte(app), byte(0))
|
//cmd := &cobra.Command{
|
||||||
return append(prefix, key...)
|
//Use: "candidates",
|
||||||
}
|
//Short: "Query for the set of validator-candidates pubkeys",
|
||||||
|
//RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
//nolint
|
//key := stake.CandidatesKey
|
||||||
var (
|
|
||||||
fsValAddr = flag.NewFlagSet("", flag.ContinueOnError)
|
|
||||||
fsDelAddr = flag.NewFlagSet("", flag.ContinueOnError)
|
|
||||||
FlagValidatorAddr = "address"
|
|
||||||
FlagDelegatorAddr = "delegator-address"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
//ctx := context.NewCoreContextFromViper()
|
||||||
//Add Flags
|
//res, err := ctx.Query(key, storeName)
|
||||||
fsValAddr.String(FlagValidatorAddr, "", "Address of the validator/candidate")
|
//if err != nil {
|
||||||
fsDelAddr.String(FlagDelegatorAddr, "", "Delegator hex address")
|
//return err
|
||||||
|
//}
|
||||||
|
|
||||||
}
|
//// parse out the candidates
|
||||||
|
//candidates := new(stake.Candidates)
|
||||||
|
//err = cdc.UnmarshalBinary(res, candidates)
|
||||||
|
//if err != nil {
|
||||||
|
//return err
|
||||||
|
//}
|
||||||
|
//output, err := wire.MarshalJSONIndent(cdc, candidates)
|
||||||
|
//if err != nil {
|
||||||
|
//return err
|
||||||
|
//}
|
||||||
|
//fmt.Println(string(output))
|
||||||
|
//return nil
|
||||||
|
|
||||||
// create command to query for all candidates
|
//// TODO output with proofs / machine parseable etc.
|
||||||
func GetCmdQueryCandidates(cdc *wire.Codec, storeName string) *cobra.Command {
|
//},
|
||||||
cmd := &cobra.Command{
|
//}
|
||||||
Use: "candidates",
|
|
||||||
Short: "Query for the set of validator-candidates pubkeys",
|
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
|
||||||
|
|
||||||
key := PrefixedKey(stake.MsgType, stake.CandidatesKey)
|
//cmd.Flags().AddFlagSet(fsDelegator)
|
||||||
|
//return cmd
|
||||||
ctx := context.NewCoreContextFromViper()
|
//}
|
||||||
res, err := ctx.Query(key, storeName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse out the candidates
|
|
||||||
candidates := new(stake.Candidates)
|
|
||||||
err = cdc.UnmarshalJSON(res, candidates)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
output, err := wire.MarshalJSONIndent(cdc, candidates)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Println(string(output))
|
|
||||||
return nil
|
|
||||||
|
|
||||||
// TODO output with proofs / machine parseable etc.
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Flags().AddFlagSet(fsDelAddr)
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the command to query a candidate
|
// get the command to query a candidate
|
||||||
func GetCmdQueryCandidate(cdc *wire.Codec, storeName string) *cobra.Command {
|
func GetCmdQueryCandidate(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "candidate",
|
Use: "candidate",
|
||||||
Short: "Query a validator-candidate account",
|
Short: "Query a validator-candidate account",
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
addr, err := sdk.GetAddress(viper.GetString(FlagValidatorAddr))
|
addr, err := sdk.GetAddress(viper.GetString(FlagAddressCandidate))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
key := PrefixedKey(stake.MsgType, stake.GetCandidateKey(addr))
|
key := stake.GetCandidateKey(addr)
|
||||||
|
|
||||||
ctx := context.NewCoreContextFromViper()
|
ctx := context.NewCoreContextFromViper()
|
||||||
|
|
||||||
|
@ -111,29 +89,29 @@ func GetCmdQueryCandidate(cdc *wire.Codec, storeName string) *cobra.Command {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().AddFlagSet(fsValAddr)
|
cmd.Flags().AddFlagSet(fsCandidate)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the command to query a single delegator bond
|
// get the command to query a single delegator bond
|
||||||
func GetCmdQueryDelegatorBond(cdc *wire.Codec, storeName string) *cobra.Command {
|
func GetCmdQueryDelegatorBond(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "delegator-bond",
|
Use: "delegator-bond",
|
||||||
Short: "Query a delegators bond based on address and candidate pubkey",
|
Short: "Query a delegators bond based on address and candidate pubkey",
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
addr, err := sdk.GetAddress(viper.GetString(FlagValidatorAddr))
|
addr, err := sdk.GetAddress(viper.GetString(FlagAddressCandidate))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
bz, err := hex.DecodeString(viper.GetString(FlagDelegatorAddr))
|
bz, err := hex.DecodeString(viper.GetString(FlagAddressDelegator))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
delegator := crypto.Address(bz)
|
delegator := crypto.Address(bz)
|
||||||
|
|
||||||
key := PrefixedKey(stake.MsgType, stake.GetDelegatorBondKey(delegator, addr, cdc))
|
key := stake.GetDelegatorBondKey(delegator, addr, cdc)
|
||||||
|
|
||||||
ctx := context.NewCoreContextFromViper()
|
ctx := context.NewCoreContextFromViper()
|
||||||
|
|
||||||
|
@ -143,7 +121,7 @@ func GetCmdQueryDelegatorBond(cdc *wire.Codec, storeName string) *cobra.Command
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse out the bond
|
// parse out the bond
|
||||||
var bond stake.DelegatorBond
|
bond := new(stake.DelegatorBond)
|
||||||
err = cdc.UnmarshalBinary(res, bond)
|
err = cdc.UnmarshalBinary(res, bond)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -159,49 +137,49 @@ func GetCmdQueryDelegatorBond(cdc *wire.Codec, storeName string) *cobra.Command
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().AddFlagSet(fsValAddr)
|
cmd.Flags().AddFlagSet(fsCandidate)
|
||||||
cmd.Flags().AddFlagSet(fsDelAddr)
|
cmd.Flags().AddFlagSet(fsDelegator)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the command to query all the candidates bonded to a delegator
|
//// get the command to query all the candidates bonded to a delegator
|
||||||
func GetCmdQueryDelegatorBonds(cdc *wire.Codec, storeName string) *cobra.Command {
|
//func GetCmdQueryDelegatorBonds(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
//cmd := &cobra.Command{
|
||||||
Use: "delegator-candidates",
|
//Use: "delegator-candidates",
|
||||||
Short: "Query all delegators candidates' pubkeys based on address",
|
//Short: "Query all delegators bond's candidate-addresses based on delegator-address",
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
//RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
bz, err := hex.DecodeString(viper.GetString(FlagDelegatorAddr))
|
//bz, err := hex.DecodeString(viper.GetString(FlagAddressDelegator))
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
return err
|
//return err
|
||||||
}
|
//}
|
||||||
delegator := crypto.Address(bz)
|
//delegator := crypto.Address(bz)
|
||||||
|
|
||||||
key := PrefixedKey(stake.MsgType, stake.GetDelegatorBondsKey(delegator, cdc))
|
//key := stake.GetDelegatorBondsKey(delegator, cdc)
|
||||||
|
|
||||||
ctx := context.NewCoreContextFromViper()
|
//ctx := context.NewCoreContextFromViper()
|
||||||
|
|
||||||
res, err := ctx.Query(key, storeName)
|
//res, err := ctx.Query(key, storeName)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
return err
|
//return err
|
||||||
}
|
//}
|
||||||
|
|
||||||
// parse out the candidates list
|
//// parse out the candidates list
|
||||||
var candidates []crypto.PubKey
|
//var candidates []crypto.PubKey
|
||||||
err = cdc.UnmarshalBinary(res, candidates)
|
//err = cdc.UnmarshalBinary(res, candidates)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
return err
|
//return err
|
||||||
}
|
//}
|
||||||
output, err := wire.MarshalJSONIndent(cdc, candidates)
|
//output, err := wire.MarshalJSONIndent(cdc, candidates)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
return err
|
//return err
|
||||||
}
|
//}
|
||||||
fmt.Println(string(output))
|
//fmt.Println(string(output))
|
||||||
return nil
|
//return nil
|
||||||
|
|
||||||
// TODO output with proofs / machine parseable etc.
|
//// TODO output with proofs / machine parseable etc.
|
||||||
},
|
//},
|
||||||
}
|
//}
|
||||||
cmd.Flags().AddFlagSet(fsDelAddr)
|
//cmd.Flags().AddFlagSet(fsDelegator)
|
||||||
return cmd
|
//return cmd
|
||||||
}
|
//}
|
||||||
|
|
|
@ -5,12 +5,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
flag "github.com/spf13/pflag"
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
crypto "github.com/tendermint/go-crypto"
|
crypto "github.com/tendermint/go-crypto"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/context"
|
"github.com/cosmos/cosmos-sdk/client/context"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/wire"
|
"github.com/cosmos/cosmos-sdk/wire"
|
||||||
|
@ -18,51 +16,6 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||||
)
|
)
|
||||||
|
|
||||||
// nolint
|
|
||||||
const (
|
|
||||||
FlagAddressDelegator = "addressD"
|
|
||||||
FlagAddressCandidate = "addressC"
|
|
||||||
FlagPubKey = "pubkey"
|
|
||||||
FlagAmount = "amount"
|
|
||||||
FlagShares = "shares"
|
|
||||||
|
|
||||||
FlagMoniker = "moniker"
|
|
||||||
FlagIdentity = "keybase-sig"
|
|
||||||
FlagWebsite = "website"
|
|
||||||
FlagDetails = "details"
|
|
||||||
)
|
|
||||||
|
|
||||||
// common flagsets to add to various functions
|
|
||||||
var (
|
|
||||||
fsPk = flag.NewFlagSet("", flag.ContinueOnError)
|
|
||||||
fsAmount = flag.NewFlagSet("", flag.ContinueOnError)
|
|
||||||
fsShares = flag.NewFlagSet("", flag.ContinueOnError)
|
|
||||||
fsCandidate = flag.NewFlagSet("", flag.ContinueOnError)
|
|
||||||
fsDelegator = flag.NewFlagSet("", flag.ContinueOnError)
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
fsPk.String(FlagPubKey, "", "PubKey of the validator-candidate")
|
|
||||||
fsAmount.String(FlagAmount, "1fermion", "Amount of coins to bond")
|
|
||||||
fsShares.String(FlagShares, "", "Amount of shares to unbond, either in decimal or keyword MAX (ex. 1.23456789, 99, MAX)")
|
|
||||||
fsCandidate.String(FlagMoniker, "", "validator-candidate name")
|
|
||||||
fsCandidate.String(FlagIdentity, "", "optional keybase signature")
|
|
||||||
fsCandidate.String(FlagWebsite, "", "optional website")
|
|
||||||
fsCandidate.String(FlagAddressCandidate, "", "hex address of the validator/candidate")
|
|
||||||
fsDelegator.String(FlagAddressDelegator, "", "hex address of the delegator")
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO refactor to common functionality
|
|
||||||
func getNamePassword() (name, passphrase string, err error) {
|
|
||||||
name = viper.GetString(client.FlagName)
|
|
||||||
buf := client.BufferStdin()
|
|
||||||
prompt := fmt.Sprintf("Password to sign with '%s':", name)
|
|
||||||
passphrase, err = client.GetPassword(prompt, buf)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//_________________________________________________________________________________________
|
|
||||||
|
|
||||||
// create declare candidacy command
|
// create declare candidacy command
|
||||||
func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command {
|
func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
|
@ -113,6 +66,7 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command {
|
||||||
|
|
||||||
cmd.Flags().AddFlagSet(fsPk)
|
cmd.Flags().AddFlagSet(fsPk)
|
||||||
cmd.Flags().AddFlagSet(fsAmount)
|
cmd.Flags().AddFlagSet(fsAmount)
|
||||||
|
cmd.Flags().AddFlagSet(fsDescription)
|
||||||
cmd.Flags().AddFlagSet(fsCandidate)
|
cmd.Flags().AddFlagSet(fsCandidate)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -155,7 +109,7 @@ func GetCmdEditCandidacy(cdc *wire.Codec) *cobra.Command {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().AddFlagSet(fsPk)
|
cmd.Flags().AddFlagSet(fsDescription)
|
||||||
cmd.Flags().AddFlagSet(fsCandidate)
|
cmd.Flags().AddFlagSet(fsCandidate)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -198,9 +152,9 @@ func GetCmdDelegate(cdc *wire.Codec) *cobra.Command {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().AddFlagSet(fsPk)
|
|
||||||
cmd.Flags().AddFlagSet(fsAmount)
|
cmd.Flags().AddFlagSet(fsAmount)
|
||||||
cmd.Flags().AddFlagSet(fsDelegator)
|
cmd.Flags().AddFlagSet(fsDelegator)
|
||||||
|
cmd.Flags().AddFlagSet(fsCandidate)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,9 +206,9 @@ func GetCmdUnbond(cdc *wire.Codec) *cobra.Command {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().AddFlagSet(fsPk)
|
|
||||||
cmd.Flags().AddFlagSet(fsShares)
|
cmd.Flags().AddFlagSet(fsShares)
|
||||||
cmd.Flags().AddFlagSet(fsDelegator)
|
cmd.Flags().AddFlagSet(fsDelegator)
|
||||||
|
cmd.Flags().AddFlagSet(fsCandidate)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,9 +223,11 @@ func GetPubKey(pubKeyStr string) (pk crypto.PubKey, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(pubKeyStr) != 64 { //if len(pkBytes) != 32 {
|
if len(pubKeyStr) != 64 { //if len(pkBytes) != 32 {
|
||||||
err = fmt.Errorf("pubkey must be Ed25519 hex encoded string which is 64 characters long")
|
err = fmt.Errorf("pubkey must be Ed25519 hex encoded string which is 64 characters, this pubkey is %v characters", len(pubKeyStr))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: bech32 ...
|
||||||
var pkBytes []byte
|
var pkBytes []byte
|
||||||
pkBytes, err = hex.DecodeString(pubKeyStr)
|
pkBytes, err = hex.DecodeString(pubKeyStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
|
||||||
abci "github.com/tendermint/abci/types"
|
abci "github.com/tendermint/abci/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,7 +17,7 @@ const (
|
||||||
|
|
||||||
//_______________________________________________________________________
|
//_______________________________________________________________________
|
||||||
|
|
||||||
func NewHandler(k Keeper, ck bank.CoinKeeper) sdk.Handler {
|
func NewHandler(k Keeper) sdk.Handler {
|
||||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||||
// NOTE msg already has validate basic run
|
// NOTE msg already has validate basic run
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
|
@ -36,7 +35,7 @@ func NewHandler(k Keeper, ck bank.CoinKeeper) sdk.Handler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//_______________________________________________
|
//_____________________________________________________________________
|
||||||
|
|
||||||
// NewEndBlocker generates sdk.EndBlocker
|
// NewEndBlocker generates sdk.EndBlocker
|
||||||
// Performs tick functionality
|
// Performs tick functionality
|
||||||
|
@ -49,6 +48,14 @@ func NewEndBlocker(k Keeper) sdk.EndBlocker {
|
||||||
|
|
||||||
//_____________________________________________________________________
|
//_____________________________________________________________________
|
||||||
|
|
||||||
|
// InitGenesis - store genesis parameters
|
||||||
|
func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) {
|
||||||
|
k.setPool(ctx, data.Pool)
|
||||||
|
k.setParams(ctx, data.Params)
|
||||||
|
}
|
||||||
|
|
||||||
|
//_____________________________________________________________________
|
||||||
|
|
||||||
// These functions assume everything has been authenticated,
|
// These functions assume everything has been authenticated,
|
||||||
// now we just perform action and save
|
// now we just perform action and save
|
||||||
|
|
||||||
|
@ -92,9 +99,6 @@ func handleMsgEditCandidacy(ctx sdk.Context, msg MsgEditCandidacy, k Keeper) sdk
|
||||||
GasUsed: GasEditCandidacy,
|
GasUsed: GasEditCandidacy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if candidate.Status == Unbonded { //candidate has been withdrawn
|
|
||||||
return ErrBondNotNominated(k.codespace).Result()
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX move to types
|
// XXX move to types
|
||||||
// replace all editable fields (clients should autofill existing values)
|
// replace all editable fields (clients should autofill existing values)
|
||||||
|
@ -136,7 +140,7 @@ func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address,
|
||||||
bondAmt sdk.Coin, candidate Candidate) sdk.Error {
|
bondAmt sdk.Coin, candidate Candidate) sdk.Error {
|
||||||
|
|
||||||
// Get or create the delegator bond
|
// Get or create the delegator bond
|
||||||
bond, found := k.getDelegatorBond(ctx, delegatorAddr, candidate.Address)
|
bond, found := k.GetDelegatorBond(ctx, delegatorAddr, candidate.Address)
|
||||||
if !found {
|
if !found {
|
||||||
bond = DelegatorBond{
|
bond = DelegatorBond{
|
||||||
DelegatorAddr: delegatorAddr,
|
DelegatorAddr: delegatorAddr,
|
||||||
|
@ -163,7 +167,7 @@ func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address,
|
||||||
func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
|
func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
|
||||||
|
|
||||||
// check if bond has any shares in it unbond
|
// check if bond has any shares in it unbond
|
||||||
bond, found := k.getDelegatorBond(ctx, msg.DelegatorAddr, msg.CandidateAddr)
|
bond, found := k.GetDelegatorBond(ctx, msg.DelegatorAddr, msg.CandidateAddr)
|
||||||
if !found {
|
if !found {
|
||||||
return ErrNoDelegatorForAddress(k.codespace).Result()
|
return ErrNoDelegatorForAddress(k.codespace).Result()
|
||||||
}
|
}
|
||||||
|
@ -171,11 +175,7 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
|
||||||
return ErrInsufficientFunds(k.codespace).Result()
|
return ErrInsufficientFunds(k.codespace).Result()
|
||||||
}
|
}
|
||||||
|
|
||||||
// test getting rational number from decimal provided
|
var shares sdk.Rat
|
||||||
shares, err := sdk.NewRatFromDecimal(msg.Shares)
|
|
||||||
if err != nil {
|
|
||||||
return err.Result()
|
|
||||||
}
|
|
||||||
|
|
||||||
// test that there are enough shares to unbond
|
// test that there are enough shares to unbond
|
||||||
if msg.Shares == "MAX" {
|
if msg.Shares == "MAX" {
|
||||||
|
@ -183,6 +183,11 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
|
||||||
return ErrNotEnoughBondShares(k.codespace, msg.Shares).Result()
|
return ErrNotEnoughBondShares(k.codespace, msg.Shares).Result()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
var err sdk.Error
|
||||||
|
shares, err = sdk.NewRatFromDecimal(msg.Shares)
|
||||||
|
if err != nil {
|
||||||
|
return err.Result()
|
||||||
|
}
|
||||||
if bond.Shares.LT(shares) {
|
if bond.Shares.LT(shares) {
|
||||||
return ErrNotEnoughBondShares(k.codespace, msg.Shares).Result()
|
return ErrNotEnoughBondShares(k.codespace, msg.Shares).Result()
|
||||||
}
|
}
|
||||||
|
@ -253,40 +258,3 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
|
||||||
k.setPool(ctx, p)
|
k.setPool(ctx, p)
|
||||||
return sdk.Result{}
|
return sdk.Result{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO use or remove
|
|
||||||
//// Perform all the actions required to bond tokens to a delegator bond from their account
|
|
||||||
//func BondCoins(ctx sdk.Context, k Keeper, bond DelegatorBond,
|
|
||||||
//candidate Candidate, amount sdk.Coin) (DelegatorBond, Candidate, Pool, sdk.Error) {
|
|
||||||
|
|
||||||
//pool := k.GetPool(ctx)
|
|
||||||
//_, err := k.coinKeeper.SubtractCoins(ctx, bond.DelegatorAddr, sdk.Coins{amount})
|
|
||||||
//if err != nil {
|
|
||||||
//return bond, candidate, pool, err
|
|
||||||
//}
|
|
||||||
//pool, candidate, newShares := pool.candidateAddTokens(candidate, amount.Amount)
|
|
||||||
//bond.Shares = bond.Shares.Add(newShares)
|
|
||||||
//return bond, candidate, pool, nil
|
|
||||||
//}
|
|
||||||
//// Perform all the actions required to bond tokens to a delegator bond from their account
|
|
||||||
//func UnbondCoins(ctx sdk.Context, k Keeper, bond DelegatorBond,
|
|
||||||
//candidate Candidate, shares sdk.Rat) (DelegatorBond, Candidate, Pool, sdk.Error) {
|
|
||||||
|
|
||||||
//pool := k.GetPool(ctx)
|
|
||||||
|
|
||||||
//// subtract bond tokens from delegator bond
|
|
||||||
//if bond.Shares.LT(shares) {
|
|
||||||
//errMsg := fmt.Sprintf("cannot unbond %v shares, only have %v shares available", shares, bond.Shares)
|
|
||||||
//return bond, candidate, pool, sdk.ErrInsufficientFunds(errMsg)
|
|
||||||
//}
|
|
||||||
//bond.Shares = bond.Shares.Sub(shares)
|
|
||||||
|
|
||||||
//pool, candidate, returnAmount := p.candidateRemoveShares(candidate, shares)
|
|
||||||
//returnCoins := sdk.Coins{{k.GetParams(ctx).BondDenom, returnAmount}}
|
|
||||||
|
|
||||||
//_, err := k.coinKeeper.AddCoins(ctx, candidate.Address, returnCoins)
|
|
||||||
//if err != nil {
|
|
||||||
//return err
|
|
||||||
//}
|
|
||||||
//return bond, candidate, pool, nil
|
|
||||||
//}
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ func TestIncrementsMsgDelegate(t *testing.T) {
|
||||||
//Check that the accounts and the bond account have the appropriate values
|
//Check that the accounts and the bond account have the appropriate values
|
||||||
candidate, found := keeper.GetCandidate(ctx, candidateAddr)
|
candidate, found := keeper.GetCandidate(ctx, candidateAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
bond, found := keeper.getDelegatorBond(ctx, delegatorAddr, candidateAddr)
|
bond, found := keeper.GetDelegatorBond(ctx, delegatorAddr, candidateAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
expBond := int64(i+1) * bondAmount
|
expBond := int64(i+1) * bondAmount
|
||||||
|
@ -139,7 +139,7 @@ func TestIncrementsMsgUnbond(t *testing.T) {
|
||||||
//Check that the accounts and the bond account have the appropriate values
|
//Check that the accounts and the bond account have the appropriate values
|
||||||
candidate, found = keeper.GetCandidate(ctx, candidateAddr)
|
candidate, found = keeper.GetCandidate(ctx, candidateAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
bond, found := keeper.getDelegatorBond(ctx, delegatorAddr, candidateAddr)
|
bond, found := keeper.GetDelegatorBond(ctx, delegatorAddr, candidateAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
expBond := initBond - int64(i+1)*unbondShares
|
expBond := initBond - int64(i+1)*unbondShares
|
||||||
|
@ -254,7 +254,7 @@ func TestMultipleMsgDelegate(t *testing.T) {
|
||||||
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
|
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
|
||||||
|
|
||||||
//Check that the account is bonded
|
//Check that the account is bonded
|
||||||
bond, found := keeper.getDelegatorBond(ctx, delegatorAddr, candidateAddr)
|
bond, found := keeper.GetDelegatorBond(ctx, delegatorAddr, candidateAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.NotNil(t, bond, "expected delegatee bond %d to exist", bond)
|
require.NotNil(t, bond, "expected delegatee bond %d to exist", bond)
|
||||||
}
|
}
|
||||||
|
@ -266,7 +266,7 @@ func TestMultipleMsgDelegate(t *testing.T) {
|
||||||
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
|
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
|
||||||
|
|
||||||
//Check that the account is unbonded
|
//Check that the account is unbonded
|
||||||
_, found := keeper.getDelegatorBond(ctx, delegatorAddr, candidateAddr)
|
_, found := keeper.GetDelegatorBond(ctx, delegatorAddr, candidateAddr)
|
||||||
require.False(t, found)
|
require.False(t, found)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package stake
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/wire"
|
"github.com/cosmos/cosmos-sdk/wire"
|
||||||
|
@ -24,7 +23,7 @@ type Keeper struct {
|
||||||
codespace sdk.CodespaceType
|
codespace sdk.CodespaceType
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewKeeper(ctx sdk.Context, cdc *wire.Codec, key sdk.StoreKey, ck bank.CoinKeeper, codespace sdk.CodespaceType) Keeper {
|
func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.CoinKeeper, codespace sdk.CodespaceType) Keeper {
|
||||||
keeper := Keeper{
|
keeper := Keeper{
|
||||||
storeKey: key,
|
storeKey: key,
|
||||||
cdc: cdc,
|
cdc: cdc,
|
||||||
|
@ -34,17 +33,6 @@ func NewKeeper(ctx sdk.Context, cdc *wire.Codec, key sdk.StoreKey, ck bank.CoinK
|
||||||
return keeper
|
return keeper
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitGenesis - store genesis parameters
|
|
||||||
func (k Keeper) InitGenesis(ctx sdk.Context, data json.RawMessage) error {
|
|
||||||
var state GenesisState
|
|
||||||
if err := json.Unmarshal(data, &state); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
k.setPool(ctx, state.Pool)
|
|
||||||
k.setParams(ctx, state.Params)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//_________________________________________________________________________
|
//_________________________________________________________________________
|
||||||
|
|
||||||
// get a single candidate
|
// get a single candidate
|
||||||
|
@ -309,7 +297,8 @@ func (k Keeper) clearAccUpdateValidators(ctx sdk.Context) {
|
||||||
|
|
||||||
//_____________________________________________________________________
|
//_____________________________________________________________________
|
||||||
|
|
||||||
func (k Keeper) getDelegatorBond(ctx sdk.Context,
|
// load a delegator bong
|
||||||
|
func (k Keeper) GetDelegatorBond(ctx sdk.Context,
|
||||||
delegatorAddr, candidateAddr sdk.Address) (bond DelegatorBond, found bool) {
|
delegatorAddr, candidateAddr sdk.Address) (bond DelegatorBond, found bool) {
|
||||||
|
|
||||||
store := ctx.KVStore(k.storeKey)
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
@ -326,7 +315,7 @@ func (k Keeper) getDelegatorBond(ctx sdk.Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
// load all bonds of a delegator
|
// load all bonds of a delegator
|
||||||
func (k Keeper) getDelegatorBonds(ctx sdk.Context, delegator sdk.Address, maxRetrieve int16) (bonds []DelegatorBond) {
|
func (k Keeper) GetDelegatorBonds(ctx sdk.Context, delegator sdk.Address, maxRetrieve int16) (bonds []DelegatorBond) {
|
||||||
store := ctx.KVStore(k.storeKey)
|
store := ctx.KVStore(k.storeKey)
|
||||||
delegatorPrefixKey := GetDelegatorBondsKey(delegator, k.cdc)
|
delegatorPrefixKey := GetDelegatorBondsKey(delegator, k.cdc)
|
||||||
iterator := store.Iterator(subspace(delegatorPrefixKey)) //smallest to largest
|
iterator := store.Iterator(subspace(delegatorPrefixKey)) //smallest to largest
|
||||||
|
|
|
@ -2,11 +2,9 @@ package stake
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
crypto "github.com/tendermint/go-crypto"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -128,19 +126,19 @@ func TestBond(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the empty keeper first
|
// check the empty keeper first
|
||||||
_, found := keeper.getDelegatorBond(ctx, addrDels[0], addrVals[0])
|
_, found := keeper.GetDelegatorBond(ctx, addrDels[0], addrVals[0])
|
||||||
assert.False(t, found)
|
assert.False(t, found)
|
||||||
|
|
||||||
// set and retrieve a record
|
// set and retrieve a record
|
||||||
keeper.setDelegatorBond(ctx, bond1to1)
|
keeper.setDelegatorBond(ctx, bond1to1)
|
||||||
resBond, found := keeper.getDelegatorBond(ctx, addrDels[0], addrVals[0])
|
resBond, found := keeper.GetDelegatorBond(ctx, addrDels[0], addrVals[0])
|
||||||
assert.True(t, found)
|
assert.True(t, found)
|
||||||
assert.True(t, bondsEqual(bond1to1, resBond))
|
assert.True(t, bondsEqual(bond1to1, resBond))
|
||||||
|
|
||||||
// modify a records, save, and retrieve
|
// modify a records, save, and retrieve
|
||||||
bond1to1.Shares = sdk.NewRat(99)
|
bond1to1.Shares = sdk.NewRat(99)
|
||||||
keeper.setDelegatorBond(ctx, bond1to1)
|
keeper.setDelegatorBond(ctx, bond1to1)
|
||||||
resBond, found = keeper.getDelegatorBond(ctx, addrDels[0], addrVals[0])
|
resBond, found = keeper.GetDelegatorBond(ctx, addrDels[0], addrVals[0])
|
||||||
assert.True(t, found)
|
assert.True(t, found)
|
||||||
assert.True(t, bondsEqual(bond1to1, resBond))
|
assert.True(t, bondsEqual(bond1to1, resBond))
|
||||||
|
|
||||||
|
@ -159,16 +157,16 @@ func TestBond(t *testing.T) {
|
||||||
keeper.setDelegatorBond(ctx, bond2to3)
|
keeper.setDelegatorBond(ctx, bond2to3)
|
||||||
|
|
||||||
// test all bond retrieve capabilities
|
// test all bond retrieve capabilities
|
||||||
resBonds := keeper.getDelegatorBonds(ctx, addrDels[0], 5)
|
resBonds := keeper.GetDelegatorBonds(ctx, addrDels[0], 5)
|
||||||
require.Equal(t, 3, len(resBonds))
|
require.Equal(t, 3, len(resBonds))
|
||||||
assert.True(t, bondsEqual(bond1to1, resBonds[0]))
|
assert.True(t, bondsEqual(bond1to1, resBonds[0]))
|
||||||
assert.True(t, bondsEqual(bond1to2, resBonds[1]))
|
assert.True(t, bondsEqual(bond1to2, resBonds[1]))
|
||||||
assert.True(t, bondsEqual(bond1to3, resBonds[2]))
|
assert.True(t, bondsEqual(bond1to3, resBonds[2]))
|
||||||
resBonds = keeper.getDelegatorBonds(ctx, addrDels[0], 3)
|
resBonds = keeper.GetDelegatorBonds(ctx, addrDels[0], 3)
|
||||||
require.Equal(t, 3, len(resBonds))
|
require.Equal(t, 3, len(resBonds))
|
||||||
resBonds = keeper.getDelegatorBonds(ctx, addrDels[0], 2)
|
resBonds = keeper.GetDelegatorBonds(ctx, addrDels[0], 2)
|
||||||
require.Equal(t, 2, len(resBonds))
|
require.Equal(t, 2, len(resBonds))
|
||||||
resBonds = keeper.getDelegatorBonds(ctx, addrDels[1], 5)
|
resBonds = keeper.GetDelegatorBonds(ctx, addrDels[1], 5)
|
||||||
require.Equal(t, 3, len(resBonds))
|
require.Equal(t, 3, len(resBonds))
|
||||||
assert.True(t, bondsEqual(bond2to1, resBonds[0]))
|
assert.True(t, bondsEqual(bond2to1, resBonds[0]))
|
||||||
assert.True(t, bondsEqual(bond2to2, resBonds[1]))
|
assert.True(t, bondsEqual(bond2to2, resBonds[1]))
|
||||||
|
@ -176,9 +174,9 @@ func TestBond(t *testing.T) {
|
||||||
|
|
||||||
// delete a record
|
// delete a record
|
||||||
keeper.removeDelegatorBond(ctx, bond2to3)
|
keeper.removeDelegatorBond(ctx, bond2to3)
|
||||||
_, found = keeper.getDelegatorBond(ctx, addrDels[1], addrVals[2])
|
_, found = keeper.GetDelegatorBond(ctx, addrDels[1], addrVals[2])
|
||||||
assert.False(t, found)
|
assert.False(t, found)
|
||||||
resBonds = keeper.getDelegatorBonds(ctx, addrDels[1], 5)
|
resBonds = keeper.GetDelegatorBonds(ctx, addrDels[1], 5)
|
||||||
require.Equal(t, 2, len(resBonds))
|
require.Equal(t, 2, len(resBonds))
|
||||||
assert.True(t, bondsEqual(bond2to1, resBonds[0]))
|
assert.True(t, bondsEqual(bond2to1, resBonds[0]))
|
||||||
assert.True(t, bondsEqual(bond2to2, resBonds[1]))
|
assert.True(t, bondsEqual(bond2to2, resBonds[1]))
|
||||||
|
@ -186,11 +184,11 @@ func TestBond(t *testing.T) {
|
||||||
// delete all the records from delegator 2
|
// delete all the records from delegator 2
|
||||||
keeper.removeDelegatorBond(ctx, bond2to1)
|
keeper.removeDelegatorBond(ctx, bond2to1)
|
||||||
keeper.removeDelegatorBond(ctx, bond2to2)
|
keeper.removeDelegatorBond(ctx, bond2to2)
|
||||||
_, found = keeper.getDelegatorBond(ctx, addrDels[1], addrVals[0])
|
_, found = keeper.GetDelegatorBond(ctx, addrDels[1], addrVals[0])
|
||||||
assert.False(t, found)
|
assert.False(t, found)
|
||||||
_, found = keeper.getDelegatorBond(ctx, addrDels[1], addrVals[1])
|
_, found = keeper.GetDelegatorBond(ctx, addrDels[1], addrVals[1])
|
||||||
assert.False(t, found)
|
assert.False(t, found)
|
||||||
resBonds = keeper.getDelegatorBonds(ctx, addrDels[1], 5)
|
resBonds = keeper.GetDelegatorBonds(ctx, addrDels[1], 5)
|
||||||
require.Equal(t, 0, len(resBonds))
|
require.Equal(t, 0, len(resBonds))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,15 +314,6 @@ func TestGetAccUpdateValidators(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// to compare pubkeys between abci pubkey and crypto.PubKey
|
|
||||||
wirePK := func(pk crypto.PubKey) []byte {
|
|
||||||
pkBytes, err := keeper.cdc.MarshalBinary(pk)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return pkBytes
|
|
||||||
}
|
|
||||||
|
|
||||||
// test from nothing to something
|
// test from nothing to something
|
||||||
// candidate set: {} -> {c1, c3}
|
// candidate set: {} -> {c1, c3}
|
||||||
// validator set: {} -> {c1, c3}
|
// validator set: {} -> {c1, c3}
|
||||||
|
@ -479,7 +468,7 @@ func TestGetAccUpdateValidators(t *testing.T) {
|
||||||
acc = keeper.getAccUpdateValidators(ctx)
|
acc = keeper.getAccUpdateValidators(ctx)
|
||||||
require.Equal(t, 2, len(acc), "%v", acc)
|
require.Equal(t, 2, len(acc), "%v", acc)
|
||||||
|
|
||||||
assert.Equal(t, wirePK(candidatesIn[0].PubKey), acc[0].PubKey)
|
assert.Equal(t, candidatesIn[0].PubKey.Bytes(), acc[0].PubKey)
|
||||||
assert.Equal(t, int64(0), acc[0].Power)
|
assert.Equal(t, int64(0), acc[0].Power)
|
||||||
assert.Equal(t, vals[0].abciValidator(keeper.cdc), acc[1])
|
assert.Equal(t, vals[0].abciValidator(keeper.cdc), acc[1])
|
||||||
|
|
||||||
|
@ -504,10 +493,10 @@ func TestGetAccUpdateValidators(t *testing.T) {
|
||||||
require.Equal(t, 0, len(candidates))
|
require.Equal(t, 0, len(candidates))
|
||||||
acc = keeper.getAccUpdateValidators(ctx)
|
acc = keeper.getAccUpdateValidators(ctx)
|
||||||
require.Equal(t, 4, len(acc))
|
require.Equal(t, 4, len(acc))
|
||||||
assert.Equal(t, wirePK(candidatesIn[1].PubKey), acc[0].PubKey)
|
assert.Equal(t, candidatesIn[1].PubKey.Bytes(), acc[0].PubKey)
|
||||||
assert.Equal(t, wirePK(candidatesIn[2].PubKey), acc[1].PubKey)
|
assert.Equal(t, candidatesIn[2].PubKey.Bytes(), acc[1].PubKey)
|
||||||
assert.Equal(t, wirePK(candidatesIn[3].PubKey), acc[2].PubKey)
|
assert.Equal(t, candidatesIn[3].PubKey.Bytes(), acc[2].PubKey)
|
||||||
assert.Equal(t, wirePK(candidatesIn[4].PubKey), acc[3].PubKey)
|
assert.Equal(t, candidatesIn[4].PubKey.Bytes(), acc[3].PubKey)
|
||||||
assert.Equal(t, int64(0), acc[0].Power)
|
assert.Equal(t, int64(0), acc[0].Power)
|
||||||
assert.Equal(t, int64(0), acc[1].Power)
|
assert.Equal(t, int64(0), acc[1].Power)
|
||||||
assert.Equal(t, int64(0), acc[2].Power)
|
assert.Equal(t, int64(0), acc[2].Power)
|
||||||
|
@ -584,31 +573,3 @@ func TestPool(t *testing.T) {
|
||||||
resPool = keeper.GetPool(ctx)
|
resPool = keeper.GetPool(ctx)
|
||||||
assert.Equal(t, expPool, resPool)
|
assert.Equal(t, expPool, resPool)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInitGenesis(t *testing.T) {
|
|
||||||
ctx, _, keeper := createTestInput(t, false, 0)
|
|
||||||
jsonStr := `{
|
|
||||||
"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": "fermion"
|
|
||||||
},
|
|
||||||
"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}
|
|
||||||
}
|
|
||||||
}`
|
|
||||||
encoded := json.RawMessage(jsonStr)
|
|
||||||
err := keeper.InitGenesis(ctx, encoded)
|
|
||||||
require.Nil(t, err)
|
|
||||||
require.Equal(t, keeper.GetPool(ctx), initialPool())
|
|
||||||
require.Equal(t, keeper.GetParams(ctx), defaultParams())
|
|
||||||
}
|
|
||||||
|
|
|
@ -75,6 +75,14 @@ func initialPool() Pool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get raw genesis raw message for testing
|
||||||
|
func GetDefaultGenesisState() GenesisState {
|
||||||
|
return GenesisState{
|
||||||
|
Pool: initialPool(),
|
||||||
|
Params: defaultParams(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// XXX reference the common declaration of this function
|
// XXX reference the common declaration of this function
|
||||||
func subspace(prefix []byte) (start, end []byte) {
|
func subspace(prefix []byte) (start, end []byte) {
|
||||||
end = make([]byte, len(prefix))
|
end = make([]byte, len(prefix))
|
||||||
|
@ -132,7 +140,7 @@ func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context
|
||||||
&auth.BaseAccount{}, // prototype
|
&auth.BaseAccount{}, // prototype
|
||||||
).Seal()
|
).Seal()
|
||||||
ck := bank.NewCoinKeeper(accountMapper)
|
ck := bank.NewCoinKeeper(accountMapper)
|
||||||
keeper := NewKeeper(ctx, cdc, keyStake, ck, DefaultCodespace)
|
keeper := NewKeeper(cdc, keyStake, ck, DefaultCodespace)
|
||||||
keeper.setPool(ctx, initialPool())
|
keeper.setPool(ctx, initialPool())
|
||||||
keeper.setParams(ctx, defaultParams())
|
keeper.setParams(ctx, defaultParams())
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,14 @@ import (
|
||||||
crypto "github.com/tendermint/go-crypto"
|
crypto "github.com/tendermint/go-crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GenesisState - all staking state that must be provided at genesis
|
||||||
|
type GenesisState struct {
|
||||||
|
Pool Pool `json:"pool"`
|
||||||
|
Params Params `json:"params"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//_________________________________________________________________________
|
||||||
|
|
||||||
// Params defines the high level settings for staking
|
// Params defines the high level settings for staking
|
||||||
type Params struct {
|
type Params struct {
|
||||||
InflationRateChange sdk.Rat `json:"inflation_rate_change"` // maximum annual change in inflation rate
|
InflationRateChange sdk.Rat `json:"inflation_rate_change"` // maximum annual change in inflation rate
|
||||||
|
@ -31,13 +39,7 @@ type Pool struct {
|
||||||
Inflation sdk.Rat `json:"inflation"` // current annual inflation rate
|
Inflation sdk.Rat `json:"inflation"` // current annual inflation rate
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenesisState - all staking state that must be provided at genesis
|
//_________________________________________________________________________
|
||||||
type GenesisState struct {
|
|
||||||
Pool Pool `json:"pool"`
|
|
||||||
Params Params `json:"params"`
|
|
||||||
}
|
|
||||||
|
|
||||||
//_______________________________________________________________________________________________________
|
|
||||||
|
|
||||||
// CandidateStatus - status of a validator-candidate
|
// CandidateStatus - status of a validator-candidate
|
||||||
type CandidateStatus byte
|
type CandidateStatus byte
|
||||||
|
@ -65,6 +67,9 @@ type Candidate struct {
|
||||||
Description Description `json:"description"` // Description terms for the candidate
|
Description Description `json:"description"` // Description terms for the candidate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Candidates - list of Candidates
|
||||||
|
type Candidates []Candidate
|
||||||
|
|
||||||
// NewCandidate - initialize a new candidate
|
// NewCandidate - initialize a new candidate
|
||||||
func NewCandidate(address sdk.Address, pubKey crypto.PubKey, description Description) Candidate {
|
func NewCandidate(address sdk.Address, pubKey crypto.PubKey, description Description) Candidate {
|
||||||
return Candidate{
|
return Candidate{
|
||||||
|
@ -126,12 +131,8 @@ type Validator struct {
|
||||||
|
|
||||||
// abci validator from stake validator type
|
// abci validator from stake validator type
|
||||||
func (v Validator) abciValidator(cdc *wire.Codec) abci.Validator {
|
func (v Validator) abciValidator(cdc *wire.Codec) abci.Validator {
|
||||||
pkBytes, err := cdc.MarshalBinary(v.PubKey)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return abci.Validator{
|
return abci.Validator{
|
||||||
PubKey: pkBytes,
|
PubKey: v.PubKey.Bytes(),
|
||||||
Power: v.Power.Evaluate(),
|
Power: v.Power.Evaluate(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,29 +140,20 @@ func (v Validator) abciValidator(cdc *wire.Codec) abci.Validator {
|
||||||
// abci validator from stake validator type
|
// abci validator from stake validator type
|
||||||
// with zero power used for validator updates
|
// with zero power used for validator updates
|
||||||
func (v Validator) abciValidatorZero(cdc *wire.Codec) abci.Validator {
|
func (v Validator) abciValidatorZero(cdc *wire.Codec) abci.Validator {
|
||||||
pkBytes, err := cdc.MarshalBinary(v.PubKey)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return abci.Validator{
|
return abci.Validator{
|
||||||
PubKey: pkBytes,
|
PubKey: v.PubKey.Bytes(),
|
||||||
Power: 0,
|
Power: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//_________________________________________________________________________
|
//_________________________________________________________________________
|
||||||
|
|
||||||
// Candidates - list of Candidates
|
|
||||||
type Candidates []Candidate
|
|
||||||
|
|
||||||
//_________________________________________________________________________
|
|
||||||
|
|
||||||
// DelegatorBond represents the bond with tokens held by an account. It is
|
// DelegatorBond represents the bond with tokens held by an account. It is
|
||||||
// owned by one delegator, and is associated with the voting power of one
|
// owned by one delegator, and is associated with the voting power of one
|
||||||
// pubKey.
|
// pubKey.
|
||||||
// TODO better way of managing space
|
// TODO better way of managing space
|
||||||
type DelegatorBond struct {
|
type DelegatorBond struct {
|
||||||
DelegatorAddr sdk.Address `json:"delegatoraddr"`
|
DelegatorAddr sdk.Address `json:"delegator_addr"`
|
||||||
CandidateAddr sdk.Address `json:"candidate_addr"`
|
CandidateAddr sdk.Address `json:"candidate_addr"`
|
||||||
Shares sdk.Rat `json:"shares"`
|
Shares sdk.Rat `json:"shares"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,10 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/wire"
|
"github.com/cosmos/cosmos-sdk/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
// XXX complete
|
// Register concrete types on wire codec
|
||||||
func RegisterWire(cdc *wire.Codec) {
|
func RegisterWire(cdc *wire.Codec) {
|
||||||
// TODO include option to always include prefix bytes.
|
cdc.RegisterConcrete(MsgDeclareCandidacy{}, "cosmos-sdk/MsgDeclareCandidacy", nil)
|
||||||
//cdc.RegisterConcrete(SendMsg{}, "cosmos-sdk/SendMsg", nil)
|
cdc.RegisterConcrete(MsgEditCandidacy{}, "cosmos-sdk/MsgEditCandidacy", nil)
|
||||||
//cdc.RegisterConcrete(IssueMsg{}, "cosmos-sdk/IssueMsg", nil)
|
cdc.RegisterConcrete(MsgDelegate{}, "cosmos-sdk/MsgDelegate", nil)
|
||||||
|
cdc.RegisterConcrete(MsgUnbond{}, "cosmos-sdk/MsgUnbond", nil)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue